from __future__ import annotations

from typing import Any

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_TITLE,
    FONT_TOTAL,
)

from .boq_rate_breakdown_service import BoqRateBreakdownEngine


def build_materials_sheet(ws, takeoff: dict[str, Any], items: list[dict[str, Any]]):
    ws.title = "4. Tổng Hợp Vật Tư (MR)"
    ws.views.sheetView[0].showGridLines = True

    ws.merge_cells("A2:G2")
    ws["A2"] = (
        "BẢNG TỔNG HỢP NHU CẦU VẬT TƯ CÔNG TRƯỜNG (MATERIAL REQUISITION SCHEDULE)"
    )
    ws["A2"].font = FONT_TITLE
    ws["A2"].alignment = ALIGN_CENTER

    mr_data = BoqRateBreakdownEngine.aggregate_material_requisition(
        items, project_title=takeoff.get("drawing_title", "Công trình")
    )

    headers = [
        ("A4", "STT"),
        ("B4", "Mã Vật Tư"),
        ("C4", "Tên Loại Vật Tư / Quy Cách"),
        ("D4", "ĐVT"),
        ("E4", "Khối Lượng Nhu Cầu (Kèm Hao Hụt)"),
        ("F4", "Đơn Giá Sở XD Hải Phòng (VNĐ)"),
        ("G4", "Thành Tiền Vật Tư (VNĐ)"),
    ]
    for cell_ref, text in headers:
        ws[cell_ref] = text
        ws[cell_ref].font = FONT_HEADER
        ws[cell_ref].fill = FILL_HEADER
        ws[cell_ref].alignment = ALIGN_CENTER
        ws[cell_ref].border = BORDER_BOX
    ws.row_dimensions[4].height = 28

    current_row = 5
    schedule = mr_data.get("material_schedule", [])
    for idx, mat in enumerate(schedule, 1):
        row_data = [
            (f"A{current_row}", idx, FONT_DATA, ALIGN_CENTER, FMT_INTEGER),
            (
                f"B{current_row}",
                mat.get("material_code") or f"MAT-{idx:02d}",
                FONT_MONO,
                ALIGN_CENTER,
                None,
            ),
            (
                f"C{current_row}",
                mat.get("material_name") or "",
                FONT_DATA,
                ALIGN_LEFT,
                None,
            ),
            (f"D{current_row}", mat.get("unit") or "m3", FONT_DATA, ALIGN_CENTER, None),
            (
                f"E{current_row}",
                float(mat.get("required_quantity") or 0.0),
                FONT_MONO,
                ALIGN_RIGHT,
                FMT_DECIMAL_2,
            ),
            (
                f"F{current_row}",
                float(mat.get("unit_price_vnd") or 0.0),
                FONT_MONO,
                ALIGN_RIGHT,
                FMT_CURRENCY_VND,
            ),
            (
                f"G{current_row}",
                f"=E{current_row}*F{current_row}",
                FONT_MONO,
                ALIGN_RIGHT,
                FMT_CURRENCY_VND,
            ),
        ]

        for cell_ref, val, fnt, alg, num_fmt in row_data:
            ws[cell_ref] = val
            ws[cell_ref].font = fnt
            ws[cell_ref].alignment = alg
            ws[cell_ref].border = BORDER_BOX
            if num_fmt:
                ws[cell_ref].number_format = num_fmt

        ws.row_dimensions[current_row].height = 20
        current_row += 1

    # Total Row
    total_row = current_row
    ws.merge_cells(f"A{total_row}:F{total_row}")
    ws[f"A{total_row}"] = "TỔNG CỘNG CHI PHÍ VẬT TƯ CÔNG TRƯỜNG (VNĐ):"
    ws[f"A{total_row}"].font = FONT_TOTAL
    ws[f"A{total_row}"].alignment = ALIGN_RIGHT
    ws[f"A{total_row}"].fill = FILL_TOTAL

    ws[f"G{total_row}"] = f"=SUM(G5:G{total_row - 1})"
    ws[f"G{total_row}"].font = FONT_TOTAL
    ws[f"G{total_row}"].alignment = ALIGN_RIGHT
    ws[f"G{total_row}"].fill = FILL_TOTAL
    ws[f"G{total_row}"].number_format = FMT_CURRENCY_VND

    for col in ["A", "B", "C", "D", "E", "F", "G"]:
        ws[f"{col}{total_row}"].border = BORDER_TOTAL

    ws.row_dimensions[total_row].height = 24

    widths = {"A": 8, "B": 18, "C": 45, "D": 8, "E": 26, "F": 24, "G": 26}
    for col_letter, width in widths.items():
        ws.column_dimensions[col_letter].width = width
