"""Redacted workflow-session persistence helpers."""

from __future__ import annotations

from pathlib import Path

from checkin_cli.nutrition_onboarding_authority import validate_authority, validate_route
from checkin_cli.nutrition_onboarding_contract import (
    QUESTION_FIELDS,
    MessageEvidence,
    OnboardingAuthority,
    OnboardingStatus,
    canonical_digest,
)
from checkin_cli.nutrition_onboarding_fs import atomic_write_private_json, read_private_json
from checkin_cli.nutrition_onboarding_models import OnboardingState


def session_cursor(document: dict[str, object]) -> int:
    cursor = document.get("cursor")
    if not isinstance(cursor, int):
        raise ValueError("invalid onboarding cursor")
    return cursor


def build_status(
    *,
    customer_key: str,
    document: dict[str, object],
) -> OnboardingStatus:
    cursor = session_cursor(document)
    state = OnboardingState(str(document["state"]))
    return OnboardingStatus(
        customer_key=customer_key,
        state=state,
        answer_count=cursor,
        next_field=(
            QUESTION_FIELDS[cursor]
            if state is OnboardingState.COLLECTING and cursor < len(QUESTION_FIELDS)
            else None
        ),
        baseline_digest=document.get("baseline_digest"),  # type: ignore[arg-type]
        owner_reviewed=bool(document.get("owner_reviewed")),
    )


def load_mutable_session(
    *,
    session_path: Path,
    customer_key: str,
    authority: OnboardingAuthority,
    evidence: MessageEvidence,
    role: str,
) -> dict[str, object]:
    validate_authority(authority, customer_key=customer_key)
    validate_route(authority, evidence, role=role)
    document = read_private_json(session_path)
    expected = canonical_digest(authority.model_dump(mode="json"))
    if document.get("authority_digest") != expected:
        raise ValueError("onboarding authority is stale")
    consumed = document.get("consumed_updates")
    if not isinstance(consumed, list) or evidence.update_id in consumed:
        raise ValueError("duplicate onboarding update")
    return document


def save_session(
    *,
    session_path: Path,
    document: dict[str, object],
    evidence: MessageEvidence,
) -> None:
    consumed = document["consumed_updates"]
    if not isinstance(consumed, list):
        raise ValueError("invalid consumed updates")
    consumed.append(evidence.update_id)
    atomic_write_private_json(session_path, document)
