from __future__ import annotations

"""API endpoints for BoQ Unit Rate Breakdown (VL+NC+M), Triple-Column Variance, and Material Requisitions."""

import logging
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Query

from app.modules.auth.presentation.auth import require_role
from app.core.postgres.erp_client import ErpDatabaseClient

from .schemas import ItemQuantitiesUpdateRequest

logger = logging.getLogger("dscons.api.takeoff.breakdown")
router = APIRouter()


@router.get(
    "/{takeoff_id}/rate-breakdown",
    summary="Bảng Phân Rã Đơn Giá Chi Tiết (VL + NC + M) & Định Mức Vật Tư 2026",
)
def get_rate_breakdown_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Phân rã đơn giá từng công tác BoQ thành 3 thành phần: Chi phí Vật liệu, Nhân công, Ca máy theo Định mức Xây dựng 2026."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    res = client.get_takeoff_rate_breakdown(takeoff_id)
    res["takeoff"] = takeoff
    return res


@router.get(
    "/{takeoff_id}/triple-column-variance",
    summary="Bảng So Sánh 3 Cột (Bản Vẽ vs HSMT vs Thực Tế) & Cảnh Báo Phát Sinh VO",
)
def get_triple_variance_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Đối soát 3 cột khối lượng: Khối lượng Bản vẽ (AI), Tiên lượng mời thầu (HSMT), và Nghiệm thu thực tế để phát hiện phát sinh (VO)."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    res = client.get_takeoff_triple_variance(takeoff_id)
    res["takeoff"] = takeoff
    return res


@router.post(
    "/{takeoff_id}/generate-material-request",
    summary="1-Click Tổng Hợp & Sinh Phiếu Dự Trù Nhu Cầu Vật Tư Công Trường (MR Schedule)",
)
def generate_material_request_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """1-Click tổng hợp toàn bộ nhu cầu vật tư chính (Cát 710k, Cát 510k, Xi măng, Thép CB400, Ván khuôn...) từ bảng BoQ để chuyển sang phòng Mua sắm."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    res = client.generate_takeoff_material_request(takeoff_id)
    return res


@router.get(
    "/{takeoff_id}/statutory-cost-summary",
    summary="Bảng Tổng Hợp Chi Phí Dự Toán Xây Dựng 2026 (Nghị Định 206/2026/NĐ-CP)",
)
def get_statutory_cost_summary_endpoint(
    takeoff_id: str,
    vat_rate: float | None = Query(None, description="Thuế suất VAT (%) tùy chọn"),
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Tính toán bảng tổng hợp kinh phí xây dựng chính thức theo Nghị định 206/2026/NĐ-CP: Chi phí trực tiếp T, Gián tiếp GT, Thu nhập chịu thuế TL, Thuế VAT, Dự phòng DP."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    items = client.list_drawing_takeoff_items(takeoff_id)
    from app.modules.takeoff.application.boq_statutory_cost_service import (
        StatutoryCostSummaryEngine,
    )

    res = StatutoryCostSummaryEngine.calculate_statutory_summary(
        items=items,
        drawing_type=takeoff.get("drawing_type", "civil_building"),
        vat_rate=vat_rate,
    )
    res["takeoff"] = takeoff
    return res


@router.get(
    "/{takeoff_id}/audit-report",
    summary="Báo Cáo Thẩm Tra & Kiểm Toán Chất Lượng BoQ (AI QS Audit Report)",
)
def get_boq_audit_report_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Thẩm tra toàn diện danh mục BoQ: kiểm tra tương quan bê tông - ván khuôn - cốt thép, đào đắp, đơn vị tính và tính điểm chất lượng hồ sơ."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    items = client.list_drawing_takeoff_items(takeoff_id)
    from app.modules.takeoff.application.boq_audit_engine import BoqAuditEngine

    res = BoqAuditEngine.audit_takeoff(
        items=items,
        drawing_type=takeoff.get("drawing_type", "civil_building"),
        takeoff_title=takeoff.get("drawing_title", "Hồ sơ bóc tách bản vẽ"),
    )
    res["takeoff"] = takeoff
    return res


@router.post(
    "/{takeoff_id}/apply-audit-recommendations",
    summary="1-Click Tự Động Bổ Sung Các Hạng Mục Khuyến Nghị Từ Báo Cáo Thẩm Tra",
)
def apply_audit_recommendations_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """1-Click tự động thêm các công tác phụ trợ/ván khuôn/đắp đất được phát hiện thiếu sót vào bảng BoQ chính."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    items = client.list_drawing_takeoff_items(takeoff_id)
    from uuid import uuid4

    from app.modules.takeoff.application.boq_audit_engine import BoqAuditEngine

    audit_res = BoqAuditEngine.audit_takeoff(
        items=items,
        drawing_type=takeoff.get("drawing_type", "civil_building"),
        takeoff_title=takeoff.get("drawing_title", "Hồ sơ bóc tách bản vẽ"),
    )
    supplements = audit_res.get("recommended_supplements", [])
    if not supplements:
        return {
            "status": "success",
            "message": "Hồ sơ bóc tách đã hoàn hảo, không có hạng mục nào cần bổ sung!",
            "added_count": 0,
        }

    current_max_index = len(items)
    added_count = 0
    for itm in supplements:
        current_max_index += 1
        client.create_drawing_takeoff_item(
            {
                "id": str(uuid4()),
                "takeoff_id": takeoff_id,
                "item_index": current_max_index,
                "wbs_code": itm.get("wbs_code") or f"SUP-{current_max_index:02d}",
                "norm_code": itm.get("norm_code", "ĐM-2026"),
                "item_name": itm.get("item_name"),
                "category": itm.get("category", "civil"),
                "dimension_formula": itm.get("dimension_formula", ""),
                "unit": itm.get("unit", "m3"),
                "quantity": float(itm.get("quantity") or 0.0),
                "unit_price_vnd": float(itm.get("unit_price_vnd") or 0.0),
                "total_amount_vnd": float(itm.get("total_amount_vnd") or 0.0),
            }
        )
        added_count += 1

    updated_items = client.list_drawing_takeoff_items(takeoff_id)
    new_total = sum(float(i.get("total_amount_vnd") or 0.0) for i in updated_items)
    client.update_drawing_takeoff(
        takeoff_id,
        {
            "total_estimated_cost_vnd": new_total,
            "ai_analysis_notes": f"Đã thẩm tra và tự động bổ sung {added_count} hạng mục phụ trợ / ván khuôn / đắp đất hoàn chỉnh.",
        },
    )

    return {
        "status": "success",
        "message": f"Đã tự động bổ sung thành công {added_count} hạng mục khuyến nghị từ báo cáo thẩm tra!",
        "added_count": added_count,
        "new_total_items": len(updated_items),
        "new_total_estimated_cost_vnd": new_total,
    }


@router.put(
    "/items/{item_id}/quantities",
    summary="Cập Nhật Khối Lượng Tiên Lượng HSMT hoặc Khối Lượng Thực Tế của Dòng BoQ",
)
def update_item_quantities_endpoint(
    item_id: str,
    req: ItemQuantitiesUpdateRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Cập nhật khối lượng HSMT / Thực tế của một công tác để hệ thống tự động tính tỷ lệ chênh lệch và trạng thái phát sinh."""
    client = ErpDatabaseClient()
    updated = client.update_takeoff_item_quantities(
        item_id=item_id,
        hsmt_quantity=req.hsmt_quantity,
        actual_quantity=req.actual_quantity,
    )
    if not updated:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hạng mục BoQ để cập nhật khối lượng"
        )

    return {
        "status": "success",
        "message": "Đã cập nhật khối lượng và tính toán chênh lệch thành công.",
        "item": updated,
    }
