"""Helper hàm nhỏ cho workflow persistence."""

from __future__ import annotations

from datetime import UTC, datetime, timedelta
from typing import Any

from app.models.schemas import WorkflowReviewFindingRequest


def merge_string_lists(*groups: list[str]) -> list[str]:
    """Gộp list chuỗi, bỏ trùng và rỗng."""
    merged: list[str] = []
    seen: set[str] = set()
    for group in groups:
        for item in group:
            text = str(item).strip()
            if not text or text in seen:
                continue
            seen.add(text)
            merged.append(text)
    return merged


def build_review_code(project_code: str, lead_agent_code: str) -> str:
    """Tạo mã review dễ đọc và ổn định."""
    sanitized_project_code = str(project_code or "").strip().upper().replace(" ", "-")
    sanitized_agent_code = str(lead_agent_code or "").strip().upper().replace(" ", "-")
    timestamp = datetime.now(UTC).strftime("%Y%m%d%H%M%S")
    return f"RVW-{sanitized_project_code}-{sanitized_agent_code}-{timestamp}"


def normalize_action_timestamp(value: Any, *, fallback_index: int = 0) -> str:
    """Chuẩn hóa thời gian action."""
    if isinstance(value, datetime):
        dt_value = value.astimezone(UTC) if value.tzinfo else value.replace(tzinfo=UTC)
    else:
        raw = str(value or "").strip()
        if raw:
            normalized = raw.replace("Z", "+00:00")
            try:
                dt_value = datetime.fromisoformat(normalized)
            except ValueError:
                dt_value = datetime.now(UTC)
        else:
            dt_value = datetime.now(UTC)

        if dt_value.tzinfo is None:
            dt_value = dt_value.replace(tzinfo=UTC)
        else:
            dt_value = dt_value.astimezone(UTC)

    if fallback_index:
        dt_value = dt_value.replace(microsecond=0) + timedelta(seconds=fallback_index)

    return dt_value.isoformat()


def build_action_external_ref(
    *,
    review_id: str,
    employee_code: str,
    action: dict[str, Any],
    fallback_index: int,
) -> str:
    """Tạo khóa dedup ổn định cho action."""
    finding_code = str(action.get("finding_code") or "").strip() or "session"
    action_type = str(
        action.get("metadata", {}).get("action_type")
        or action.get("action")
        or "action"
    ).strip()
    return f"{review_id}:{employee_code}:{finding_code}:{fallback_index}:{action_type}"


def resolve_persona_from_actions(
    actions: Sequence[Mapping[str, Any]],
) -> dict[str, Any] | None:
    """Tìm persona từ actions."""
    import app.modules.core.application.workflow_persistence_service as wps

    get_persona_fn = getattr(wps, "get_persona", None)
    if get_persona_fn is None:
        from app.agents.personas import get_persona as get_persona_fn
    for item in actions:
        agent_code = item.get("actor_agent_code") or item.get("agent_code")
        if agent_code:
            try:
                return get_persona_fn(str(agent_code))
            except Exception:
                return None
    return None


def normalize_work_log_status(status: Any) -> str:
    """Chuẩn hóa trạng thái log việc."""
    raw = str(status or "").strip().lower()
    if raw in {"completed", "done", "resolved", "verified", "hoàn thành"}:
        return "completed"
    if raw in {"blocked", "cancelled", "canceled", "tạm dừng"}:
        return "blocked"
    if raw in {
        "planned",
        "pending",
        "todo",
        "to_do",
        "draft",
        "chuẩn bị",
        "chưa bắt đầu",
        "logged",
    }:
        return "planned"
    if raw in {
        "active",
        "in_review",
        "awaiting_assignment",
        "assigned",
        "pending_verification",
        "submitted",
        "in_progress",
        "collecting",
        "accepted",
        "system_logged",
        "corrected",
        "đang xử lý",
        "đang theo dõi",
    }:
        return "in_progress"
    return "in_progress"


def normalize_work_log_action_type(action_type: Any, action_text: Any = None) -> str:
    """Chuẩn hóa loại action log việc."""
    raw = str(action_type or "").strip().lower()
    action_value = str(action_text or "").strip().lower()

    if raw in {
        "manual_update",
        "ai_analysis",
        "task_update",
        "issue_recorded",
        "handover_note",
        "progress_update",
        "checklist_update",
        "system_sync",
    }:
        return raw
    if raw in {"workflow_review", "system_logged", "system_review", "session_created"}:
        return "system_sync"
    if raw in {"finding_created", "issue_found", "missing_document", "risk_flagged"}:
        return "issue_recorded"
    if raw in {"assignment_created", "assignment_updated", "task_created"}:
        return "task_update"
    if raw in {"progress_logged", "status_update"}:
        return "progress_update"
    if raw in {"checklist_created", "checklist_review"}:
        return "checklist_update"
    if raw in {"analysis", "review_analysis"}:
        return "ai_analysis"

    if any(
        keyword in action_value
        for keyword in ("thiếu", "missing", "lỗi", "vướng", "rủi ro")
    ):
        return "issue_recorded"
    if any(
        keyword in action_value
        for keyword in ("checklist", "danh sách", "rà soát", "ra soat")
    ):
        return "checklist_update"
    if any(keyword in action_value for keyword in ("bàn giao", "ban giao", "handover")):
        return "handover_note"
    if any(
        keyword in action_value
        for keyword in ("tiến độ", "tien do", "cập nhật", "cap nhat")
    ):
        return "progress_update"

    return "task_update"


def infer_assigned_employee_code(finding: WorkflowReviewFindingRequest) -> str | None:
    """Đoán người phụ trách từ action có sẵn."""
    for action in finding.employee_actions:
        if action.employee_code:
            return action.employee_code
    return None


def map_priority(
    severity: str | None, impact_level: str | None, is_blocking: bool
) -> str:
    """Đổi mức độ sang priority."""
    severity_value = str(severity or "").strip().lower()
    impact_value = str(impact_level or "").strip().lower()
    if (
        is_blocking
        or severity_value in {"critical", "high"}
        or impact_value in {"critical", "high"}
    ):
        return "high"
    if severity_value in {"medium"} or impact_value in {"medium"}:
        return "medium"
    return "low"
