from __future__ import annotations

import app.modules.core.application.workflow_policy_service as _policy_mod
from app.models.schemas import (
    WorkflowReviewEscalationTargetItem,
    WorkflowReviewPolicyCheckResult,
    WorkflowReviewPolicyViolationItem,
    WorkflowReviewStartRequest,
)


class SessionPolicyMixin:
    """Session-level guardrails and escalation target evaluation."""

    def _evaluate_session_policy(
        self, request: WorkflowReviewStartRequest
    ) -> WorkflowReviewPolicyCheckResult:
        """Evaluate session-level guardrails."""
        lead_persona = _policy_mod.get_persona(request.lead_agent_code)
        violations: list[WorkflowReviewPolicyViolationItem] = []
        warnings: list[str] = []
        escalation_targets: list[WorkflowReviewEscalationTargetItem] = []
        applied_rules = [
            "lead_agent_must_exist",
            "workflow_should_include_findings",
            "blocking_workflow_requires_departments",
            "high_risk_workflow_requires_manual_review",
            "conflicting_metadata_triggers_circuit_breaker",
        ]

        if not request.findings:
            violations.append(
                WorkflowReviewPolicyViolationItem(
                    code="SESSION_NO_FINDINGS",
                    message="Workflow phải có ít nhất một finding để được tự động xử lý.",
                    severity="high",
                    field_name="findings",
                )
            )

        if (
            any(finding.is_blocking for finding in request.findings)
            and not request.assigned_departments
        ):
            warnings.append(
                "Workflow có finding blocking nhưng chưa khai báo assigned_departments."
            )

        if request.metadata.get("source") == "integration_test":
            warnings.append("Workflow đang chạy ở chế độ integration_test.")

        risk_score = 0
        risk_level = "low"
        requires_escalation = False
        requires_manual_review = False
        circuit_breaker_triggered = False

        metadata_flags = (
            request.metadata.get("flags", {})
            if isinstance(request.metadata.get("flags"), dict)
            else {}
        )
        if metadata_flags.get("data_conflict") or metadata_flags.get(
            "critical_data_missing"
        ):
            violations.append(
                WorkflowReviewPolicyViolationItem(
                    code="SESSION_DATA_CONFLICT",
                    message="Metadata workflow cho biết dữ liệu mâu thuẫn hoặc thiếu nghiêm trọng.",
                    severity="critical",
                    field_name="metadata.flags",
                )
            )
            circuit_breaker_triggered = True

        if violations:
            risk_score += 80
            risk_level = "high"
            requires_escalation = True

        if any(finding.is_blocking for finding in request.findings):
            risk_score += 15
            if risk_level == "low":
                risk_level = "medium"

        if warnings:
            risk_score += min(15, len(warnings) * 5)
            if risk_level == "low":
                risk_level = "medium"

        if risk_score >= 60 or any(
            finding.severity.lower() == "critical" for finding in request.findings
        ):
            requires_manual_review = True

        if requires_escalation or any(
            finding.is_blocking for finding in request.findings
        ):
            escalation_targets.extend(
                WorkflowReviewEscalationTargetItem(
                    agent_code=agent_code,
                    reason=f"Escalation theo cấu hình persona của lead agent {lead_persona['display_name']}.",
                    priority="high" if agent_code in {"thao", "nam"} else "medium",
                    metadata={
                        "source": "persona_registry",
                        "lead_agent_code": request.lead_agent_code,
                    },
                )
                for agent_code in lead_persona["escalation_targets"]
            )

        return WorkflowReviewPolicyCheckResult(
            scope="session",
            allowed=not violations,
            risk_level=risk_level,
            risk_score=risk_score,
            requires_escalation=requires_escalation
            or bool(
                escalation_targets and any(f.is_blocking for f in request.findings)
            ),
            requires_manual_review=requires_manual_review,
            circuit_breaker_triggered=circuit_breaker_triggered,
            violations=violations,
            warnings=warnings,
            escalation_targets=escalation_targets,
            applied_rules=applied_rules,
            metadata={
                "project_code": request.project_code,
                "lead_agent_code": request.lead_agent_code,
                "finding_count": len(request.findings),
                "flags": metadata_flags,
            },
        )
