from __future__ import annotations

from app.schemas.steward import (
    StewardCandidateFlow,
    StewardFlowStatePatch,
    StewardPendingFlowConfirmation,
    StewardPlanResponse,
)
from app.services.steward_flow_state import StewardFlowStateService


def test_state_merge_keeps_application_and_reimbursement_flows() -> None:
    service = StewardFlowStateService()

    state = service.merge_state(
        {},
        StewardFlowStatePatch(
            active_flow="travel_application",
            flow_id="travel_application",
            intent="travel_application_create",
            fields={"expense_type": "travel", "location": "上海", "reason": "客户现场支撑"},
            missing_fields=["transport_mode"],
        ),
    )
    state = service.merge_state(
        state,
        StewardFlowStatePatch(
            active_flow="travel_reimbursement",
            flow_id="travel_reimbursement",
            intent="travel_reimbursement_draft",
            fields={"amount": "708.00", "invoice_no": "NO-1"},
            linked_application_claim_id="claim-app-001",
        ),
    )

    assert state["active_flow"] == "travel_reimbursement"
    assert state["flows"]["travel_application"]["fields"]["location"] == "上海"
    assert state["flows"]["travel_application"]["missing_fields"] == ["transport_mode"]
    assert state["flows"]["travel_reimbursement"]["fields"]["amount"] == "708.00"
    assert state["flows"]["travel_reimbursement"]["linked_application_claim_id"] == "claim-app-001"


def test_state_merge_filters_non_ontology_fields() -> None:
    service = StewardFlowStateService()

    state = service.merge_state(
        {},
        StewardFlowStatePatch(
            active_flow="travel_application",
            flow_id="travel_application",
            intent="travel_application_create",
            fields={
                "location": "上海",
                "invented_field": "x",
                "occurred_date": "2026-06-15",
            },
        ),
    )

    assert state["flows"]["travel_application"]["fields"] == {
        "location": "上海",
        "time_range": "2026-06-15",
    }


def test_state_merge_appends_traceable_events() -> None:
    service = StewardFlowStateService()

    state = service.merge_state(
        {},
        StewardFlowStatePatch(
            active_flow="travel_application",
            flow_id="travel_application",
            intent="travel_application_create",
            fields={"location": "北京"},
            evidence=[{"source": "user_message", "field": "location", "text": "去北京出差"}],
        ),
    )

    assert len(state["events"]) == 1
    assert state["events"][0]["flow_id"] == "travel_application"
    assert state["events"][0]["intent"] == "travel_application_create"
    assert state["events"][0]["fields"] == {"location": "北京"}
    assert state["events"][0]["evidence"][0]["text"] == "去北京出差"


def test_state_merge_plan_keeps_pending_flow_confirmation() -> None:
    service = StewardFlowStateService()

    state = service.merge_plan(
        {},
        StewardPlanResponse(
            plan_id="steward_plan_pending",
            plan_status="needs_flow_confirmation",
            planning_source="llm_function_call",
            next_action="confirm_flow",
            summary="需要先确认是申请还是报销。",
            pending_flow_confirmation=StewardPendingFlowConfirmation(
                status="pending",
                source_message="2月20-23日去上海出差辅助国网仿生产环境部署",
                reason="缺少申请或报销动作词。",
                candidate_flows=[
                    StewardCandidateFlow(
                        flow_id="travel_application",
                        label="补办出差申请",
                        confidence=0.52,
                        reason="可能是补办申请。",
                        ontology_fields={
                            "time_range": "2026-02-20",
                            "location": "上海",
                            "expense_type": "travel",
                            "reason": "辅助国网仿生产环境部署",
                        },
                        missing_fields=["transport_mode"],
                    ),
                    StewardCandidateFlow(
                        flow_id="travel_reimbursement",
                        label="发起费用报销",
                        confidence=0.48,
                        reason="可能是发起报销。",
                        ontology_fields={
                            "time_range": "2026-02-20",
                            "location": "上海",
                            "expense_type": "travel",
                            "reason": "辅助国网仿生产环境部署",
                        },
                    ),
                ],
            ),
        ),
    )

    assert state["active_flow"] == ""
    assert state["pending_flow_confirmation"]["status"] == "pending"
    assert state["flows"]["travel_application"]["status"] == "pending_flow_confirmation"
    assert state["flows"]["travel_application"]["fields"]["location"] == "上海"
    assert state["flows"]["travel_application"]["missing_fields"] == ["transport_mode"]
    assert state["flows"]["travel_reimbursement"]["fields"]["time_range"] == "2026-02-20"
