"""Arrival: the tool walkthrough's state and the contents pane.

Both are read-mostly and project-scoped. The tour's STEPS are not served from
here — they are frontend data (see app/tour.py for why); this owns only the
question "should this person be walked through this board, and have they been
through the tours on it".
"""

import logging

from fastapi import APIRouter, Body, Depends, HTTPException

from app import bw_config, schemas
from app import bw_accounts as bwa
from app.db import get_session_factory
from app.identity import optional_user
from app.services import projects as svc

log = logging.getLogger(__name__)
router = APIRouter(prefix="/api/projects", tags=["onboarding"])


def _user(user: str | None = Depends(optional_user)) -> str:
    assert user is not None
    return user


def _require_view(user: str, project_id: str) -> None:
    if svc.side_of(user, project_id) is None or not any(
            i["id"] == project_id for i in bwa.instances()):
        raise HTTPException(status_code=404, detail={
            "error_code": "NO_SUCH_PROJECT",
            "summary": f"No such {bw_config.INSTANCE_NOUN}."})


@router.get("/{project_id}/contents", response_model=schemas.ContentsOut)
def get_contents(project_id: str, user: str = Depends(_user)) -> schemas.ContentsOut:
    _require_view(user, project_id)
    sf = get_session_factory()
    with sf() as db:
        return schemas.ContentsOut(**svc.contents(db, project_id, user))


@router.post("/{project_id}/tour/seen", response_model=schemas.OkOut)
def mark_tour_seen(project_id: str,
                   body: schemas.MarkTourSeenIn = Body(default=None),
                   user: str = Depends(_user)) -> schemas.OkOut:
    """Finished it, or said 'not now' — both record the version. Asking again on
    the next visit is exactly the wall the milestone forbids."""
    _require_view(user, project_id)
    sf = get_session_factory()
    with sf() as db:
        svc.mark_tour_seen(db, project_id, user,
                           completed=bool(body and body.completed))
        db.commit()
    return schemas.OkOut()
