from __future__ import annotations

from typing import Any

from .agents import AfterSalesAgent, PreSalesAgent, QuoteAgent, RiskAgent, RouterAgent
from .models import Decision
from .rules import detect_intent, detect_order_status
from .state_machine import evolve_after_sales_state, migrate_state_schema
from .store import ConversationStore


class Orchestrator:
    def __init__(self) -> None:
        self.router = RouterAgent()
        self.pre_sales = PreSalesAgent()
        self.quote = QuoteAgent()
        self.after_sales = AfterSalesAgent()
        self.risk = RiskAgent()
        self.store = ConversationStore()

    async def decide(self, context: dict[str, Any]) -> tuple[str, Decision, dict[str, Any]]:
        customer_key = context["customer_key"]
        session = self.store.get_session(customer_key)
        prev_state = migrate_state_schema(session.get("state", {}))
        prev_route = session.get("route", "pre_sales")

        intent = detect_intent(str(context.get("msg", "") or ""))
        order_status = detect_order_status(str(context.get("goods_order", "") or ""))

        merged_ctx = {
            **context,
            "session_state": prev_state,
            "previous_route": prev_route,
            "intent": intent,
            "order_status": order_status,
        }

        # 先风控
        risk_decision = await self.risk.decide(merged_ctx)
        if risk_decision.action in {"transfer"}:
            route = "risk"
            new_state = evolve_after_sales_state(
                {**prev_state, **(risk_decision.state_patch or {})},
                route=route,
                action=risk_decision.action,
                intent=intent,
                order_status=order_status,
                msg=str(context.get("msg", "") or ""),
            )
            self.store.upsert_session(customer_key, context.get("acc_id", ""), context.get("customer_id", ""), route, new_state)
            self.store.append_event(customer_key, "decision", {"route": route, "action": risk_decision.action, "reason": risk_decision.reason})
            return route, risk_decision, new_state

        route, route_reason = await self.router.route(merged_ctx)

        if route == "quote":
            decision = await self.quote.decide(merged_ctx)
        elif route == "after_sales":
            decision = await self.after_sales.decide(merged_ctx)
        elif route == "risk":
            decision = await self.risk.decide(merged_ctx)
        else:
            decision = await self.pre_sales.decide(merged_ctx)

        merged_state = {**prev_state, **(decision.state_patch or {})}
        new_state = evolve_after_sales_state(
            merged_state,
            route=route,
            action=decision.action,
            intent=intent,
            order_status=order_status,
            msg=str(context.get("msg", "") or ""),
        )

        self.store.upsert_session(customer_key, context.get("acc_id", ""), context.get("customer_id", ""), route, new_state)
        self.store.append_event(
            customer_key,
            "decision",
            {
                "route": route,
                "route_reason": route_reason,
                "action": decision.action,
                "reason": decision.reason,
                "after_sales_stage": new_state.get("after_sales_stage", "new"),
            },
        )
        return route, decision, new_state
