from __future__ import annotations

from pathlib import Path
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font, PatternFill
from openpyxl.utils import get_column_letter

from models import Identity

HEADER_FILL = PatternFill("solid", fgColor="FF111827")
HEADER_FONT = Font(color="FFFFFFFF", bold=True)
GOLD_FILL = PatternFill("solid", fgColor="FFFFF1B8")


def _style_header(ws):
    for cell in ws[1]:
        cell.fill = HEADER_FILL
        cell.font = HEADER_FONT
        cell.alignment = Alignment(horizontal="center", vertical="center")
    ws.freeze_panes = "A2"
    ws.auto_filter.ref = ws.dimensions


def export_catalog_xlsx(catalog, rules, destination: Path, cached_stats: list[dict] | None = None) -> Path:
    destination = Path(destination)
    wb = Workbook()
    summary = wb.active
    summary.title = "Podsumowanie"
    summary.append(["Kategoria", "Bazy", "Prefixy + brak", "Suffixy + brak", "Tożsamości", "Pełne warianty"])
    for row in catalog.statistics():
        summary.append([
            row["label"], row["bases"], row["prefixes_with_blank"], row["suffixes_with_blank"],
            row["identities"], row["variants"],
        ])
    summary.append(["RAZEM", "", "", "", catalog.identity_count(), catalog.variant_count()])
    _style_header(summary)
    for col, width in enumerate([24, 12, 16, 16, 16, 18], 1):
        summary.column_dimensions[get_column_letter(col)].width = width

    ws = wb.create_sheet("Tożsamości przedmiotów")
    ws.append(["Kategoria", "Prefix key", "Prefix", "Baza key", "Baza", "Suffix key", "Suffix", "Nazwa"])
    for ident in catalog.identities():
        identity = Identity(ident.category, ident.base, ident.prefix, ident.suffix, False)
        ws.append([
            rules.category_label(ident.category),
            ident.prefix,
            rules.prefix_filter_label(ident.prefix) if ident.prefix else "Brak",
            ident.base,
            rules.display(ident.base),
            ident.suffix,
            rules.display(ident.suffix) if ident.suffix else "Brak",
            rules.identity_display(identity),
        ])
    _style_header(ws)
    widths = [22, 22, 20, 24, 24, 24, 24, 48]
    for col, width in enumerate(widths, 1):
        ws.column_dimensions[get_column_letter(col)].width = width

    levels = wb.create_sheet("Poziomy jakości")
    levels.append(["Class ID", "Jakość", "Ulepszenie", "Etykieta"])
    qualities = ["Zwykły", "Dobry", "Doskonały", "Epicki"]
    for rank, quality in enumerate(qualities):
        for upgrade in range(6):
            label = quality + (f" +{upgrade}" if upgrade else "")
            levels.append([rank * 6 + upgrade, quality, upgrade, label])
    _style_header(levels)
    for col, width in enumerate([12, 16, 14, 18], 1):
        levels.column_dimensions[get_column_letter(col)].width = width

    if cached_stats is not None:
        cache = wb.create_sheet("Cache statystyk")
        headers = [
            "Nazwa", "Kategoria", "Prefix", "Baza", "Suffix", "Jakość", "+", "Legendarny",
            "Poziom gracza", "Obrażenia", "Obrona", "Cechy", "Wymagania", "Cena",
            "Cena sprzedaży", "Mana", "Nanity", "Strefa", "Rzadkość", "URL", "Pobrano",
        ]
        cache.append(headers)
        for row in cached_stats:
            cache.append([
                row.get("item_name", ""), rules.category_label(row.get("category", "")),
                rules.prefix_filter_label(row.get("prefix", "")) if row.get("prefix") else "Brak",
                rules.display(row.get("base", "")), rules.display(row.get("suffix", "")) if row.get("suffix") else "Brak",
                row.get("quality", ""), row.get("upgrade", 0), "TAK" if row.get("legendary") else "NIE",
                row.get("player_level", 80), row.get("damage", ""), row.get("defense", ""),
                row.get("features", ""), row.get("requirements", ""), row.get("price", ""),
                row.get("sell_price", ""), row.get("mana", ""), row.get("nanites", ""),
                row.get("zone_total", ""), row.get("rarity_total", ""), row.get("url", ""),
                row.get("fetched_at", ""),
            ])
            if row.get("legendary"):
                for cell in cache[cache.max_row]:
                    cell.fill = GOLD_FILL
        _style_header(cache)
        for col, width in enumerate([42,20,20,24,24,14,6,12,12,18,12,45,45,18,18,10,10,22,22,55,22],1):
            cache.column_dimensions[get_column_letter(col)].width = width
        cache.sheet_view.showGridLines = False

    wb.save(destination)
    return destination
