from __future__ import annotations

import json
from pathlib import Path

from checkin_cli import nutrition_onboarding as domain


def authority() -> domain.OnboardingAuthority:
    return domain.OnboardingAuthority(
        customer_key="client_001",
        customer_user_id=10,
        customer_chat_id=10,
        customer_topic_id=0,
        owner_user_id=12,
        owner_chat_id=12,
        owner_topic_id=0,
        consent_notice_version="privacy-v1",
        consent_granted=True,
        customer_enabled=False,
    )


def evidence(*, actor: int, message: int) -> domain.MessageEvidence:
    return domain.MessageEvidence(
        actor_user_id=actor,
        chat_id=actor,
        topic_id=0,
        message_id=message,
        update_id=message + 100,
    )


def complete_answers(service: domain.NutritionOnboardingService) -> None:
    auth = authority()
    service.start_or_resume(authority=auth, evidence=evidence(actor=10, message=1))
    for index, field in enumerate(domain.QUESTION_FIELDS, start=2):
        service.submit_answer(
            field=field,
            value=domain.example_answer(field),
            authority=auth,
            evidence=evidence(actor=10, message=index),
        )


def test_owner_v1_api_has_only_owner_and_customer_authority() -> None:
    assert domain.NUTRITION_ONBOARDING_API_VERSION == "2.0"
    dumped = authority().model_dump(mode="json")
    assert set(dumped) == {
        "customer_key", "customer_user_id", "customer_chat_id", "customer_topic_id",
        "owner_user_id", "owner_chat_id", "owner_topic_id", "consent_notice_version",
        "consent_granted", "customer_enabled",
    }


def test_attestation_goes_directly_to_owner_and_all_owner_decisions(tmp_path: Path) -> None:
    service = domain.NutritionOnboardingService(
        profile_root=tmp_path,
        customer_key="client_001",
        enforce_current_authority=False,
    )
    complete_answers(service)
    status = service.attest_baseline(
        authority=authority(), evidence=evidence(actor=10, message=40)
    )
    assert status.state.value == "owner_review"
    workflow = json.loads(service.session_path.read_text())
    assert workflow["schema_version"] == "2.0"
    assert workflow["review_flow"] == "owner_v1"
    assert workflow["owner_reviewed"] is False

    held = service.review_as_owner(
        decision="safety_hold",
        authority=authority(),
        evidence=evidence(actor=12, message=41),
    )
    assert held.state.value == "safety_hold"
    cleared = service.record_clinical_review(
        cleared=True,
        external_reference="opaque-clearance-1",
        authority=authority(),
        evidence=evidence(actor=12, message=42),
    )
    assert cleared.state.value == "owner_review"


def test_owner_approve_needs_no_owner_receipt(tmp_path: Path) -> None:
    service = domain.NutritionOnboardingService(
        profile_root=tmp_path,
        customer_key="client_001",
        enforce_current_authority=False,
    )
    complete_answers(service)
    service.attest_baseline(
        authority=authority(), evidence=evidence(actor=10, message=40)
    )
    status = service.review_as_owner(
        decision="approved",
        authority=authority(),
        evidence=evidence(actor=12, message=41),
    )
    assert status.state.value == "finalizing"
    workflow = json.loads(service.session_path.read_text())
    assert workflow["owner_reviewed"] is True
    assert len(workflow["owner_review_receipt"]) == 64
