from __future__ import annotations

from decimal import Decimal
from typing import Any

from openpyxl.styles import Font

from app.common.excel_styler import (
    ALIGN_CENTER,
    ALIGN_LEFT,
    ALIGN_RIGHT,
    BORDER_BOX,
    BORDER_TOTAL,
    FILL_HEADER,
    FILL_TOTAL,
    FMT_CURRENCY_VND,
    FMT_DECIMAL_2,
    FMT_INTEGER,
    FONT_DATA,
    FONT_HEADER,
    FONT_MONO,
    FONT_SUBTITLE,
    FONT_TITLE,
    FONT_TOTAL,
)

from .boq_rate_breakdown_service import BoqRateBreakdownEngine


def build_boq_sheet(ws1, takeoff: dict[str, Any], items: list[dict[str, Any]]):
    ws1.title = "2. BoQ Khối Lượng"
    ws1.views.sheetView[0].showGridLines = True

    # Header Enterprise Info
    ws1["A1"] = "CÔNG TY TNHH XÂY DỰNG ĐỊNH SƠN"
    ws1["A1"].font = Font(name="Arial", size=11, bold=True, color="0F172A")
    ws1["A2"] = "Mã số thuế: 0202111150 | Hotline: 0936.565.888"
    ws1["A2"].font = Font(name="Arial", size=9, italic=True, color="475569")

    # Document Title
    ws1.merge_cells("A4:K4")
    ws1["A4"] = "BẢNG DỰ TOÁN CHI PHÍ XÂY DỰNG & BÓC TÁCH KHỐI LƯỢNG BOQ"
    ws1["A4"].font = FONT_TITLE
    ws1["A4"].alignment = ALIGN_CENTER

    project_name = takeoff.get("project_name") or "DỰ ÁN XÂY DỰNG THỰC TẾ"
    ws1.merge_cells("A5:K5")
    ws1["A5"] = (
        f"Hạng mục công trình: {project_name.upper()} - Bản vẽ: {takeoff.get('drawing_name', '')}"
    )
    ws1["A5"].font = FONT_SUBTITLE
    ws1["A5"].alignment = ALIGN_CENTER

    headers = [
        ("A7", "STT"),
        ("B7", "Mã WBS"),
        ("C7", "Mã Hiệu ĐM"),
        ("D7", "Tên Hạng Mục / Công Tác Thi Công"),
        ("E7", "Quy Cách / Kích Thước Hình Học"),
        ("F7", "ĐVT"),
        ("G7", "Khối Lượng"),
        ("H7", "Đơn Giá Vật Liệu (VNĐ)"),
        ("I7", "Đơn Giá Nhân Công & Máy"),
        ("J7", "Đơn Giá Dự Toán 2026"),
        ("K7", "Thành Tiền Dự Toán (VNĐ)"),
    ]
    for cell_ref, text in headers:
        ws1[cell_ref] = text
        ws1[cell_ref].font = FONT_HEADER
        ws1[cell_ref].fill = FILL_HEADER
        ws1[cell_ref].alignment = ALIGN_CENTER
        ws1[cell_ref].border = BORDER_BOX
    ws1.row_dimensions[7].height = 28

    current_row = 8
    total_boq_amount = Decimal(0)

    for idx, item in enumerate(items, 1):
        qty = Decimal(str(item.get("quantity") or 0))
        unit_price = float(item.get("unit_price_vnd") or item.get("unit_price") or 0.0)

        breakdown = BoqRateBreakdownEngine.breakdown_item_rate(
            item_name=item.get("item_name", ""),
            category=item.get("category", ""),
            unit=item.get("unit", "m3"),
            total_unit_price=unit_price,
            norm_code=item.get("norm_code", "AF.11110"),
        )

        vl_price = float(breakdown.get("material_cost_vnd") or 0.0)
        nc_m_price = float(
            (breakdown.get("labor_cost_vnd") or 0.0)
            + (breakdown.get("equipment_cost_vnd") or 0.0)
        )
        final_unit_price = (
            vl_price + nc_m_price if (vl_price + nc_m_price) > 0 else unit_price
        )
        norm_code_val = item.get("norm_code") or breakdown.get("norm_code", "ĐM-2026")

        row_data = [
            (f"A{current_row}", idx, FONT_DATA, ALIGN_CENTER, FMT_INTEGER),
            (
                f"B{current_row}",
                item.get("wbs_code") or f"WBS-{idx:02d}",
                FONT_MONO,
                ALIGN_CENTER,
                None,
            ),
            (f"C{current_row}", norm_code_val, FONT_MONO, ALIGN_CENTER, None),
            (
                f"D{current_row}",
                item.get("item_name") or "",
                FONT_DATA,
                ALIGN_LEFT,
                None,
            ),
            (
                f"E{current_row}",
                item.get("dimension_formula") or item.get("specification") or "",
                FONT_DATA,
                ALIGN_LEFT,
                None,
            ),
            (
                f"F{current_row}",
                item.get("unit") or "m3",
                FONT_DATA,
                ALIGN_CENTER,
                None,
            ),
            (f"G{current_row}", float(qty), FONT_MONO, ALIGN_RIGHT, FMT_DECIMAL_2),
            (f"H{current_row}", vl_price, FONT_MONO, ALIGN_RIGHT, FMT_CURRENCY_VND),
            (f"I{current_row}", nc_m_price, FONT_MONO, ALIGN_RIGHT, FMT_CURRENCY_VND),
            (
                f"J{current_row}",
                f"=H{current_row}+I{current_row}",
                FONT_TOTAL,
                ALIGN_RIGHT,
                FMT_CURRENCY_VND,
            ),
            (
                f"K{current_row}",
                f"=G{current_row}*J{current_row}",
                FONT_MONO,
                ALIGN_RIGHT,
                FMT_CURRENCY_VND,
            ),
        ]

        for cell_ref, val, fnt, alg, num_fmt in row_data:
            ws1[cell_ref] = val
            ws1[cell_ref].font = fnt
            ws1[cell_ref].alignment = alg
            ws1[cell_ref].border = BORDER_BOX
            if num_fmt:
                ws1[cell_ref].number_format = num_fmt

        ws1.row_dimensions[current_row].height = 20
        current_row += 1

    # Total Row
    total_row = current_row
    ws1.merge_cells(f"A{total_row}:J{total_row}")
    ws1[f"A{total_row}"] = "TỔNG CỘNG CHI PHÍ XÂY DỰNG DỰ TOÁN TRƯỚC THUẾ (VNĐ):"
    ws1[f"A{total_row}"].font = FONT_TOTAL
    ws1[f"A{total_row}"].alignment = ALIGN_RIGHT
    ws1[f"A{total_row}"].fill = FILL_TOTAL

    ws1[f"K{total_row}"] = f"=SUM(K8:K{total_row - 1})"
    ws1[f"K{total_row}"].font = FONT_TOTAL
    ws1[f"K{total_row}"].alignment = ALIGN_RIGHT
    ws1[f"K{total_row}"].fill = FILL_TOTAL
    ws1[f"K{total_row}"].number_format = FMT_CURRENCY_VND
    ws1[f"K{total_row}"].border = BORDER_TOTAL
    ws1.row_dimensions[total_row].height = 26

    cols = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"]
    for col in cols:
        ws1[f"{col}{total_row}"].border = BORDER_TOTAL

    col_widths = {
        "A": 6,
        "B": 14,
        "C": 14,
        "D": 42,
        "E": 35,
        "F": 8,
        "G": 14,
        "H": 18,
        "I": 18,
        "J": 18,
        "K": 22,
    }
    for col_letter, width in col_widths.items():
        ws1.column_dimensions[col_letter].width = width
