from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from app.models.schemas import (
    RemediationArtifactRequirementItem,
    RemediationPlanItem,
    RemediationRequiredInputItem,
)


@dataclass(frozen=True)
class RemediationCoverageGap:
    """Gap coverage nội bộ."""

    message: str
    blocking: bool


def build_plan_from_finding(
    service: Any,
    *,
    session: dict[str, Any],
    finding: dict[str, Any],
    source: str,
    source_used_fallback: bool,
    coverage_used_fallback: bool,
    coverage_message: str | None,
    coverage_project: dict[str, Any] | None,
) -> RemediationPlanItem | None:
    """Dựng plan từ finding."""
    if not service._is_open_finding(finding.get("status")):
        return None
    document_type = str(finding.get("document_type") or "").strip()
    if not document_type:
        return None
    review_id = str(session.get("review_id") or "")
    finding_code = str(finding.get("finding_code") or "") or None
    dossier_stage = str(finding.get("dossier_stage") or "").strip() or None
    priority = service._derive_priority(
        finding.get("severity"), finding.get("impact_level"), finding.get("is_blocking")
    )
    owner_department_code, owner_employee_code = service._derive_owner_codes(finding)
    destination_folder = service._build_destination_folder(
        project_code=str(session.get("project_code") or ""),
        dossier_stage=dossier_stage,
        document_type=document_type,
    )
    required_inputs = service._build_required_inputs(session=session, finding=finding)
    artifact_requirements = service._build_artifact_requirements(
        session=session,
        finding=finding,
        destination_folder=destination_folder,
    )
    remediation_tasks = service._build_remediation_tasks(
        session=session,
        finding=finding,
        priority=priority,
        owner_department_code=owner_department_code,
        owner_employee_code=owner_employee_code,
    )
    readiness_summary = service._build_readiness_summary(
        session=session,
        finding=finding,
        required_inputs=required_inputs,
        artifact_requirements=artifact_requirements,
        remediation_tasks=remediation_tasks,
        coverage_project=coverage_project,
    )
    plan_used_fallback = (
        source_used_fallback
        or coverage_used_fallback
        or document_type != "bien_ban_nghiem_thu_noi_bo"
    )
    return RemediationPlanItem(
        plan_id=service._build_plan_id(review_id=review_id, finding=finding),
        project_code=str(session.get("project_code") or ""),
        review_session_id=review_id,
        finding_id=str(finding.get("finding_id") or ""),
        finding_code=finding_code,
        document_type=document_type,
        dossier_stage=dossier_stage,
        priority=priority,
        owner_department_code=owner_department_code,
        owner_employee_code=owner_employee_code,
        destination_folder=destination_folder,
        output_filename=service._build_output_filename(
            project_code=str(session.get("project_code") or ""),
            document_type=document_type,
            dossier_stage=dossier_stage,
            finding_code=finding_code,
        ),
        naming_rule="project_code/document_type/dossier_stage/finding_code theo định dạng snake_case ổn định.",
        required_inputs=required_inputs,
        artifact_requirements=artifact_requirements,
        remediation_tasks=remediation_tasks,
        readiness_summary=readiness_summary,
        source=source,
        used_fallback=plan_used_fallback,
        message=service._merge_messages(
            service._build_plan_message(
                document_type=document_type, readiness_summary=readiness_summary
            ),
            coverage_message,
        ),
        metadata={
            "project_name": session.get("project_name"),
            "review_code": session.get("review_code"),
            "finding_title": finding.get("title"),
            "supplement_status": finding.get("supplement_status"),
            "is_blocking": bool(finding.get("is_blocking")),
            "coverage_project_found": bool(coverage_project),
        },
    )


def build_required_inputs(
    *, finding: dict[str, Any]
) -> list[RemediationRequiredInputItem]:
    """Tạo required input."""
    document_type = str(finding.get("document_type") or "").strip()
    metadata = (
        finding.get("metadata") if isinstance(finding.get("metadata"), dict) else {}
    )
    stage_label = str(finding.get("dossier_stage") or "").strip() or "chưa xác định"
    if document_type == "bien_ban_nghiem_thu_noi_bo":
        return [
            RemediationRequiredInputItem(
                input_code="thong_tin_hang_muc",
                label="Thông tin hạng mục/công việc nghiệm thu",
                status="ready" if metadata.get("work_item_name") else "missing",
                description="Tên hạng mục, phạm vi nghiệm thu nội bộ, vị trí thi công liên quan.",
                example_value=str(metadata.get("work_item_name") or "") or None,
                source_hint="metadata finding hoặc nhật ký thi công",
                required=True,
                blocking=True,
            ),
            RemediationRequiredInputItem(
                input_code="can_cu_ho_so_chat_luong",
                label="Căn cứ hồ sơ chất lượng và bản vẽ áp dụng",
                status="ready" if metadata.get("quality_reference") else "missing",
                description="Danh sách bản vẽ, chỉ dẫn kỹ thuật, tiêu chuẩn và biên bản liên quan làm căn cứ nghiệm thu.",
                example_value=str(metadata.get("quality_reference") or "") or None,
                source_hint="hồ sơ quản lý chất lượng",
                required=True,
                blocking=True,
            ),
            RemediationRequiredInputItem(
                input_code="thanh_phan_tham_du",
                label="Thành phần tham dự nghiệm thu",
                status="ready" if metadata.get("attendees") else "missing",
                description="Đội trưởng, kỹ thuật hiện trường, QA/QC, giám sát nội bộ hoặc các thành phần ký biên bản.",
                source_hint="phân công hiện trường / danh sách nhân sự",
                required=True,
                blocking=False,
                metadata={"accepts_list": True},
            ),
            RemediationRequiredInputItem(
                input_code="ket_qua_kiem_tra_hien_truong",
                label="Kết quả kiểm tra hiện trường",
                status="ready" if metadata.get("inspection_result") else "missing",
                description="Tóm tắt khối lượng kiểm tra, chất lượng đạt/không đạt, tồn tại cần khắc phục.",
                example_value=str(metadata.get("inspection_result") or "") or None,
                source_hint="nhật ký thi công / checklist QAQC",
                required=True,
                blocking=True,
            ),
            RemediationRequiredInputItem(
                input_code="ngay_nghiem_thu",
                label="Ngày nghiệm thu nội bộ",
                status="ready" if metadata.get("inspection_date") else "missing",
                description="Ngày lập biên bản nghiệm thu nội bộ.",
                example_value=str(metadata.get("inspection_date") or "") or None,
                source_hint="lịch thi công / nhật ký",
                required=True,
                blocking=False,
            ),
        ]
    return [
        RemediationRequiredInputItem(
            input_code="thong_tin_tai_lieu",
            label=f"Thông tin nguồn để lập {document_type}",
            status="missing",
            description=f"Cần tập hợp dữ liệu đầu vào tối thiểu để tái tạo hồ sơ {document_type} tại giai đoạn {stage_label}.",
            source_hint="metadata finding / hồ sơ dự án / trao đổi bộ phận phụ trách",
            required=True,
            blocking=True,
        ),
        RemediationRequiredInputItem(
            input_code="nguoi_xac_nhan_noi_dung",
            label="Người xác nhận nội dung hồ sơ",
            status="missing",
            description="Cần xác định đầu mối chuyên môn hoặc người phê duyệt trước khi hoàn thiện tài liệu.",
            source_hint="assignment hoặc responsible_department_code",
            required=True,
            blocking=False,
        ),
    ]


def build_artifact_requirements(
    *, finding: dict[str, Any], destination_folder: str
) -> list[RemediationArtifactRequirementItem]:
    """Tạo artifact requirement."""
    document_type = str(finding.get("document_type") or "").strip()
    if document_type == "bien_ban_nghiem_thu_noi_bo":
        return [
            RemediationArtifactRequirementItem(
                artifact_code="ban_du_thao_bien_ban",
                label="Bản dự thảo biên bản nghiệm thu nội bộ",
                artifact_type="document_draft",
                required=True,
                review_required=True,
                acceptance_criteria=[
                    "Có đầy đủ thông tin công việc/hạng mục nghiệm thu",
                    "Có căn cứ hồ sơ, tiêu chuẩn hoặc bản vẽ áp dụng",
                    "Có kết luận đạt/không đạt và kiến nghị xử lý",
                ],
                delivery_format="docx",
                destination_folder=destination_folder,
            ),
            RemediationArtifactRequirementItem(
                artifact_code="bo_minh_chung_dinh_kem",
                label="Bộ minh chứng đính kèm",
                artifact_type="evidence_bundle",
                required=True,
                review_required=True,
                acceptance_criteria=[
                    "Có ảnh hiện trường hoặc checklist kiểm tra liên quan",
                    "Có tài liệu viện dẫn phục vụ nghiệm thu",
                ],
                delivery_format="pdf_zip",
                destination_folder=destination_folder,
            ),
            RemediationArtifactRequirementItem(
                artifact_code="ban_ky_xac_nhan",
                label="Bản ký xác nhận hoặc luồng ký số",
                artifact_type="approval_record",
                required=True,
                review_required=False,
                acceptance_criteria=[
                    "Xác định đủ thành phần ký",
                    "Có trạng thái chờ ký hoặc đã ký hợp lệ",
                ],
                delivery_format="pdf",
                destination_folder=destination_folder,
            ),
        ]
    return [
        RemediationArtifactRequirementItem(
            artifact_code="tai_lieu_khac_phuc",
            label=f"Tài liệu khắc phục cho {document_type}",
            artifact_type="document",
            required=True,
            review_required=True,
            acceptance_criteria=[
                "Tài liệu được tạo đúng loại document_type",
                "Có thể nộp lại để xử lý finding",
            ],
            delivery_format="docx_or_pdf",
            destination_folder=destination_folder,
        )
    ]
