"""Các hàm nhỏ dùng chung cho operational state."""

from __future__ import annotations

from typing import Any


def ensure_list(value: Any) -> list[dict[str, Any]]:
    """Ép về list dict an toàn."""
    if isinstance(value, list):
        return [item for item in value if isinstance(item, dict)]
    return []


def ensure_dict(value: Any) -> dict[str, Any]:
    """Ép về dict an toàn."""
    if isinstance(value, dict):
        return value
    return {}


def merge_metadata(*parts: Any) -> dict[str, Any]:
    """Gộp metadata theo thứ tự."""
    merged: dict[str, Any] = {}
    for part in parts:
        if isinstance(part, dict):
            merged.update(part)
    return merged


def extract_string_list(value: Any) -> list[str]:
    """Lấy danh sách chuỗi không rỗng."""
    if isinstance(value, list):
        return [str(item) for item in value if str(item or "").strip()]
    if isinstance(value, str) and value.strip():
        return [value.strip()]
    return []


def is_high_severity(value: Any) -> bool:
    """Kiểm tra mức độ cao."""
    normalized = str(value or "").strip().lower()
    return normalized in {"cao", "high", "critical", "nghiêm trọng"}


def is_open_status(value: Any) -> bool:
    """Kiểm tra trạng thái còn mở."""
    normalized = str(value or "").strip().lower()
    return normalized not in {
        "",
        "closed",
        "đóng",
        "resolved",
        "waived",
        "rejected",
        "accepted",
        "verified",
        "cancelled",
    }


def is_assignment_open(value: Any) -> bool:
    """Kiểm tra assignment còn cần xử lý."""
    normalized = str(value or "").strip().lower()
    return normalized in {
        "pending",
        "accepted",
        "in_progress",
        "submitted",
        "returned",
        "overdue",
    }


def is_active_project(value: Any) -> bool:
    """Kiểm tra dự án còn hoạt động."""
    normalized = str(value or "").strip().lower()
    return normalized not in {
        "",
        "closed",
        "completed",
        "hoàn thành",
        "cancelled",
        "đã đóng",
    }


def derive_priority(severity: Any, impact_level: Any, is_blocking: Any) -> str:
    """Suy ra độ ưu tiên."""
    normalized_severity = str(severity or "").strip().lower()
    normalized_impact = str(impact_level or "").strip().lower()
    if (
        bool(is_blocking)
        or normalized_severity in {"critical", "high"}
        or normalized_impact in {"critical", "high"}
    ):
        return "high"
    if normalized_severity in {"medium", "moderate"} or normalized_impact in {
        "medium",
        "moderate",
    }:
        return "medium"
    return "low"


def coerce_follow_up_items(value: Any) -> list[dict[str, Any]]:
    """Chuẩn hóa raw follow-up thành list dict."""
    if isinstance(value, dict):
        return [value]
    if isinstance(value, list):
        return [item for item in value if isinstance(item, dict)]
    if isinstance(value, str) and value.strip():
        return [{"title": value.strip()}]
    return []


def merge_messages(*messages: str | None) -> str | None:
    """Gộp message không rỗng."""
    parts = [str(message).strip() for message in messages if str(message or "").strip()]
    if not parts:
        return None
    return " | ".join(parts)


def action_matches_finding(
    *, action_payload: dict[str, Any], finding: dict[str, Any]
) -> bool:
    """Kiểm tra action có trỏ đúng finding."""
    payload_finding_id = str(action_payload.get("finding_id") or "")
    payload_finding_code = str(action_payload.get("finding_code") or "")
    finding_id = str(finding.get("finding_id") or "")
    finding_code = str(finding.get("finding_code") or "")
    if payload_finding_id and payload_finding_id != finding_id:
        return False
    if payload_finding_code and payload_finding_code != finding_code:
        return False
    return True


def normalize_follow_up_item(
    item: dict[str, Any],
    *,
    review_id: str,
    finding_id: str,
    finding_code: str,
    trigger_phase: str,
) -> dict[str, Any]:
    """Chuẩn hóa payload follow-up."""
    title = (
        item.get("title")
        or item.get("action")
        or item.get("next_action")
        or item.get("name")
    )
    reference_id = str(item.get("reference_id") or item.get("action_id") or "")
    return {
        "reference_id": reference_id
        or f"{review_id}:{finding_id or finding_code}:{trigger_phase}",
        "title": str(title or "Follow-up action"),
        "description": item.get("description") or item.get("note"),
        "reason": item.get("reason") or item.get("summary"),
        "priority": item.get("priority") or "medium",
        "status": item.get("status") or "pending",
        "due_date": item.get("due_date"),
        "department_code": item.get("department_code")
        or item.get("owner_department_code"),
        "owner_employee_code": item.get("owner_employee_code")
        or item.get("employee_code"),
        "action_type": item.get("action_type") or "dossier_review_follow_up",
        "source_type": item.get("source_type") or "dossier_review_follow_up",
        "trigger_phase": item.get("trigger_phase") or trigger_phase,
        "blocking": item.get("blocking"),
        "is_blocking": item.get("is_blocking"),
    }


def deduplicate_follow_up_items(items: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """Loại trùng follow-up theo khóa ổn định."""
    deduped: list[dict[str, Any]] = []
    seen: set[str] = set()
    for item in items:
        identity = "|".join(
            [
                str(item.get("reference_id") or ""),
                str(item.get("title") or ""),
                str(item.get("action_type") or ""),
                str(item.get("trigger_phase") or ""),
            ]
        )
        if identity in seen:
            continue
        seen.add(identity)
        deduped.append(item)
    return deduped


def derive_trigger_phase_from_key(key: str) -> str:
    """Đoán giai đoạn từ key."""
    if "verification" in key or "verify" in key:
        return "post_verification"
    return "post_close"


def derive_trigger_phase_from_action_type(action_type: Any) -> str:
    """Đoán giai đoạn từ action type."""
    normalized = str(action_type or "").strip().lower()
    if "verification" in normalized or "verified" in normalized:
        return "post_verification"
    return "post_close"


def is_blocking_review_follow_up(item: dict[str, Any]) -> bool:
    """Kiểm tra follow-up có là blocker."""
    status = str(item.get("status") or "").strip().lower()
    if status in {"completed", "closed", "resolved", "verified", "accepted", "done"}:
        return False
    if bool(item.get("blocking")) or bool(item.get("is_blocking")):
        return True
    normalized_priority = str(item.get("priority") or "").strip().lower()
    normalized_type = str(item.get("action_type") or "").strip().lower()
    return normalized_priority in {"high", "critical"} or "block" in normalized_type
