"""Render extracted invoice data into a tidy XLSX file."""
from openpyxl import Workbook
from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
from openpyxl.utils import get_column_letter


HEADER_FILL = PatternFill("solid", fgColor="2563EB")
HEADER_FONT = Font(bold=True, color="FFFFFF", size=11)
LABEL_FONT = Font(bold=True, size=10)
THIN = Side(style="thin", color="D0D5DC")
BORDER = Border(left=THIN, right=THIN, top=THIN, bottom=THIN)


def write_invoice_xlsx(data: dict, out_path: str) -> None:
    wb = Workbook()
    ws = wb.active
    ws.title = "Faktura"

    # ── Header section ──
    ws.cell(row=1, column=1, value="FAKTURA — extrahovaná data").font = Font(bold=True, size=14)
    ws.merge_cells("A1:D1")

    row = 3
    row = _write_kv_block(ws, row, "Identifikace faktury", [
        ("Číslo faktury", data.get("invoice_number")),
        ("Variabilní symbol", data.get("variable_symbol")),
        ("Konstantní symbol", data.get("constant_symbol")),
        ("Specifický symbol", data.get("specific_symbol")),
        ("Datum vystavení", data.get("issue_date")),
        ("Datum splatnosti", data.get("due_date")),
        ("DUZP", data.get("taxable_date")),
        ("Měna", data.get("currency") or "CZK"),
        ("Způsob platby", data.get("payment_method")),
        ("Číslo účtu", data.get("bank_account")),
        ("IBAN", data.get("iban")),
    ])
    row += 1

    sup = data.get("supplier") or {}
    row = _write_kv_block(ws, row, "Dodavatel", [
        ("Název", sup.get("name")),
        ("IČO", sup.get("ico")),
        ("DIČ", sup.get("dic")),
        ("Adresa", sup.get("address")),
    ])
    row += 1

    cust = data.get("customer") or {}
    row = _write_kv_block(ws, row, "Odběratel", [
        ("Název", cust.get("name")),
        ("IČO", cust.get("ico")),
        ("DIČ", cust.get("dic")),
        ("Adresa", cust.get("address")),
    ])
    row += 1

    # ── Line items table ──
    items = data.get("line_items") or []
    if items:
        row = _write_section_header(ws, row, "Položky faktury")
        headers = ["Popis", "Množství", "Jednotka", "Cena/jed. bez DPH",
                   "Sazba DPH (%)", "Bez DPH", "S DPH"]
        for c, h in enumerate(headers, 1):
            cell = ws.cell(row=row, column=c, value=h)
            cell.font = HEADER_FONT
            cell.fill = HEADER_FILL
            cell.alignment = Alignment(horizontal="center")
            cell.border = BORDER
        row += 1
        for item in items:
            values = [
                item.get("description") or "",
                item.get("quantity"),
                item.get("unit") or "",
                item.get("unit_price_excluding_vat"),
                item.get("vat_rate"),
                item.get("total_excluding_vat"),
                item.get("total_including_vat"),
            ]
            for c, v in enumerate(values, 1):
                cell = ws.cell(row=row, column=c, value=v)
                cell.border = BORDER
                if c >= 4 and isinstance(v, (int, float)):
                    cell.number_format = "#,##0.00"
            row += 1
        row += 1

    # ── VAT breakdown ──
    vat = data.get("vat_breakdown") or []
    if vat:
        row = _write_section_header(ws, row, "Rekapitulace DPH")
        headers = ["Sazba (%)", "Základ", "DPH", "Celkem"]
        for c, h in enumerate(headers, 1):
            cell = ws.cell(row=row, column=c, value=h)
            cell.font = HEADER_FONT
            cell.fill = HEADER_FILL
            cell.alignment = Alignment(horizontal="center")
            cell.border = BORDER
        row += 1
        for br in vat:
            for c, v in enumerate([br.get("rate"), br.get("base"),
                                   br.get("vat"), br.get("total")], 1):
                cell = ws.cell(row=row, column=c, value=v)
                cell.border = BORDER
                if c >= 2 and isinstance(v, (int, float)):
                    cell.number_format = "#,##0.00"
            row += 1
        row += 1

    # ── Totals ──
    row = _write_section_header(ws, row, "Celkem")
    totals = [
        ("Celkem bez DPH", data.get("total_excluding_vat")),
        ("Celkem DPH", data.get("total_vat")),
        ("CELKEM K ÚHRADĚ", data.get("total_including_vat")),
    ]
    for label, val in totals:
        ws.cell(row=row, column=1, value=label).font = LABEL_FONT
        cell = ws.cell(row=row, column=2, value=val)
        if isinstance(val, (int, float)):
            cell.number_format = "#,##0.00"
        if label.startswith("CELKEM K"):
            ws.cell(row=row, column=1).font = Font(bold=True, size=12)
            cell.font = Font(bold=True, size=12)
        row += 1

    if data.get("notes"):
        row += 1
        ws.cell(row=row, column=1, value="Poznámka:").font = LABEL_FONT
        ws.cell(row=row, column=2, value=data["notes"])

    # ── Auto-widths ──
    widths = {1: 32, 2: 14, 3: 10, 4: 16, 5: 14, 6: 14, 7: 14}
    for c, w in widths.items():
        ws.column_dimensions[get_column_letter(c)].width = w

    wb.save(out_path)


def _write_section_header(ws, row: int, text: str) -> int:
    cell = ws.cell(row=row, column=1, value=text)
    cell.font = Font(bold=True, size=12, color="0F1729")
    cell.fill = PatternFill("solid", fgColor="EFF4FF")
    ws.merge_cells(start_row=row, start_column=1, end_row=row, end_column=7)
    return row + 1


def _write_kv_block(ws, row: int, header: str, pairs: list[tuple]) -> int:
    row = _write_section_header(ws, row, header)
    for label, val in pairs:
        ws.cell(row=row, column=1, value=label).font = LABEL_FONT
        ws.cell(row=row, column=2, value=val if val is not None else "")
        row += 1
    return row
