"""
Constrói a base de dados da calculadora Benfazer a partir dos ficheiros
originais da Agribalyse 3.2 (ADEME) e das traduções para português.

Entradas (nesta pasta):
  original/agribalyse-3.2-synthese.csv          valores por kg de alimento
  original/agribalyse-3.2-detail-par-etape.csv  os mesmos valores divididos por etapa
  traducao/nomes.tsv                             nome em português de cada alimento
  traducao/grupos.tsv                            grupos e subgrupos em português

Saídas:
  alimentos.csv   uma linha por alimento, pronta a importar e a publicar
  alimentos.sql   criação da tabela agb_alimentos e inserção dos dados

Os valores numéricos não são alterados: são copiados tal como estão na fonte.

Uso:  python3 construir.py
"""
import csv
import os

AQUI = os.path.dirname(os.path.abspath(__file__))
VERSAO_DADOS = "Agribalyse 3.2"
DATA_DOWNLOAD = "2026-10-27"

# coluna no ficheiro de síntese -> (coluna nossa, unidade)
INDICADORES = [
    ("Changement climatique", "co2_kg", "kg CO2 eq/kg"),
    ("Utilisation du sol", "uso_solo_pt", "Pt/kg"),
    ("Épuisement des ressources eau", "agua_m3_privacao", "m3 depriv./kg"),
    ("Score unique EF", "score_ef_mpt", "mPt/kg"),
    ("Changement climatique - émissions fossiles", "co2_fossil_kg", "kg CO2 eq/kg"),
    ("Changement climatique - émissions biogéniques", "co2_biogenico_kg", "kg CO2 eq/kg"),
    ("Changement climatique - émissions liées au changement d'affectation des sols", "co2_alteracao_uso_solo_kg", "kg CO2 eq/kg"),
    ("Eutrophisation eaux douces", "eutrofizacao_agua_doce", "kg P eq/kg"),
    ("Eutrophisation marine", "eutrofizacao_marinha", "kg N eq/kg"),
    ("Eutrophisation terrestre", "eutrofizacao_terrestre", "mol N eq/kg"),
    ("Acidification terrestre et eaux douces", "acidificacao", "mol H+ eq/kg"),
    ("Particules fines", "particulas_finas", "disease inc./kg"),
    ("Épuisement des ressources énergétiques", "recursos_energeticos_mj", "MJ/kg"),
    ("Épuisement des ressources minéraux", "recursos_minerais", "kg Sb eq/kg"),
    ("Appauvrissement de la couche d'ozone", "camada_ozono", "kg CFC11 eq/kg"),
    ("Formation photochimique d'ozone", "ozono_fotoquimico", "kg NMVOC eq/kg"),
    ("Rayonnements ionisants", "radiacao_ionizante", "kBq U-235 eq/kg"),
    ("Effets toxicologiques sur la santé humaine : substances non-cancérogènes", "tox_nao_cancerigena", "CTUh/kg"),
    ("Effets toxicologiques sur la santé humaine : substances cancérogènes", "tox_cancerigena", "CTUh/kg"),
    ("Écotoxicité pour écosystèmes aquatiques d'eau douce", "ecotox_agua_doce", "CTUe/kg"),
]

# etapas do ciclo de vida para o CO2e (ficheiro "détail par étape")
ETAPAS = [
    ("Agriculture", "co2_agricultura_kg"),
    ("Transformation", "co2_transformacao_kg"),
    ("Emballage", "co2_embalagem_kg"),
    ("Transport", "co2_transporte_kg"),
    ("Supermarché et distribution", "co2_distribuicao_kg"),
    ("Consommation", "co2_consumo_kg"),
]

PREPARACAO = {
    "Pas de préparation": "Sem preparação",
    "Four": "Forno",
    "Micro-onde": "Micro-ondas",
    "Cuisson à l'eau": "Cozedura em água",
    "Poêle": "Frigideira",
    "Réfrigéré chez le consommateur": "Refrigerado em casa",
}

TEXTO = [
    ("codigo_agb", "VARCHAR(16) NOT NULL PRIMARY KEY"),
    ("codigo_ciqual", "VARCHAR(16)"),
    ("nome_pt", "VARCHAR(255) NOT NULL"),
    ("nome_fr", "VARCHAR(255)"),
    ("nome_en", "VARCHAR(255)"),
    ("grupo_pt", "VARCHAR(120)"),
    ("subgrupo_pt", "VARCHAR(120)"),
    ("preparacao", "VARCHAR(80)"),
    ("transporte_aviao", "TINYINT"),
    ("dqr", "DECIMAL(4,2)"),
]


def ler_csv(nome):
    caminho = os.path.join(AQUI, "original", nome)
    with open(caminho, encoding="utf-8-sig", newline="") as f:
        # alguns nomes de coluna da fonte usam espaço não separável (\xa0)
        return [{k.replace("\xa0", " "): v for k, v in r.items()}
                for r in csv.DictReader(f) if r.get("Code AGB")]


def ler_tsv(nome):
    with open(os.path.join(AQUI, "traducao", nome), encoding="utf-8") as f:
        return list(csv.DictReader(f, delimiter="\t"))


def numero(valor):
    valor = (valor or "").strip()
    return float(valor) if valor else None


def main():
    sintese = ler_csv("agribalyse-3.2-synthese.csv")
    # o ficheiro por etapa escreve alguns códigos com zeros à esquerda ("0001" em vez de "1")
    etapas = {r["Code AGB"].lstrip("0"): r for r in ler_csv("agribalyse-3.2-detail-par-etape.csv")}
    nomes = {r["codigo_agb"]: r["nome_pt"] for r in ler_tsv("nomes.tsv")}
    grupos = {(r["tipo"], r["fr"]): r["pt"] for r in ler_tsv("grupos.tsv")}

    linhas = []
    for r in sintese:
        c = r["Code AGB"]
        e = etapas[c.lstrip("0")]
        linha = {
            "codigo_agb": c,
            "codigo_ciqual": r["Code CIQUAL"],
            "nome_pt": nomes[c],
            "nome_fr": r["Nom du Produit en Français"],
            "nome_en": r["LCI Name"],
            "grupo_pt": grupos[("grupo", r["Groupe d'aliment"])],
            "subgrupo_pt": grupos[("subgrupo", r["Sous-groupe d'aliment"])],
            "preparacao": PREPARACAO[r["Préparation"].strip()],
            "transporte_aviao": int(r["code avion"] or 0),
            "dqr": numero(r["DQR"]),
        }
        for fonte, coluna, _ in INDICADORES:
            linha[coluna] = numero(r[fonte])
        for etapa, coluna in ETAPAS:
            linha[coluna] = numero(e[f"Changement climatique - {etapa}"])
        linha["versao_dados"] = VERSAO_DADOS
        linhas.append(linha)

    linhas.sort(key=lambda x: x["nome_pt"].lower())
    colunas = list(linhas[0].keys())

    with open(os.path.join(AQUI, "alimentos.csv"), "w", encoding="utf-8", newline="") as f:
        w = csv.DictWriter(f, fieldnames=colunas)
        w.writeheader()
        w.writerows(linhas)

    def sql_valor(v):
        if v is None:
            return "NULL"
        if isinstance(v, (int, float)):
            return repr(v)
        return "'" + str(v).replace("\\", "\\\\").replace("'", "''") + "'"

    defs = [f"  `{n}` {t}" for n, t in TEXTO]
    for _, coluna, unidade in INDICADORES:
        defs.append(f"  `{coluna}` DOUBLE COMMENT '{unidade}'")
    for etapa, coluna in ETAPAS:
        defs.append(f"  `{coluna}` DOUBLE COMMENT 'kg CO2 eq/kg, etapa {etapa}'")
    defs.append("  `versao_dados` VARCHAR(40) NOT NULL")

    with open(os.path.join(AQUI, "alimentos.sql"), "w", encoding="utf-8") as f:
        f.write(f"-- Gerado por construir.py a partir de {VERSAO_DADOS} (download {DATA_DOWNLOAD})\n")
        f.write("-- Valores por kg de alimento, tal como publicados pela ADEME. Licença Ouverte / Etalab 2.0.\n\n")
        f.write("DROP TABLE IF EXISTS `agb_alimentos`;\n")
        f.write("CREATE TABLE `agb_alimentos` (\n" + ",\n".join(defs) + "\n) DEFAULT CHARSET=utf8mb4;\n\n")
        for i in range(0, len(linhas), 200):
            bloco = linhas[i:i + 200]
            f.write("INSERT INTO `agb_alimentos` (" + ",".join(f"`{c}`" for c in colunas) + ") VALUES\n")
            f.write(",\n".join("(" + ",".join(sql_valor(l[c]) for c in colunas) + ")" for l in bloco))
            f.write(";\n")

    print(f"{len(linhas)} alimentos escritos em alimentos.csv e alimentos.sql")


if __name__ == "__main__":
    main()
