#!/usr/bin/env python3
"""
classify_gaps.py — Clasifica los huecos de traducción aflorados por el crawler
(#121/#132) en DESCARGAR (bíblico/litúrgico) vs TRADUCIR (comentarios/artículos),
para coordinar con Minimax.

Entrada: report.csv (de analyze.py). Cruza las páginas marcadas SPANISH_LEAK /
LANG_MISMATCH / CROSS_LANG_REDIRECT con las categorías WP del post, vía wp eval.

Salida:
  gaps_traducir.csv   — posts ES a traducir (comentarios/artículos)
  gaps_descargar.csv  — posts bíblicos/litúrgicos (lecturas, evangelios, salmos)
  gaps_dossier.json   — todo, estructurado
"""
import csv, json, subprocess, re, os, sys
from collections import defaultdict

DIR = os.path.dirname(os.path.abspath(__file__))
REPORT = os.path.join(DIR, "report.csv")

# Categorías que se DESCARGAN (texto oficial), no se traducen con LLM.
DESCARGAR_CATS = {
    1645,  # Lecturas bíblicas
    1648,  # Eucaristía (lecturas/salmos litúrgicos)
    28,    # evangelios-y-comentarios (los 4 evangelistas: descarga)
}
# term_id de las categorías que SÍ se traducen
TRADUCIR_CATS = {1646, 1647, 1650, 6}  # editorial, comentarios evangelio, artículos, carta

FLAGS_INTERES = ("SPANISH_LEAK", "LANG_MISMATCH", "HTML_LANG_MISMATCH", "CROSS_LANG_REDIRECT")


def slug_from_url(url):
    path = re.sub(r"https?://[^/]+", "", url).strip("/")
    parts = [p for p in path.split("/") if p]
    if parts and parts[0] in ("en", "fr", "it", "pt", "es"):
        parts = parts[1:]
    # saltar prefijos no-post
    if parts and parts[0] in ("category", "tag", "author", "page"):
        return None
    return parts[-1] if parts else None


def wp_resolve(slugs):
    """Devuelve {slug: {id, lang, cats:[ids], title, es_id}} vía wp eval."""
    if not slugs:
        return {}
    payload = json.dumps(list(slugs))
    php = r'''
$slugs=json_decode(file_get_contents("php://stdin"),true);
$out=[];
foreach($slugs as $s){
  $p=get_posts(["name"=>$s,"post_type"=>"post","post_status"=>["publish","draft"],"numberposts"=>1,"suppress_filters"=>true]);
  if(!$p){$out[$s]=null;continue;}
  $id=$p[0]->ID;
  $lang=function_exists("pll_get_post_language")?pll_get_post_language($id):"";
  $es=$id;
  if($lang!=="es"&&function_exists("pll_get_post")){$t=pll_get_post($id,"es");if($t)$es=$t;}
  $out[$s]=["id"=>$id,"lang"=>$lang,"cats"=>wp_get_post_categories($id),"title"=>get_the_title($id),"es_id"=>$es,
            "es_cats"=>wp_get_post_categories($es),"es_title"=>get_the_title($es)];
}
echo json_encode($out);
'''
    r = subprocess.run(
        ["docker", "exec", "-i", "wordpress-web", "wp", "eval", php, "--allow-root"],
        input=payload, capture_output=True, text=True)
    try:
        return json.loads(r.stdout.strip().splitlines()[-1])
    except Exception as e:
        print("wp_resolve error:", e, r.stdout[:300], r.stderr[:300], file=sys.stderr)
        return {}


def main():
    if not os.path.exists(REPORT):
        print("Falta report.csv — ejecuta analyze.py primero", file=sys.stderr)
        return 1
    rows = list(csv.DictReader(open(REPORT, encoding="utf-8")))
    flagged = [r for r in rows if any(f in (r.get("flags") or "") for f in FLAGS_INTERES)]
    print(f"Páginas marcadas: {len(flagged)} / {len(rows)}")

    slugs = {}
    for r in flagged:
        s = slug_from_url(r.get("url", ""))
        if s:
            slugs.setdefault(s, r)

    meta = wp_resolve(set(slugs))

    traducir, descargar, otros = [], [], []
    for s, r in slugs.items():
        m = meta.get(s)
        if not m:
            otros.append({"slug": s, "url": r["url"], "flags": r.get("flags"), "motivo": "no resuelve post"})
            continue
        cats = set(m.get("es_cats") or m.get("cats") or [])
        row = {"slug": s, "lang": r.get("lang"), "flags": r.get("flags"),
               "es_id": m["es_id"], "es_title": m.get("es_title"), "cats": sorted(cats), "url": r["url"]}
        if cats & DESCARGAR_CATS:
            descargar.append(row)
        elif cats & TRADUCIR_CATS:
            traducir.append(row)
        else:
            otros.append(row)

    # dedup por es_id para traducir (lo que va a Minimax)
    by_es = {}
    for t in traducir:
        by_es.setdefault(t["es_id"], t)

    def write_csv(path, rows, cols):
        with open(path, "w", newline="", encoding="utf-8") as f:
            w = csv.DictWriter(f, fieldnames=cols, extrasaction="ignore")
            w.writeheader()
            w.writerows(rows)

    write_csv(os.path.join(DIR, "gaps_traducir.csv"), list(by_es.values()),
              ["es_id", "es_title", "lang", "cats", "flags", "url"])
    write_csv(os.path.join(DIR, "gaps_descargar.csv"), descargar,
              ["es_id", "es_title", "lang", "cats", "flags", "url"])
    json.dump({"traducir": list(by_es.values()), "descargar": descargar, "otros": otros},
              open(os.path.join(DIR, "gaps_dossier.json"), "w"), ensure_ascii=False, indent=2)

    print(f"\nTRADUCIR (Minimax): {len(by_es)} posts ES únicos")
    print(f"DESCARGAR (bíblico/litúrgico): {len(descargar)} páginas")
    print(f"OTROS (revisar a mano): {len(otros)}")
    print("\nIDs ES a traducir:", ",".join(str(i) for i in by_es))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
