from __future__ import annotations

import re
from typing import Any

from app.schemas.steward import (
    StewardPlanResponse,
    StewardTask,
    StewardThinkingEvent,
)


# "再提交"类确认话术：用户在删除草稿/解决冲突后，用这些话术恢复之前的申请 task
RESUME_CONFIRMATION_KEYWORDS = (
    "再提交",
    "继续提交",
    "重新提交",
    "再申请",
    "继续申请",
    "重新申请",
    "那就提交",
    "那就申请",
    "继续吧",
    "再试一次",
    "重新发起",
    "重新创建",
)

# flow_id → task_type 映射，用于从 steward_state 恢复 task
_FLOW_TASK_TYPE = {
    "travel_application": "expense_application",
    "travel_reimbursement": "reimbursement",
}

_FLOW_ASSIGNED_AGENT = {
    "travel_application": "application_assistant",
    "travel_reimbursement": "reimbursement_assistant",
}


def should_resume_recent_task(
    message: str,
    steward_state: dict[str, Any] | None,
) -> str | None:
    """检测'再提交'类话术 + steward_state 里有可恢复的 flow，返回 flow_id 或 None。

    确定性兜底：不依赖 LLM，当用户用确认类话术（如"再提交"）且 state 里存在
    一个仍有业务字段的 flow 时，直接恢复该 flow。
    """
    if not _matches_resume_keywords(message):
        return None
    if not isinstance(steward_state, dict):
        return None

    active_flow = str(steward_state.get("active_flow") or "").strip()
    flows = steward_state.get("flows") if isinstance(steward_state.get("flows"), dict) else {}

    # 优先恢复 active_flow，其次遍历所有 flow 找最近一个有字段的
    candidate_flow_ids: list[str] = []
    if active_flow and active_flow in flows:
        candidate_flow_ids.append(active_flow)
    for flow_id in flows:
        if flow_id not in candidate_flow_ids:
            candidate_flow_ids.append(flow_id)

    for flow_id in candidate_flow_ids:
        flow = flows.get(flow_id)
        if isinstance(flow, dict) and _flow_has_resumable_fields(flow):
            return str(flow_id or "").strip() or None
    return None


def resume_task_from_flow(
    flow_id: str,
    flow: dict[str, Any],
    task_index: int = 1,
) -> StewardTask:
    """从 steward_state.flows[flow_id] 恢复成 StewardTask。

    复用 runtime-decision 的恢复逻辑（_hydrate_runtime_state 的 field 读取），
    但产出完整 StewardTask 而非 runtime dict。
    """
    task_type = _FLOW_TASK_TYPE.get(flow_id, "expense_application")
    assigned_agent = _FLOW_ASSIGNED_AGENT.get(flow_id, "application_assistant")
    fields = {
        str(key or "").strip(): str(value or "").strip()
        for key, value in (flow.get("fields") or {}).items()
        if str(key or "").strip() and str(value or "").strip()
    }
    missing_fields = [
        str(item or "").strip()
        for item in (flow.get("missing_fields") or [])
        if str(item or "").strip()
    ]
    task_prefix = "app" if task_type == "expense_application" else "reim"
    return StewardTask(
        task_id=f"task_resume_{task_prefix}_{task_index:03d}",
        task_type=task_type,
        assigned_agent=assigned_agent,
        title="恢复上次未完成的申请" if task_type == "expense_application" else "恢复上次未完成的报销",
        summary="根据之前的对话上下文恢复该任务。",
        status="needs_confirmation" if missing_fields else "ready_to_delegate",
        confidence=0.85,
        requested_action="submit",
        ontology_fields=fields,
        missing_fields=missing_fields,
        confirmation_required=True,
    )


def attach_resumed_task(
    plan: StewardPlanResponse,
    steward_state: dict[str, Any] | None,
    flow_id: str,
) -> StewardPlanResponse:
    """把恢复的 task 挂回 plan，并补充一条 thinking_event 说明上下文已恢复。"""
    if not isinstance(steward_state, dict):
        return plan
    flows = steward_state.get("flows") if isinstance(steward_state.get("flows"), dict) else {}
    flow = flows.get(flow_id) if isinstance(flows, dict) else None
    if not isinstance(flow, dict):
        return plan

    resumed_task = resume_task_from_flow(flow_id, flow, task_index=len(plan.tasks) + 1)
    tasks = list(plan.tasks) + [resumed_task]

    thinking_events = list(plan.thinking_events)
    field_summary = "、".join(
        f"{key}:{value}" for key, value in resumed_task.ontology_fields.items() if value
    )
    thinking_events.append(
        StewardThinkingEvent(
            event_id="context_resume_recovered",
            stage="llm_function_call",
            title="已恢复上次未完成的申请",
            content=(
                f"识别到您要继续之前的{('出差申请' if resumed_task.task_type == 'expense_application' else '费用报销')}，"
                f"已从会话上下文恢复该任务"
                + (f"（{field_summary}）。" if field_summary else "。")
            ),
            status="completed",
        )
    )

    return plan.model_copy(
        update={
            "tasks": tasks,
            "thinking_events": thinking_events,
            "planning_source": "context_resume",
            "next_action": "confirm_task" if resumed_task.missing_fields else "delegate_task",
        }
    )


def _matches_resume_keywords(message: str) -> bool:
    compact = re.sub(r"\s+", "", str(message or ""))
    if not compact:
        return False
    return any(keyword in compact for keyword in RESUME_CONFIRMATION_KEYWORDS)


def _flow_has_resumable_fields(flow: dict[str, Any]) -> bool:
    """判断 flow 是否还有可恢复的业务字段（至少有 1 个非空字段）。"""
    fields = flow.get("fields")
    if not isinstance(fields, dict):
        return False
    return any(
        str(value or "").strip()
        for value in fields.values()
    )
