from __future__ import annotations

from typing import Any

from app.models.schemas import (
    DossierReviewSessionRecord,
    WorkflowOperationalStateSnapshot,
    WorkflowReviewRunSummary,
    WorkflowReviewStartRequest,
)
from app.modules.core.application.workflow_persistence.builders import (
    build_assignment_request,
    build_auto_submission,
    build_auto_verification,
    build_automation_employee_actions,
    build_employee_log_session_payload,
    build_escalation_next_actions,
    build_manual_follow_up_reason,
    build_next_actions,
    build_operational_state_snapshot,
    build_policy_employee_actions,
    build_policy_summary,
    build_post_close_actions,
    build_trigger_summary,
    collect_policy_blocked_reasons,
    find_policy_for_finding,
)
from app.modules.core.application.workflow_persistence.helpers import (
    build_action_external_ref,
    infer_assigned_employee_code,
    map_priority,
    merge_string_lists,
    normalize_action_timestamp,
    normalize_work_log_action_type,
    normalize_work_log_status,
    resolve_persona_from_actions,
)


class WorkflowPersistenceWrappersMixin:
    """Summary aggregation and static method delegation wrappers."""

    @staticmethod
    def _build_review_record(payload: dict[str, Any]):
        return DossierReviewSessionRecord(**payload)

    @staticmethod
    def _build_run_summary(
        *,
        request,
        review_record,
        core_result: dict[str, Any],
        employee_log_summaries,
        operational_state_snapshot,
        operational_state_message: str,
        policy_checks,
        policy_summary,
        trigger_summary,
        review_code: str,
    ):
        return WorkflowReviewRunSummary(
            review=review_record,
            finding_summaries=core_result["finding_summaries"],
            employee_log_summaries=employee_log_summaries,
            created_snapshot_ids=core_result["created_snapshot_ids"],
            next_actions=core_result["next_actions"],
            policy_checks=policy_checks,
            lifecycle_outcomes=core_result["lifecycle_outcomes"],
            correlation_id=review_code,
            run_id=request.metadata.get("diagnostic_run_id"),
            automation_status=core_result["automation_status"],
            requires_manual_intervention=core_result["requires_manual_intervention"]
            or bool(core_result["manual_follow_up_count"]),
            resumable_from_step=core_result["resumable_from_step"],
            close_executed=core_result["close_executed"],
            assigned_findings_count=core_result["assigned_findings_count"],
            submitted_findings_count=core_result["submitted_findings_count"],
            verified_findings_count=core_result["verified_findings_count"],
            escalated_findings_count=core_result["escalated_findings_count"],
            manual_follow_up_count=core_result["manual_follow_up_count"],
            blocked_reasons=core_result["blocked_reasons"],
            review_action_count=len(review_record.actions),
            operational_state_snapshot=operational_state_snapshot,
            policy_summary=policy_summary,
            trigger_summary=trigger_summary,
            post_close_actions=core_result["post_close_actions"],
            message=(
                "Đã lưu workflow rà soát hồ sơ chủ động theo chu trình end-to-end, "
                f"kèm policy guardrail, escalation và nhật ký tham gia của nhân sự AI. "
                f"Automation status: {core_result['automation_status']}. "
                f"{operational_state_message}"
            ),
        )

    def _ensure_assignment(
        self,
        *,
        request: WorkflowReviewStartRequest,
        review_id: str,
        finding_id: str,
        finding,
        connection: Any | None = None,
    ) -> dict[str, Any] | None:
        assignment = finding.assignment or build_assignment_request(
            request=request, finding=finding
        )
        return self._postgres_client.assign_dossier_review_finding(
            review_id,
            finding_id,
            {
                **assignment.model_dump(exclude_none=True),
                "actor_type": "agent",
                "actor_employee_code": request.lead_reviewer_employee_code
                or request.initiated_by_employee_code,
                "actor_agent_code": request.lead_agent_code,
                "assigned_by_employee_code": assignment.assigned_by_employee_code
                or request.lead_reviewer_employee_code
                or request.initiated_by_employee_code,
                "action_summary": f"Phân công xử lý finding {finding.finding_code} cho bộ phận {assignment.assigned_department_code}.",
            },
            connection=connection,
        )

    def _build_operational_state_enrichment(
        self,
    ) -> tuple[Any | None, WorkflowOperationalStateSnapshot, str]:
        """Nạp snapshot vận hành theo best effort."""
        try:
            operational_state = (
                self._company_operational_state_service.get_company_operational_state()
            )
        except Exception as exc:
            return (
                None,
                WorkflowOperationalStateSnapshot(
                    source="unavailable",
                    used_fallback=True,
                    available_sources=[],
                    metadata={
                        "degraded_dependency": "company_operational_state",
                        "error": str(exc),
                        "source_status_count": 0,
                        "project_count": 0,
                        "risk_count": 0,
                        "backlog_count": 0,
                    },
                ),
                "Không thể nạp operational twin sau khi lưu workflow; response đã trả fallback snapshot an toàn.",
            )
        return (
            operational_state,
            self._build_operational_state_snapshot(operational_state),
            (
                f"Operational twin hiện có {operational_state.summary.total_projects} dự án, "
                f"{operational_state.summary.open_risks} rủi ro mở và "
                f"{operational_state.summary.blocked_items_count} đầu mục đang chặn."
            ),
        )

    _collect_policy_blocked_reasons = staticmethod(collect_policy_blocked_reasons)
    _build_manual_follow_up_reason = staticmethod(build_manual_follow_up_reason)
    _find_policy_for_finding = staticmethod(find_policy_for_finding)
    _build_escalation_next_actions = staticmethod(build_escalation_next_actions)
    _build_policy_employee_actions = staticmethod(build_policy_employee_actions)
    _build_trigger_summary = staticmethod(build_trigger_summary)
    _build_policy_summary = staticmethod(build_policy_summary)
    _build_operational_state_snapshot = staticmethod(build_operational_state_snapshot)
    _infer_assigned_employee_code = staticmethod(infer_assigned_employee_code)
    _map_priority = staticmethod(map_priority)
    _build_employee_log_session_payload = staticmethod(
        build_employee_log_session_payload
    )
    _merge_string_lists = staticmethod(merge_string_lists)

    @staticmethod
    def _build_review_code(project_code: str, lead_agent_code: str) -> str:
        from datetime import datetime

        import app.modules.core.application.workflow_persistence_service as wps

        dt_cls = getattr(wps, "datetime", datetime)
        sanitized_project_code = (
            str(project_code or "").strip().upper().replace(" ", "-")
        )
        sanitized_agent_code = (
            str(lead_agent_code or "").strip().upper().replace(" ", "-")
        )
        timestamp = dt_cls.now().strftime("%Y%m%d%H%M%S")
        return f"RVW-{sanitized_project_code}-{sanitized_agent_code}-{timestamp}"

    _normalize_action_timestamp = staticmethod(normalize_action_timestamp)
    _build_action_external_ref = staticmethod(build_action_external_ref)
    _resolve_persona_from_actions = staticmethod(resolve_persona_from_actions)
    _normalize_work_log_status = staticmethod(normalize_work_log_status)
    _normalize_work_log_action_type = staticmethod(normalize_work_log_action_type)
    _build_auto_submission = staticmethod(build_auto_submission)
    _build_auto_verification = staticmethod(build_auto_verification)
    _build_automation_employee_actions = staticmethod(build_automation_employee_actions)
    _build_next_actions = staticmethod(build_next_actions)
    _build_post_close_actions = staticmethod(build_post_close_actions)
