"""The project's roadmap — caddie's `stages` (01-vision §5), held here per
project until the hub owns them.

A stage is a named phase of work, NOT a step in a state machine: any number
may be active, each closes on its own, and the order is display only. easel
renders the client's timeline from these and shows its own work — the
concepts, the walkthrough, the feedback round — inside the active one.

The default roadmap below is the template a new project starts from (caddie's
"Website build v1"). The scope stage's body is written per project (the design
scope from the proposal, the client's initial direction); the rest ship with
client-facing prose that says what happens there.
"""

from datetime import datetime, timezone

from sqlalchemy import select
from sqlalchemy.orm import Session

from app.models import ProjectStage

STATUSES = ("planned", "active", "done", "skipped")

# (key, title, body_md)
ROADMAP: list[tuple[str, str, str]] = [
    ("scope", "Scope and Initial Direction", ""),
    ("concepts", "Initial Concepts",
     "Different answers to the same brief. Walk through each concept, leave "
     "a note anywhere on it, tell us which direction you prefer, and press "
     "**Feedback complete** when you are done. We take it from there."),
    ("revision", "Concept Revision and Finalization",
     "We take your feedback on the concepts, refine the direction you "
     "preferred, and bring back a finalized homepage for your approval."),
    ("inner-pages", "Inner Page Mockups",
     "With the homepage direction settled, we mock up the key inner pages, "
     "such as practice areas, team and locations, in the same language, for "
     "one more round of feedback."),
    ("signoff", "Signoff",
     "You review the final mockups and sign off. From here the design is "
     "fixed and the build begins."),
    ("development", "Development",
     "We build the site on a private staging copy, migrate the content, and "
     "prepare the launch. You will see it again on staging before it goes "
     "live."),
]


def _now() -> datetime:
    return datetime.now(timezone.utc)


def stages_of(db: Session, project_id: str) -> list[ProjectStage]:
    """This project's stages in roadmap order — seeded from ROADMAP on first
    read (the caller commits). A brand-new project starts with the scope
    stage done and the concepts stage active: if it is in easel at all, the
    concepts are what it is here for."""
    rows = list(db.scalars(
        select(ProjectStage).where(ProjectStage.instance_id == project_id)
        .order_by(ProjectStage.position, ProjectStage.id)))
    if rows:
        return rows
    now = _now()
    for i, (key, title, body) in enumerate(ROADMAP, start=1):
        stage = ProjectStage(instance_id=project_id, key=key, position=i,
                             title=title, body_md=body, status="planned")
        if key == "scope":
            stage.status, stage.started_at, stage.closed_at = "done", now, now
        elif key == "concepts":
            stage.status, stage.started_at = "active", now
        db.add(stage)
        rows.append(stage)
    db.flush()
    return rows


def visible(stages: list[ProjectStage], side: str | None) -> list[ProjectStage]:
    return stages if side == "manager" else [s for s in stages if s.client_visible]


def set_status(stage: ProjectStage, status: str) -> None:
    """The timestamps follow the status so a timeline can say "completed 12
    Aug" without anyone typing a date."""
    if status not in STATUSES:
        raise ValueError(status)
    now = _now()
    stage.status = status
    if status == "planned":
        stage.started_at = None
        stage.closed_at = None
    elif status == "active":
        stage.started_at = stage.started_at or now
        stage.closed_at = None
    else:  # done | skipped
        stage.started_at = stage.started_at or now
        stage.closed_at = now


def stage_out(s: ProjectStage) -> dict:
    return {
        "id": s.id, "key": s.key, "position": s.position, "title": s.title,
        "body_md": s.body_md or "", "status": s.status,
        "client_visible": s.client_visible,
        "started_at": s.started_at, "closed_at": s.closed_at,
    }
