from __future__ import annotations

from typing import Any

from app.models.schemas import (
    WorkflowOperationalStateSnapshot,
    WorkflowReviewEmployeeActionRequest,
    WorkflowReviewPolicyCheckResult,
    WorkflowReviewPolicySummary,
    WorkflowReviewTriggerSummary,
)
from app.modules.core.application.workflow_persistence.helpers import (
    merge_string_lists,
)


def build_policy_employee_actions(
    *,
    review_code: str,
    policy_checks: list[WorkflowReviewPolicyCheckResult],
    project_code: str,
    lead_agent_code: str,
    lead_reviewer_employee_code: str | None,
) -> list[WorkflowReviewEmployeeActionRequest]:
    """Sinh action log cho policy và escalation."""
    actions: list[WorkflowReviewEmployeeActionRequest] = []

    for item in policy_checks:
        if item.allowed and not item.requires_escalation and not item.warnings:
            continue

        notes = [violation.message for violation in item.violations] + list(
            item.warnings
        )
        ai_result = [
            f"Policy scope {item.scope}: allowed={item.allowed}, risk={item.risk_level}"
        ]
        actions.append(
            WorkflowReviewEmployeeActionRequest(
                employee_code=lead_reviewer_employee_code or "SYSTEM",
                role_title="Điều phối policy",
                agent_role=lead_agent_code,
                department_code="synthesis",
                action=f"Policy check cho {item.scope} trong review {review_code}",
                status="completed" if item.allowed else "blocked",
                summary="Đã đánh giá guardrail và escalation cho workflow rà soát hồ sơ.",
                priority="high"
                if not item.allowed or item.requires_escalation
                else "medium",
                role_group="policy",
                next_priority="Theo dõi escalations hoặc xử lý violation còn mở.",
                findings=[item.scope],
                notes=notes
                or [
                    "Policy check không phát hiện vi phạm nhưng có escalation/warning."
                ],
                ai_result=ai_result,
                metadata={
                    "action_type": "ai_analysis",
                    "policy_scope": item.scope,
                    "project_code": project_code,
                },
            )
        )

        for target in item.escalation_targets:
            actions.append(
                WorkflowReviewEmployeeActionRequest(
                    employee_code=lead_reviewer_employee_code or "SYSTEM",
                    role_title="Điều phối escalation",
                    agent_role=lead_agent_code,
                    department_code="follow_up",
                    action=f"Escalate {item.scope} tới agent {target.agent_code}",
                    status="in_progress",
                    summary="Đã tạo escalation theo policy guardrail.",
                    priority=target.priority,
                    role_group="follow_up",
                    next_priority="Chờ agent chuyên trách tiếp nhận.",
                    findings=[item.scope],
                    notes=[target.reason or "Escalation theo policy."],
                    ai_result=[f"Escalation target: {target.agent_code}"],
                    metadata={
                        "action_type": "risk_flagged",
                        "policy_scope": item.scope,
                        "target_agent_code": target.agent_code,
                        **target.metadata,
                    },
                )
            )

    return actions


def build_trigger_summary(
    request: WorkflowReviewStartRequest,
) -> WorkflowReviewTriggerSummary:
    """Tạo trigger summary gọn."""
    trigger_metadata = {
        key: value
        for key, value in dict(request.metadata or {}).items()
        if key.startswith("trigger_")
        or key in {"diagnostic_run_id", "source_event_id", "source_session_id"}
    }
    return WorkflowReviewTriggerSummary(
        trigger_source=request.trigger_source,
        trigger_mode=str(request.metadata.get("trigger_mode") or "initial_run"),
        trigger_reason=request.review_reason or request.review_summary,
        initiated_by_employee_code=request.initiated_by_employee_code,
        lead_reviewer_employee_code=request.lead_reviewer_employee_code,
        lead_agent_code=request.lead_agent_code,
        project_code=request.project_code,
        dossier_scope=request.dossier_scope,
        assigned_departments=list(request.assigned_departments),
        metadata=trigger_metadata,
    )


def build_policy_summary(
    policy_checks: list[WorkflowReviewPolicyCheckResult],
    summarized_payload: dict[str, Any] | None = None,
) -> WorkflowReviewPolicySummary:
    """Tạo summary policy giàu thông tin."""
    warnings = merge_string_lists(*[list(item.warnings) for item in policy_checks])
    applied_rules = merge_string_lists(
        *[list(item.applied_rules) for item in policy_checks]
    )

    risk_rank = {"low": 1, "medium": 2, "high": 3, "critical": 4}
    highest_risk_level = "low"
    highest_risk_value = 0
    scopes_requiring_attention: list[str] = []

    for item in policy_checks:
        item_risk = str(item.risk_level or "low").lower()
        if risk_rank.get(item_risk, 0) > highest_risk_value:
            highest_risk_value = risk_rank.get(item_risk, 0)
            highest_risk_level = item_risk

        if (
            (not item.allowed)
            or item.requires_escalation
            or item.requires_manual_review
            or item.circuit_breaker_triggered
        ):
            scopes_requiring_attention.append(item.scope)

    return WorkflowReviewPolicySummary(
        total_checks=len(policy_checks),
        allowed_checks=sum(1 for item in policy_checks if item.allowed),
        blocked_checks=sum(1 for item in policy_checks if not item.allowed),
        escalation_count=sum(
            len(item.escalation_targets)
            for item in policy_checks
            if item.requires_escalation
        ),
        manual_review_count=sum(
            1 for item in policy_checks if item.requires_manual_review
        ),
        circuit_breaker_count=sum(
            1 for item in policy_checks if item.circuit_breaker_triggered
        ),
        highest_risk_level=highest_risk_level,
        scopes_requiring_attention=scopes_requiring_attention,
        warnings=warnings,
        applied_rules=applied_rules,
        metadata=dict(summarized_payload or {}),
    )


def build_operational_state_snapshot(
    operational_state: Any,
) -> WorkflowOperationalStateSnapshot:
    """Tạo snapshot vận hành nhẹ."""
    source_status = list(getattr(operational_state, "source_status", []) or [])
    available_sources = [
        item.source_name
        for item in source_status
        if getattr(item, "available", False)
        and not getattr(item, "used_fallback", False)
    ]

    return WorkflowOperationalStateSnapshot(
        generated_at=getattr(operational_state, "generated_at", None),
        source=getattr(operational_state, "source", None),
        used_fallback=bool(getattr(operational_state, "used_fallback", False)),
        total_projects=int(getattr(operational_state.summary, "total_projects", 0)),
        open_risks=int(getattr(operational_state.summary, "open_risks", 0)),
        blocked_items_count=int(
            getattr(operational_state.summary, "blocked_items_count", 0)
        ),
        backlog_items_count=int(
            getattr(operational_state.summary, "backlog_items_count", 0)
        ),
        active_review_sessions=int(
            getattr(operational_state.summary, "active_review_sessions", 0)
        ),
        available_sources=available_sources,
        metadata={
            "source_status_count": len(source_status),
            "project_count": len(getattr(operational_state, "projects", []) or []),
            "risk_count": len(getattr(operational_state, "risks", []) or []),
            "backlog_count": len(getattr(operational_state, "backlog", []) or []),
        },
    )
