from agent_core.results import AgentResult
from apps.chat.models import Conversation
from apps.documents.models import SubmissionBatch

from .models import AgentAuditLog, NotificationRecord


def create_audit_log(
    scenario_id: str,
    scenario_name: str,
    user_input: str,
    agent_result: AgentResult,
    batch_id: str = "",
    conversation_id: str = "",
    product_name: str = "",
) -> AgentAuditLog:
    """
    将一次 Agent 执行结果落库为审计日志。

    设计原则：
    - 成功与失败都必须记录，方便复盘整条执行链路
    - 敏感信息在写库前先脱敏，避免误存 API Key
    - 对前端和 Django Model 统一输出稳定字段
    """
    return AgentAuditLog.objects.create(
        scenario_id=scenario_id,
        scenario_name=scenario_name,
        batch_id=batch_id,
        conversation_id=conversation_id,
        product_name=product_name,
        user_input=user_input,
        retrieved_chunks=agent_result.references,
        tool_calls=agent_result.tool_calls,
        structured_output=agent_result.structured_output,
        final_answer=agent_result.answer,
        raw_output=agent_result.raw_output,
        model_name=agent_result.model_name,
        latency_ms=max(agent_result.latency_ms, 0),
        status=agent_result.status,
        error_message=mask_sensitive_text(agent_result.error),
    )


def mask_sensitive_text(value: str) -> str:
    """
    对错误文本中的敏感配置进行脱敏。

    当前至少处理：
    - `LLM_API_KEY=...`
    - `EMBEDDING_API_KEY=...`
    """
    masked = value
    for marker in ("LLM_API_KEY=", "EMBEDDING_API_KEY="):
        masked = _mask_token_after_marker(masked, marker)
    return masked


def _mask_token_after_marker(value: str, marker: str) -> str:
    """将 marker 后紧跟的 token 替换为脱敏占位符。"""
    if marker not in value:
        return value
    prefix, _, suffix = value.partition(marker)
    secret, separator, rest = suffix.partition(" ")
    masked_secret = "sk-***" if secret.startswith("sk-") else "***"
    return f"{prefix}{marker}{masked_secret}{separator}{rest}"


def create_notification_record(
    *,
    batch_id: str,
    conversation_id: str,
    product_name: str,
    trigger_source: str,
    notify_reason: str,
    owner_role: str,
    feishu_user_id: str,
    message_status: str,
    web_detail_url: str,
    receipt: dict,
) -> NotificationRecord:
    """
    保存通知留痕。

    V1 先把通知载荷和结果状态稳定落库，
    真实飞书发送可在后续阶段接入。
    """
    return NotificationRecord.objects.create(
        batch_id=batch_id,
        conversation_id=conversation_id,
        product_name=product_name,
        trigger_source=trigger_source,
        notify_reason=notify_reason,
        owner_role=owner_role,
        feishu_user_id=feishu_user_id,
        message_status=message_status,
        web_detail_url=web_detail_url,
        receipt=receipt,
    )


def build_history_rows(logs) -> list[dict]:
    """
    为处理历史列表补齐风险状态和通知状态。

    View 只负责收集筛选条件，列表展示所需的聚合字段统一在服务层完成。
    """
    notification_map = {
        (item.batch_id, item.conversation_id): item
        for item in NotificationRecord.objects.order_by("-created_at")
    }
    batch_map = {
        item.batch_id: item
        for item in SubmissionBatch.objects.filter(
            batch_id__in=[log.batch_id for log in logs if log.batch_id]
        )
    }
    conversation_map = {
        item.conversation_id: item
        for item in Conversation.objects.filter(
            conversation_id__in=[log.conversation_id for log in logs if log.conversation_id]
        )
    }
    rows = []
    for log in logs:
        notification = notification_map.get((log.batch_id, log.conversation_id))
        batch = batch_map.get(log.batch_id)
        conversation = conversation_map.get(log.conversation_id)
        structured_output = log.structured_output or {}
        rows.append(
            {
                "log": log,
                "batch": batch,
                "conversation": conversation,
                "batch_scale": f"{batch.file_count} 份 / {batch.page_count} 页" if batch else "-",
                "batch_status": batch.get_import_status_display_text() if batch else "-",
                "conversation_status": conversation.task_status if conversation else "-",
                "risk_status": structured_output.get("highest_risk_level")
                or structured_output.get("risk_level")
                or "-",
                "notify_status": notification.message_status if notification else "-",
                "notify_reason": notification.notify_reason if notification else "-",
            }
        )
    return rows


def build_history_metrics(history_rows: list[dict]) -> list[dict]:
    """
    为处理历史页生成顶部指标卡。

    口径保持前台可讲解：
    - 处理任务数：当前筛选结果中的执行记录数
    - 成功执行：状态为 success 的记录数
    - 通知已发送：通知状态为 sent 的记录数
    - 高风险阻断：风险等级为 high 的记录数
    """
    total_count = len(history_rows)
    success_count = sum(1 for row in history_rows if row["log"].status == "success")
    notify_sent_count = sum(1 for row in history_rows if row.get("notify_status") == "sent")
    blocked_count = sum(1 for row in history_rows if row.get("risk_status") == "high")
    return [
        {"label": "处理任务数", "value": total_count, "note": "按当前筛选条件回看执行留痕。"},
        {"label": "成功执行", "value": success_count, "note": "执行完成并写入审计快照。"},
        {"label": "通知已发送", "value": notify_sent_count, "note": "已生成 sent 状态的通知留痕。"},
        {"label": "高风险阻断", "value": blocked_count, "note": "风险等级为 high 的处理记录。"},
    ]


def build_detail_summary(log: AgentAuditLog, conversation, notifications) -> dict:
    """
    组装处理历史详情页的导出摘要与通知回执信息。

    详情页模板只负责展示，字段拼装与优先级判断统一放在服务层。
    """
    structured_output = log.structured_output or {}
    output_file = structured_output.get("output_file") or {}
    export_node = None
    if conversation and conversation.node_results:
        export_node = next(
            (node for node in conversation.node_results if node.get("label") == "Word 回填导出"),
            None,
        )
    latest_notification = notifications.first() if hasattr(notifications, "first") else None
    return {
        "export_status": structured_output.get("export_status") or (export_node or {}).get("status", "-"),
        "download_url": structured_output.get("download_url", ""),
        "output_file_name": output_file.get("file_name", ""),
        "output_file_relative_path": output_file.get("relative_path", ""),
        "export_mode": output_file.get("export_mode", ""),
        "template_name": structured_output.get("template_name", ""),
        "template_version": structured_output.get("template_version", ""),
        "draft_export_status": structured_output.get("draft_export_status", ""),
        "formal_export_status": structured_output.get("formal_export_status", ""),
        "blocked_items": structured_output.get("blocked_items") or [],
        "notification_receipt": latest_notification.receipt if latest_notification else {},
    }
