"""
Modulo generatore — Scrittura del file Excel di output (comparativo e riepilogo).

La funzione principale è genera_comparativo(), che coordina la lettura
dei file e la scrittura dell'output.
"""

import os
from datetime import datetime

from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter

from core.config import (
    SOGLIA_ANOMALIA_PERC, FONT_NAME,
    COL_HEADER_BG, COL_SECTION_BG,
    COL_ANOMALO_ALTO, COL_ANOMALO_BASSO,
    COL_MEDIA_BG, COL_MANCANTE_BG,
)
from core.lettore import (
    leggi_capitolato, estrai_firma_intestazione, leggi_preventivo
)


# ─────────────────────────────────────────────────────────────────
#  FUNZIONE PRINCIPALE
# ─────────────────────────────────────────────────────────────────

def genera_comparativo(capitolato_path, preventivi_paths, nomi_imprese,
                       output_path, log_fn=None, soglia_anomalie=None):
    """
    Genera il file Excel comparativo delle offerte.

    Args:
        capitolato_path:  path del file Excel capitolato di riferimento
        preventivi_paths: lista di path dei file Excel delle imprese
        nomi_imprese:     lista nomi imprese (stesso ordine di preventivi_paths)
        output_path:      path del file Excel di output da creare
        log_fn:           funzione di log opzionale, riceve una stringa
        soglia_anomalie:  soglia % anomalie (se None usa SOGLIA_ANOMALIA_PERC da config)

    Returns:
        output_path se tutto è andato bene
    """
    # Usa la soglia passata oppure quella di default dalla config
    soglia = soglia_anomalie if soglia_anomalie is not None else SOGLIA_ANOMALIA_PERC

    def log(msg):
        if log_fn:
            log_fn(msg)

    # ── Lettura capitolato ──
    log("📋 Lettura capitolato...")
    struttura = leggi_capitolato(capitolato_path)

    # Estrae i num_voce delle righe dati per il confronto con i preventivi
    numeri_voce = {r["num_voce"] for r in struttura if r["tipo"] == "dati"}
    righe_dati  = [r for r in struttura if r["tipo"] == "dati"]
    log(f"   → {len(numeri_voce)} voci prezzabili")

    # ── Estrai firma intestazione per riconoscimento nei preventivi ──
    log("🔍 Estrazione firma intestazione...")
    firma = estrai_firma_intestazione(capitolato_path)

    # ── Lettura preventivi imprese ──
    imprese = []
    for path, nome in zip(preventivi_paths, nomi_imprese):
        nome_file = os.path.basename(path)
        log(f"🏗  Lettura: {nome_file}")
        voci = leggi_preventivo(path, firma, numeri_voce)
        imprese.append({
            "nome": nome,
            "voci": voci,
            "file": path,
        })
        prezzate = sum(1 for v in voci.values() if v is not None)
        mancanti = len(numeri_voce) - prezzate
        log(f"   → {nome}: {prezzate}/{len(numeri_voce)} voci prezzate, "
            f"{mancanti} mancanti")

    n_imprese = len(imprese)

    # ── Calcolo medie per voce (esclude None e 0, usa solo prima riga dati per voce) ──
    medie = {}
    for r in righe_dati:
        num = r["num_voce"]
        if num in medie:
            continue  # usa solo la prima riga dati per ogni voce
        prezzi_validi = [
            imp["voci"].get(num)
            for imp in imprese
            if imp["voci"].get(num) is not None and imp["voci"].get(num) > 0
        ]
        medie[num] = (sum(prezzi_validi) / len(prezzi_validi)
                      if prezzi_validi else None)

    # ── Scrittura Excel ──
    log("📊 Generazione Excel...")
    wb_out = Workbook()
    ws_comp = wb_out.active
    ws_comp.title = "Comparativo"
    _genera_foglio_comparativo(ws_comp, struttura, imprese, medie, n_imprese, soglia)

    ws_riepilogo = wb_out.create_sheet("Riepilogo")
    _genera_foglio_riepilogo(ws_riepilogo, struttura, imprese, medie, n_imprese)

    wb_out.save(output_path)
    log(f"✅ File salvato: {os.path.basename(output_path)}")
    return output_path


# ─────────────────────────────────────────────────────────────────
#  FOGLIO COMPARATIVO
# ─────────────────────────────────────────────────────────────────

def _genera_foglio_comparativo(ws, struttura, imprese, medie, n_imprese,
                                soglia=None):
    """
    Scrive il foglio 'Comparativo' dell'Excel di output.

    Replica fedelmente la struttura del capitolato:
    ogni riga del capitolato corrisponde a una riga nell'output.
    I prezzi imprese vengono aggiunti SOLO sulle righe di tipo 'dati'
    (quelle con U.M. in col C e quantità totale in col D).

    Layout colonne:
      A-D   = contenuto originale del capitolato
      E..   = prezzi unitari imprese (solo righe dati)
      +N+1  = media P.U.
      +N+2  = totali imprese (formula Excel = D * PU)
      fine  = note anomalie
    """
    if soglia is None:
        soglia = SOGLIA_ANOMALIA_PERC

    # ── Helper stile ──
    bordo_sottile = Side(style="thin",   color="BFBFBF")
    bordo_medio   = Side(style="medium", color="2E75B6")
    b  = Border(left=bordo_sottile, right=bordo_sottile,
                top=bordo_sottile,  bottom=bordo_sottile)
    bs = Border(left=bordo_medio,   right=bordo_medio,
                top=bordo_medio,    bottom=bordo_medio)

    def sfondo(colore):
        return PatternFill("solid", start_color=colore)

    def allin(orizzontale="center", verticale="center", a_capo=False, rientro=0):
        return Alignment(horizontal=orizzontale, vertical=verticale,
                         wrap_text=a_capo, indent=rientro)

    # ── Indici di colonna ──
    col_pu_inizio  = 5                        # prima colonna PU imprese (E)
    col_media      = 5 + n_imprese            # colonna media P.U.
    col_tot_inizio = col_media + 1            # prima colonna totali
    col_note       = col_tot_inizio + n_imprese  # colonna note anomalie
    ultima_col     = get_column_letter(col_note)

    # ── Larghezze colonne ──
    ws.column_dimensions["A"].width = 8
    ws.column_dimensions["B"].width = 52
    ws.column_dimensions["C"].width = 9
    ws.column_dimensions["D"].width = 11
    for i in range(n_imprese):
        ws.column_dimensions[get_column_letter(col_pu_inizio + i)].width = 14
    ws.column_dimensions[get_column_letter(col_media)].width = 14
    for i in range(n_imprese):
        ws.column_dimensions[get_column_letter(col_tot_inizio + i)].width = 14
    ws.column_dimensions[get_column_letter(col_note)].width = 32

    # ── Riga 1: Titolo ──
    ws.row_dimensions[1].height = 28
    ws.merge_cells(f"A1:{ultima_col}1")
    c = ws["A1"]
    c.value     = f"COMPARATIVO OFFERTE — {datetime.now().strftime('%d/%m/%Y %H:%M')}"
    c.font      = Font(name=FONT_NAME, bold=True, size=12, color="FFFFFF")
    c.fill      = sfondo(COL_HEADER_BG)
    c.alignment = allin("left", rientro=2)

    # ── Riga 2: Legenda colori ──
    ws.row_dimensions[2].height = 16
    ws.merge_cells(f"A2:{ultima_col}2")
    c = ws["A2"]
    c.value     = (f"Soglia anomalie: ±{soglia}%  |  "
                   "ROSSO = prezzo alto   VERDE = prezzo basso   "
                   "GIALLO = voce mancante (usata media)")
    c.font      = Font(name=FONT_NAME, size=8, italic=True, color="404040")
    c.fill      = sfondo("D6E4F0")
    c.alignment = allin("left", rientro=2)

    # ── Riga 3: Raggruppamenti colonne ──
    ws.row_dimensions[3].height = 18
    for col in range(1, 5):
        ws.cell(row=3, column=col).fill   = sfondo(COL_HEADER_BG)
        ws.cell(row=3, column=col).border = b

    col_pu_fine  = col_pu_inizio + n_imprese - 1
    col_tot_fine = col_tot_inizio + n_imprese - 1

    ws.merge_cells(f"{get_column_letter(col_pu_inizio)}3:"
                   f"{get_column_letter(col_pu_fine)}3")
    c = ws.cell(row=3, column=col_pu_inizio, value="PREZZI UNITARI (€)")
    c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
    c.fill      = sfondo(COL_SECTION_BG)
    c.alignment = allin()
    for col in range(col_pu_inizio, col_pu_fine + 1):
        ws.cell(row=3, column=col).border = b

    c = ws.cell(row=3, column=col_media, value="")
    c.fill   = sfondo("375623")
    c.border = b

    ws.merge_cells(f"{get_column_letter(col_tot_inizio)}3:"
                   f"{get_column_letter(col_tot_fine)}3")
    c = ws.cell(row=3, column=col_tot_inizio, value="TOTALI (€)")
    c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
    c.fill      = sfondo(COL_SECTION_BG)
    c.alignment = allin()
    for col in range(col_tot_inizio, col_tot_fine + 1):
        ws.cell(row=3, column=col).border = b

    c = ws.cell(row=3, column=col_note, value="")
    c.fill   = sfondo(COL_HEADER_BG)
    c.border = b

    # ── Riga 4: Intestazioni colonne ──
    ws.row_dimensions[4].height = 30
    for col, intestazione in enumerate(["N°", "DESCRIZIONE LAVORAZIONE",
                                        "U.M.", "QUANTITÀ"], 1):
        c = ws.cell(row=4, column=col, value=intestazione)
        c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
        c.fill      = sfondo(COL_HEADER_BG)
        c.alignment = allin(a_capo=True)
        c.border    = b

    for i, imp in enumerate(imprese):
        c = ws.cell(row=4, column=col_pu_inizio + i, value=imp["nome"].upper())
        c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
        c.fill      = sfondo(COL_SECTION_BG)
        c.alignment = allin(a_capo=True)
        c.border    = b

    c = ws.cell(row=4, column=col_media, value="MEDIA P.U.")
    c.font      = Font(name=FONT_NAME, bold=True, size=9, color="1F4E79")
    c.fill      = sfondo(COL_MEDIA_BG)
    c.alignment = allin(a_capo=True)
    c.border    = b

    for i, imp in enumerate(imprese):
        c = ws.cell(row=4, column=col_tot_inizio + i, value=imp["nome"].upper())
        c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
        c.fill      = sfondo(COL_SECTION_BG)
        c.alignment = allin(a_capo=True)
        c.border    = b

    c = ws.cell(row=4, column=col_note, value="NOTE ANOMALIE")
    c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
    c.fill      = sfondo(COL_HEADER_BG)
    c.alignment = allin(a_capo=True)
    c.border    = b

    ws.freeze_panes = "A5"

    # ── Variabili di stato per scorrere le righe ──
    riga_corrente = 5
    righe_totali  = []  # righe con formule totale, per la somma finale

    # ── Scrittura righe ──
    for riga in struttura:
        tipo = riga["tipo"]

        # ── Riga vuota ──
        if tipo == "vuota":
            ws.row_dimensions[riga_corrente].height = 8
            riga_corrente += 1
            continue

        # ── Riga testo (tutto ciò che non ha quantità: titoli, descrizioni, note) ──
        if tipo == "testo":
            ws.row_dimensions[riga_corrente].height = 14
            # Col A: eventuale codice/numero
            if riga.get("col_a"):
                c_a = ws.cell(row=riga_corrente, column=1, value=riga["col_a"])
                c_a.font      = Font(name=FONT_NAME, bold=True, size=9,
                                     color=COL_HEADER_BG)
                c_a.alignment = allin("center")
            # Col B: testo descrittivo
            if riga.get("col_b"):
                c_b = ws.cell(row=riga_corrente, column=2, value=riga["col_b"])
                c_b.font      = Font(name=FONT_NAME, size=9, color="404040")
                c_b.alignment = Alignment(horizontal="left", vertical="center",
                                          wrap_text=True)
            riga_corrente += 1
            continue

        # ── Riga dati (ha quantità in col D → prezzi imprese) ──
        if tipo == "dati":
            num_voce = riga.get("num_voce")
            qta      = riga["col_d"]
            media    = medie.get(num_voce) if num_voce else None

            ws.row_dimensions[riga_corrente].height = 16

            # Colonna A: codice/numero voce
            if riga.get("col_a"):
                c_a = ws.cell(row=riga_corrente, column=1, value=riga["col_a"])
                c_a.font      = Font(name=FONT_NAME, bold=True, size=9,
                                     color=COL_HEADER_BG)
                c_a.alignment = allin("center")
                c_a.fill      = sfondo("EEF4FB")
                c_a.border    = b

            # Colonna B: descrizione breve
            if riga.get("col_b"):
                c_b = ws.cell(row=riga_corrente, column=2, value=riga["col_b"])
                c_b.font      = Font(name=FONT_NAME, bold=True, size=9)
                c_b.alignment = Alignment(horizontal="left", vertical="center",
                                          wrap_text=True)
                c_b.fill      = sfondo("EEF4FB")
                c_b.border    = b

            # Colonna C: U.M.
            c_um = ws.cell(row=riga_corrente, column=3, value=riga["col_c"])
            c_um.font      = Font(name=FONT_NAME, size=9)
            c_um.alignment = allin("center")
            c_um.border    = b

            # Colonna D: quantità totale
            c_qta = ws.cell(row=riga_corrente, column=4, value=qta)
            c_qta.font          = Font(name=FONT_NAME, size=9)
            c_qta.number_format = "#,##0.00"
            c_qta.alignment     = allin("right")
            c_qta.border        = b

            # Colonne PU: prezzo unitario per ogni impresa
            note_anomalie = []
            for i, imp in enumerate(imprese):
                prezzo   = imp["voci"].get(num_voce) if num_voce else None
                mancante = prezzo is None or prezzo == 0
                prezzo_display = media if (mancante and media) else (prezzo or 0)

                # Verifica anomalia rispetto alla media
                e_alto = e_basso = False
                if media and media > 0 and not mancante and prezzo_display:
                    delta = (prezzo_display - media) / media * 100
                    if delta > soglia:
                        e_alto = True
                        note_anomalie.append(
                            f"{imp['nome']}: +{delta:.0f}% (ALTO)")
                    elif delta < -soglia:
                        e_basso = True
                        note_anomalie.append(
                            f"{imp['nome']}: {delta:.0f}% (BASSO)")

                c_pu = ws.cell(row=riga_corrente,
                               column=col_pu_inizio + i,
                               value=prezzo_display)
                c_pu.font = Font(
                    name=FONT_NAME, size=9,
                    bold=(e_alto or e_basso),
                    italic=mancante,
                    color="C00000" if e_alto else
                          ("375623" if e_basso else
                           ("7F7F7F" if mancante else "000000")),
                )
                c_pu.number_format = "#,##0.00"
                c_pu.alignment     = allin("right")
                c_pu.border        = b
                c_pu.fill          = sfondo(
                    COL_MANCANTE_BG if mancante else
                    (COL_ANOMALO_ALTO if e_alto else
                     (COL_ANOMALO_BASSO if e_basso else "FFFFFF"))
                )

            # Colonna Media P.U.
            c_med = ws.cell(row=riga_corrente, column=col_media,
                            value=media if media else "—")
            c_med.font      = Font(name=FONT_NAME, size=9, bold=True,
                                   color="375623")
            c_med.fill      = sfondo(COL_MEDIA_BG)
            c_med.alignment = allin("right")
            c_med.border    = b
            if media:
                c_med.number_format = "#,##0.00"

            # Colonne Totali: formula Excel = D_riga * PU_col_riga
            for i in range(n_imprese):
                col_pu_let = get_column_letter(col_pu_inizio + i)
                c_tot = ws.cell(
                    row=riga_corrente,
                    column=col_tot_inizio + i,
                    value=f"=D{riga_corrente}*{col_pu_let}{riga_corrente}",
                )
                c_tot.font          = Font(name=FONT_NAME, size=9)
                c_tot.number_format = "€#,##0.00"
                c_tot.alignment     = allin("right")
                c_tot.border        = b
                prezzo_i   = imprese[i]["voci"].get(num_voce) if num_voce else None
                mancante_i = prezzo_i is None or prezzo_i == 0
                c_tot.fill = sfondo(COL_MANCANTE_BG if mancante_i else "F8F8F8")

            # Colonna note anomalie
            testo_note = " | ".join(note_anomalie) if note_anomalie else ""
            c_note = ws.cell(row=riga_corrente, column=col_note,
                             value=testo_note)
            c_note.font      = Font(name=FONT_NAME, size=8, italic=True,
                                    color="C00000" if note_anomalie else "7F7F7F")
            c_note.alignment = Alignment(horizontal="left", vertical="center",
                                         wrap_text=True)
            c_note.border    = b

            righe_totali.append(riga_corrente)
            riga_corrente += 1

    # ── Riga totale finale ──
    riga_corrente += 1
    ws.row_dimensions[riga_corrente].height = 26
    ws.merge_cells(f"A{riga_corrente}:D{riga_corrente}")
    c = ws.cell(row=riga_corrente, column=1,
                value="TOTALE OFFERTA (IVA ESCLUSA)")
    c.font      = Font(name=FONT_NAME, bold=True, size=10, color="FFFFFF")
    c.fill      = sfondo(COL_HEADER_BG)
    c.alignment = allin("right")
    c.border    = b

    for i in range(n_imprese):
        c = ws.cell(row=riga_corrente, column=col_pu_inizio + i, value="—")
        c.font      = Font(name=FONT_NAME, bold=True, color="FFFFFF")
        c.fill      = sfondo(COL_HEADER_BG)
        c.alignment = allin()
        c.border    = b

    c = ws.cell(row=riga_corrente, column=col_media, value="—")
    c.font      = Font(name=FONT_NAME, bold=True, color="FFFFFF")
    c.fill      = sfondo(COL_HEADER_BG)
    c.alignment = allin()
    c.border    = b

    for i in range(n_imprese):
        col_let       = get_column_letter(col_tot_inizio + i)
        formula_somma = "+".join([f"{col_let}{r}" for r in righe_totali])
        c_tot = ws.cell(row=riga_corrente, column=col_tot_inizio + i,
                        value=f"={formula_somma}")
        c_tot.font          = Font(name=FONT_NAME, bold=True, size=10,
                                   color="FFFFFF")
        c_tot.fill          = sfondo(COL_HEADER_BG)
        c_tot.number_format = "€#,##0.00"
        c_tot.alignment     = allin("right")
        c_tot.border        = b

    c = ws.cell(row=riga_corrente, column=col_note, value="")
    c.fill   = sfondo(COL_HEADER_BG)
    c.border = b


# ─────────────────────────────────────────────────────────────────
#  FOGLIO RIEPILOGO
# ─────────────────────────────────────────────────────────────────

def _genera_foglio_riepilogo(ws_r, struttura, imprese, medie, n_imprese):
    """
    Scrive il foglio 'Riepilogo' dell'Excel di output.

    Le sezioni sono identificate come righe 'testo' precedute da riga 'vuota'.
    Per ogni sezione calcola il totale = somma(qta * prezzo) per le voci dentro.
    Mostra anche il totale generale e lo scarto percentuale max-min tra imprese.
    """
    def sfondo(colore):
        return PatternFill("solid", start_color=colore)

    bordo_sottile = Side(style="thin", color="BFBFBF")
    bordo         = Border(left=bordo_sottile, right=bordo_sottile,
                           top=bordo_sottile,  bottom=bordo_sottile)

    def allin(orizzontale="center"):
        return Alignment(horizontal=orizzontale, vertical="center")

    n_cols         = n_imprese + 2
    ultima_col_let = get_column_letter(n_cols)

    ws_r.column_dimensions["A"].width = 38
    for i in range(1, n_imprese + 2):
        ws_r.column_dimensions[get_column_letter(i + 1)].width = 18

    # ── Titolo ──
    ws_r.merge_cells(f"A1:{ultima_col_let}1")
    c = ws_r.cell(row=1, column=1, value="RIEPILOGO PER SEZIONE")
    c.font      = Font(name=FONT_NAME, bold=True, size=12, color="FFFFFF")
    c.fill      = sfondo(COL_HEADER_BG)
    c.alignment = allin("left")

    # ── Intestazione ──
    ws_r.row_dimensions[2].height = 25
    c = ws_r.cell(row=2, column=1, value="SEZIONE")
    c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
    c.fill      = sfondo(COL_HEADER_BG)
    c.alignment = allin("left")
    c.border    = bordo
    for i, imp in enumerate(imprese):
        c = ws_r.cell(row=2, column=i + 2, value=imp["nome"].upper())
        c.font      = Font(name=FONT_NAME, bold=True, size=9, color="FFFFFF")
        c.fill      = sfondo(COL_SECTION_BG)
        c.alignment = allin()
        c.border    = bordo
    c = ws_r.cell(row=2, column=n_imprese + 2, value="SCARTO MAX-MIN")
    c.font      = Font(name=FONT_NAME, bold=True, size=9, color="1F4E79")
    c.fill      = sfondo(COL_MEDIA_BG)
    c.alignment = allin()
    c.border    = bordo

    # ── Identifica le sezioni (righe 'testo' con col_b, precedute da 'vuota') ──
    sezioni_trovate = []
    for idx, riga in enumerate(struttura):
        if riga["tipo"] == "testo" and riga.get("col_b"):
            precedente = struttura[idx - 1] if idx > 0 else None
            if precedente and precedente["tipo"] == "vuota":
                sezioni_trovate.append(riga["col_b"])

    # ── Calcolo totali per sezione ──
    totali_sezione = {s: {imp["nome"]: 0.0 for imp in imprese}
                      for s in sezioni_trovate}
    totali_sezione["TOTALE GENERALE"] = {imp["nome"]: 0.0 for imp in imprese}

    sezione_corrente = None
    for riga in struttura:
        if (riga["tipo"] == "testo"
                and riga.get("col_b") in totali_sezione):
            sezione_corrente = riga["col_b"]
        elif riga["tipo"] == "dati":
            num  = riga.get("num_voce")
            qta  = riga.get("col_d") or 0
            for imp in imprese:
                prezzo = imp["voci"].get(num) if num else None
                if prezzo is None or prezzo == 0:
                    prezzo = medie.get(num) or 0
                totale_voce = qta * prezzo
                if sezione_corrente and sezione_corrente in totali_sezione:
                    totali_sezione[sezione_corrente][imp["nome"]] += totale_voce
                totali_sezione["TOTALE GENERALE"][imp["nome"]] += totale_voce

    # ── Scrittura righe ──
    riga_corrente = 3
    for nome_sezione, totali_imp in totali_sezione.items():
        e_totale      = (nome_sezione == "TOTALE GENERALE")
        col_sfondo    = (COL_HEADER_BG if e_totale else
                         ("F2F2F2" if riga_corrente % 2 == 0 else "FFFFFF"))
        col_testo     = "FFFFFF" if e_totale else "000000"

        ws_r.row_dimensions[riga_corrente].height = 18
        c = ws_r.cell(row=riga_corrente, column=1, value=nome_sezione)
        c.font      = Font(name=FONT_NAME, bold=e_totale, size=9,
                           color=col_testo)
        c.fill      = sfondo(col_sfondo)
        c.alignment = Alignment(horizontal="left", vertical="center", indent=1)
        c.border    = bordo

        valori = []
        for i, imp in enumerate(imprese):
            val = totali_imp[imp["nome"]]
            valori.append(val)
            c = ws_r.cell(row=riga_corrente, column=i + 2, value=val)
            c.font          = Font(name=FONT_NAME, bold=e_totale, size=9,
                                   color=col_testo)
            c.fill          = sfondo(col_sfondo)
            c.number_format = "€#,##0.00"
            c.alignment     = allin("right")
            c.border        = bordo

        scarto     = max(valori) - min(valori) if len(valori) >= 2 else 0
        scarto_pct = (scarto / min(valori) * 100
                      if len(valori) >= 2 and min(valori) > 0 else 0)
        testo_sc   = f"€{scarto:,.0f}  ({scarto_pct:.1f}%)"
        c = ws_r.cell(row=riga_corrente, column=n_imprese + 2, value=testo_sc)
        c.font      = Font(
            name=FONT_NAME, bold=e_totale, size=9,
            color=col_testo if e_totale else
                  ("C00000" if scarto_pct > 15 else "000000"),
        )
        c.fill      = sfondo(col_sfondo if e_totale else COL_MEDIA_BG)
        c.alignment = allin("right")
        c.border    = bordo
        riga_corrente += 1

    ws_r.freeze_panes = "A3"
