#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Scorecard MODE — GP_stat (Ganho Percentual) para variáveis de SUPERFÍCIE
Compara RMSE do BAM_SMNA (EXP2) contra BAM_NCEP (EXP1).
Verificação contra ERA5.

Gera UM painel PNG por domínio encontrado em BASE_DIR.
"""

from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import seaborn as sns

# =========================================================
# 1) Configurações
# =========================================================
BASE_DIR = Path("/mnt/beegfs/thaisa.lopes/SCANTEC/dataout/SMNA_x_NCEP/CFSR_SURF")

ARQ_NCEP = "RMSEBAM_NCEP_20251020002025111200T.scan"
ARQ_SMNA = "RMSEBAM_SMNA_20251020002025111200T.scan"

REMOVER_0H = True

VMIN, VMAX  = -6, 6
DEAD_ZONE   = 1
EXTEND_FRAC = 0.05

OUT_DIR = Path("scorecards_gp_surf")
OUT_DIR.mkdir(exist_ok=True)

# ---- Nomes legíveis dos domínios ----
# A chave deve ser EXATAMENTE o nome da pasta dentro de BASE_DIR.
NOMES_DOMINIOS = {
    # Globais / grandes regiões
    "GLOBAL": "Global",
    "GL":     "Global",
    "AS":     "América do Sul",
    "SAM":    "América do Sul",
    "SA":     "América do Sul",
    "AFRIC":  "África",
    "AF":     "África",
    "EU":     "Europa",
    "EUR":    "Europa",
    "NA":     "América do Norte",
    "NAN":    "América do Norte",
    "AUST":   "Austrália",
    "AUS":    "Austrália",
    "ANT":    "Antártida",
    "ARC":    "Ártico",
    "ASIA":   "Ásia",
    "IND":    "Índia",
    "CHINA":  "China",
    "JPN":    "Japão",
    "SEA":    "Sudeste Asiático",
    "PAC":    "Pacífico",
    "ATL":    "Atlântico",
    "MED":    "Mediterrâneo",
    "BR":     "Brasil",
    "NEB":    "Nordeste do Brasil",
    "AMZ":    "Amazônia",
    "SIB":    "Sibéria",
    "HIMAL":  "Himalaia",
    "TP":     "Planalto Tibetano",
}


def nome_legivel(dominio: str) -> str:
    """Nome bonito do domínio; fallback = código em maiúsculas."""
    return NOMES_DOMINIOS.get(dominio.upper(), dominio.upper())


# =========================================================
# 1b) Colormap com dead zone
# =========================================================
def make_cmap_com_deadzone(vmin, vmax, dead, base_cmap="RdYlGn"):
    base = plt.get_cmap(base_cmap)
    n = 256
    cores = []
    for i in range(n):
        val = vmin + (vmax - vmin) * i / (n - 1)
        if -dead <= val <= dead:
            cores.append((0.92, 0.92, 0.92, 1.0))
        else:
            pos = (val - vmin) / (vmax - vmin)
            cores.append(base(pos))
    return mcolors.LinearSegmentedColormap.from_list(
        "RdYlGn_deadzone", cores, N=n
    )

CMAP = make_cmap_com_deadzone(VMIN, VMAX, DEAD_ZONE, "RdYlGn")


# =========================================================
# 2) Leitura de um .scan (SURF)
# =========================================================
def ler_scan(caminho):
    with open(caminho) as f:
        linhas = f.readlines()

    header = next(l for l in linhas if l.strip().startswith("%"))
    partes = header.replace("%Previsao", "").split()
    variaveis = [p.split(":")[0] for p in partes]

    dados, horas = [], []
    for l in linhas:
        l = l.strip()
        if not l or l.startswith("%"):
            continue
        vals = l.split()
        horas.append(int(vals[0]))
        dados.append([float(v) for v in vals[1:]])

    df = pd.DataFrame(dados, columns=variaveis, index=horas)
    df.index.name = "Hora"
    return df


# =========================================================
# 3) Gera painel de UM domínio
# =========================================================
def gera_painel(dominio, caminho_ncep, caminho_smna, nome_painel, arq_saida):
    exp1 = ler_scan(caminho_ncep)
    exp2 = ler_scan(caminho_smna)

    # Alinha exp2 ao exp1 (evita NaNs por label desalinhado)
    exp2 = exp2.reindex(index=exp1.index, columns=exp1.columns)

    print(f"\n[{dominio}] exp1.shape={exp1.shape}  exp2.shape={exp2.shape}")
    print(f"[{dominio}] variáveis: {list(exp1.columns)}")
    print(f"[{dominio}] horas    : {list(exp1.index)}")

    gp = (1 - exp2 / exp1) * 100

    if REMOVER_0H and 0 in gp.index:
        gp = gp.drop(index=0)

    variaveis = list(gp.columns)
    horas     = list(gp.index)
    matriz    = gp.T.reindex(index=variaveis, columns=horas)

    n_var, n_hor = len(variaveis), len(horas)

    # ---- Figura ----
    fig, ax = plt.subplots(
        figsize=(0.6 * n_hor + 3.5, 0.5 * n_var + 1.7),
        constrained_layout=True,
    )

    sns.heatmap(
        matriz, ax=ax, cmap=CMAP, center=0,
        vmin=VMIN, vmax=VMAX,
        annot=True, fmt=".1f",
        annot_kws={"size": 8, "color": "black"},
        cbar=False,
        linewidths=0.4, linecolor="black",
    )

    ax.set_title(nome_painel, fontsize=14, fontweight="bold", pad=10)
    ax.set_xlabel("Hora", fontsize=11)
    ax.set_ylabel("")

    ax.set_yticks(np.arange(n_var) + 0.5)
    ax.set_yticklabels(variaveis, rotation=0, fontsize=9)

    ax.set_xticks(np.arange(n_hor) + 0.5)
    ax.set_xticklabels([f"{h:03d}" for h in horas], rotation=0, fontsize=10)

    # ---- Barra de cor ----
    cbar_ax = fig.add_axes([1.02, 0.15, 0.02, 0.70])
    sm = plt.cm.ScalarMappable(
        cmap=CMAP, norm=plt.Normalize(vmin=VMIN, vmax=VMAX)
    )
    sm.set_array([])
    fig.colorbar(
        sm, cax=cbar_ax, label="GP (%)",
        extend="both", extendfrac=EXTEND_FRAC,
        ticks=[-6, -3, -1, 1, 3, 6],
    )

    fig.suptitle(
        f"Scorecard (superfície) — {nome_painel} | "
        "Ganho percentual (GP$_{stat}$)\n"
        "EXP2 = BAM_SMNA | EXP1 = BAM_NCEP | Verificação: ERA5 | "
        "EXP$_{perfeito}$ = 0",
        fontsize=12, y=1.09,
    )

    plt.savefig(arq_saida, dpi=300, bbox_inches="tight",
                facecolor="white", edgecolor="none")
    plt.close(fig)

    print(f"[{dominio}] ✅ salvo: {arq_saida}")


# =========================================================
# 4) Loop sobre todos os domínios encontrados
# =========================================================
dominios = sorted([
    d.name for d in BASE_DIR.iterdir()
    if d.is_dir()
    and (d / ARQ_NCEP).exists()
    and (d / ARQ_SMNA).exists()
])

if not dominios:
    raise SystemExit(f"❌ Nenhum domínio com os arquivos .scan em {BASE_DIR}")

print(f"🔎 Domínios encontrados: {dominios}")

for dominio in dominios:
    caminho_ncep = BASE_DIR / dominio / ARQ_NCEP
    caminho_smna = BASE_DIR / dominio / ARQ_SMNA

    nome_painel = nome_legivel(dominio)
    arq_saida   = OUT_DIR / f"scorecard_gp_surf_{dominio.lower()}.png"

    gera_painel(dominio, caminho_ncep, caminho_smna, nome_painel, arq_saida)

print(f"\n🎉 Concluído. PNGs em: {OUT_DIR.resolve()}")
