<?php
/**
 * translate_lectura_titles.php  (issue Gitea #140)
 *
 * Traduce SOLO el nombre del libro bíblico en el INICIO del post_title de los
 * posts no-ES (EN/FR/IT/PT) cuyo título es una cita bíblica «<LIBRO> <num>, ...».
 * El cuerpo ya está traducido; esto es title-only.
 *
 * - Determinista: mapa fijo de libros ES -> {en,fr,it,pt}.
 * - Idempotente: si el token inicial ya está en el idioma destino, no toca nada.
 * - Seguro: exige número tras el libro (excluye «Juan Pablo II», «Domingo 30...»,
 *   etc. — DOMINGO/SEMANA no son libros, no están en el mapa).
 * - Cotejo insensible a acentos (fold a ASCII-mayúsculas) para casar variantes;
 *   el valor canónico por idioma garantiza que ES==destino sea un no-op.
 *
 * Uso (local):  docker exec wordpress-web php /var/www/html/scripts/...  (o vía cwd)
 *   php scripts/translate_lectura_titles.php            # dry-run + reporte
 *   APPLY=1 php scripts/translate_lectura_titles.php    # aplica
 * Prod:  FEA_WP_LOAD=/web/wp-load.php php translate_lectura_titles.php
 */

error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE);

$WP_LOAD = getenv('FEA_WP_LOAD') ?: '/var/www/html/wp-load.php';
if (!file_exists($WP_LOAD)) {
    fwrite(STDERR, "No encuentro wp-load.php en $WP_LOAD\n");
    exit(1);
}
define('WP_USE_THEMES', false);
require $WP_LOAD;

global $wpdb;
$APPLY  = getenv('APPLY') === '1';
$LANGS  = ['en', 'fr', 'it', 'pt'];

/*
 * Mapa de libros: clave en español (display) => [en, fr, it, pt] (Title case canónico).
 * El cotejo es accent-insensitive; los valores destino son los litúrgicos católicos.
 */
$BOOKS = [
    // --- Antiguo Testamento ---
    'Génesis'        => ['Genesis', 'Genèse', 'Genesi', 'Gênesis'],
    'Éxodo'          => ['Exodus', 'Exode', 'Esodo', 'Êxodo'],
    'Levítico'       => ['Leviticus', 'Lévitique', 'Levitico', 'Levítico'],
    'Números'        => ['Numbers', 'Nombres', 'Numeri', 'Números'],
    'Deuteronomio'   => ['Deuteronomy', 'Deutéronome', 'Deuteronomio', 'Deuteronômio'],
    'Josué'          => ['Joshua', 'Josué', 'Giosuè', 'Josué'],
    'Jueces'         => ['Judges', 'Juges', 'Giudici', 'Juízes'],
    'Rut'            => ['Ruth', 'Ruth', 'Rut', 'Rute'],
    'Samuel'         => ['Samuel', 'Samuel', 'Samuele', 'Samuel'],
    'Reyes'          => ['Kings', 'Rois', 'Re', 'Reis'],
    'Crónicas'       => ['Chronicles', 'Chroniques', 'Cronache', 'Crônicas'],
    'Esdras'         => ['Ezra', 'Esdras', 'Esdra', 'Esdras'],
    'Nehemías'       => ['Nehemiah', 'Néhémie', 'Neemia', 'Neemias'],
    'Tobías'         => ['Tobit', 'Tobie', 'Tobia', 'Tobias'],
    'Judit'          => ['Judith', 'Judith', 'Giuditta', 'Judite'],
    'Ester'          => ['Esther', 'Esther', 'Ester', 'Ester'],
    'Macabeos'       => ['Maccabees', 'Maccabées', 'Maccabei', 'Macabeus'],
    'Job'            => ['Job', 'Job', 'Giobbe', 'Jó'],
    'Salmos'         => ['Psalms', 'Psaumes', 'Salmi', 'Salmos'],
    'Salmo'          => ['Psalm', 'Psaume', 'Salmo', 'Salmo'],
    'Proverbios'     => ['Proverbs', 'Proverbes', 'Proverbi', 'Provérbios'],
    'Eclesiastés'    => ['Ecclesiastes', 'Ecclésiaste', 'Ecclesiaste', 'Eclesiastes'],
    'Eclesiástico'   => ['Ecclesiasticus', 'Siracide', 'Siracide', 'Eclesiástico'],
    'Sabiduría'      => ['Wisdom', 'Sagesse', 'Sapienza', 'Sabedoria'],
    'Isaías'         => ['Isaiah', 'Isaïe', 'Isaia', 'Isaías'],
    'Jeremías'       => ['Jeremiah', 'Jérémie', 'Geremia', 'Jeremias'],
    'Lamentaciones'  => ['Lamentations', 'Lamentations', 'Lamentazioni', 'Lamentações'],
    'Baruc'          => ['Baruch', 'Baruch', 'Baruc', 'Baruc'],
    'Ezequiel'       => ['Ezekiel', 'Ézéchiel', 'Ezechiele', 'Ezequiel'],
    'Daniel'         => ['Daniel', 'Daniel', 'Daniele', 'Daniel'],
    'Oseas'          => ['Hosea', 'Osée', 'Osea', 'Oseias'],
    'Joel'           => ['Joel', 'Joël', 'Gioele', 'Joel'],
    'Amós'           => ['Amos', 'Amos', 'Amos', 'Amós'],
    'Abdías'         => ['Obadiah', 'Abdias', 'Abdia', 'Abdias'],
    'Jonás'          => ['Jonah', 'Jonas', 'Giona', 'Jonas'],
    'Miqueas'        => ['Micah', 'Michée', 'Michea', 'Miqueias'],
    'Nahúm'          => ['Nahum', 'Nahum', 'Naum', 'Naum'],
    'Habacuc'        => ['Habakkuk', 'Habacuc', 'Abacuc', 'Habacuc'],
    'Sofonías'       => ['Zephaniah', 'Sophonie', 'Sofonia', 'Sofonias'],
    'Ageo'           => ['Haggai', 'Aggée', 'Aggeo', 'Ageu'],
    'Zacarías'       => ['Zechariah', 'Zacharie', 'Zaccaria', 'Zacarias'],
    'Malaquías'      => ['Malachi', 'Malachie', 'Malachia', 'Malaquias'],
    // --- Nuevo Testamento ---
    'Mateo'          => ['Matthew', 'Matthieu', 'Matteo', 'Mateus'],
    'Marcos'         => ['Mark', 'Marc', 'Marco', 'Marcos'],
    'Lucas'          => ['Luke', 'Luc', 'Luca', 'Lucas'],
    'Juan'           => ['John', 'Jean', 'Giovanni', 'João'],
    'Hechos'         => ['Acts', 'Actes', 'Atti', 'Atos'],
    'Romanos'        => ['Romans', 'Romains', 'Romani', 'Romanos'],
    'Corintios'      => ['Corinthians', 'Corinthiens', 'Corinzi', 'Coríntios'],
    'Gálatas'        => ['Galatians', 'Galates', 'Galati', 'Gálatas'],
    'Efesios'        => ['Ephesians', 'Éphésiens', 'Efesini', 'Efésios'],
    'Filipenses'     => ['Philippians', 'Philippiens', 'Filippesi', 'Filipenses'],
    'Colosenses'     => ['Colossians', 'Colossiens', 'Colossesi', 'Colossenses'],
    'Tesalonicenses' => ['Thessalonians', 'Thessaloniciens', 'Tessalonicesi', 'Tessalonicenses'],
    'Timoteo'        => ['Timothy', 'Timothée', 'Timoteo', 'Timóteo'],
    'Tito'           => ['Titus', 'Tite', 'Tito', 'Tito'],
    'Filemón'        => ['Philemon', 'Philémon', 'Filemone', 'Filêmon'],
    'Hebreos'        => ['Hebrews', 'Hébreux', 'Ebrei', 'Hebreus'],
    'Santiago'       => ['James', 'Jacques', 'Giacomo', 'Tiago'],
    'Pedro'          => ['Peter', 'Pierre', 'Pietro', 'Pedro'],
    'Judas'          => ['Jude', 'Jude', 'Giuda', 'Judas'],
    'Apocalipsis'    => ['Revelation', 'Apocalypse', 'Apocalisse', 'Apocalipse'],
];

// fold a ASCII-mayúsculas (quita acentos) para cotejo robusto
function fold($s) {
    $s = trim($s);
    $map = ['Á'=>'A','À'=>'A','Ä'=>'A','Â'=>'A','Ã'=>'A','É'=>'E','È'=>'E','Ë'=>'E','Ê'=>'E',
            'Í'=>'I','Ì'=>'I','Ï'=>'I','Î'=>'I','Ó'=>'O','Ò'=>'O','Ö'=>'O','Ô'=>'O','Õ'=>'O',
            'Ú'=>'U','Ù'=>'U','Ü'=>'U','Û'=>'U','Ñ'=>'N','Ç'=>'C'];
    $s = mb_strtoupper($s, 'UTF-8');
    return strtr($s, $map);
}

$langIdx = array_flip($LANGS); // en=>0,...
// índice de búsqueda: foldedSpanish => [en,fr,it,pt]
$LOOKUP = [];
foreach ($BOOKS as $es => $tr) {
    $LOOKUP[fold($es)] = $tr;
}

// Todos los posts no-ES (filtramos/transformamos en PHP, regex /u fiable).
$placeholders = implode(',', array_fill(0, count($LANGS), '%s'));
$sql = $wpdb->prepare(
    "SELECT p.ID, t.slug AS lang, p.post_title
       FROM {$wpdb->posts} p
       JOIN {$wpdb->term_relationships} tr ON tr.object_id = p.ID
       JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy='language'
       JOIN {$wpdb->terms} t ON t.term_id = tt.term_id
      WHERE p.post_type='post'
        AND p.post_status IN ('publish','draft','future','pending','private')
        AND t.slug IN ($placeholders)",
    $LANGS
);
$rows = $wpdb->get_results($sql);

$changes = [];   // [ID => [lang, old, new]]
$per_lang = array_fill_keys($LANGS, 0);
$skipped_already = 0;
$candidates = 0;  // títulos con al menos una cita bíblica detectada

/*
 * Traduce CADA token de libro de una cita bíblica dentro del título:
 *   - una palabra (letras) NO precedida por letra/número
 *   - seguida de «<espacios><dígito>» (el capítulo de la cita).
 * Cubre el inicio, los compuestos «1ª lectura / 2ª lectura / evangelio» (tras «/»),
 * el ordinal previo («2 Timoteo 4») y prefijos de fiesta («Epifanía - Isaías 60»).
 * Como SOLO casa ortografías españolas (las del mapa), en posts no-ES únicamente
 * toca citas heredadas del ES; las descripciones van en el idioma destino.
 */
$BOOK_RE = '/(?<![\p{L}\p{N}])(\p{L}[\p{L}.]*)(?=\s+\d)/u';

foreach ($rows as $r) {
    $lang = $r->lang;
    $li   = $langIdx[$lang];
    $hit  = false;
    $new_title = preg_replace_callback($BOOK_RE, function ($m) use ($LOOKUP, $li, &$hit) {
        $book = $m[1];
        $key  = fold($book);
        if (!isset($LOOKUP[$key])) {
            return $m[0]; // no es libro conocido -> intacto
        }
        $hit = true;
        $canon   = $LOOKUP[$key][$li];
        $isUpper = (mb_strtoupper($book, 'UTF-8') === $book);
        return $isUpper ? mb_strtoupper($canon, 'UTF-8') : $canon;
    }, $r->post_title);

    if (!$hit) { continue; }
    $candidates++;
    if ($new_title === $r->post_title) { $skipped_already++; continue; } // idempotente

    $changes[$r->ID] = [$lang, $r->post_title, $new_title];
    $per_lang[$lang]++;
}

// --- Reporte ---
echo "== translate_lectura_titles.php (issue #140) ==\n";
echo "WP_LOAD: $WP_LOAD\n";
echo "Posts no-ES escaneados: " . count($rows) . "\n";
echo "  - con cita bíblica detectada: $candidates\n";
echo "  - ya en idioma destino (idempotente): $skipped_already\n";
echo "  - A CAMBIAR: " . count($changes) . "\n";
echo "    por idioma: ";
foreach ($LANGS as $l) echo strtoupper($l) . "=" . $per_lang[$l] . "  ";
echo "\n\n";

$SAMPLE = (int)(getenv('SAMPLE') ?: 8);
foreach ($LANGS as $l) {
    $shown = 0;
    echo "--- muestra $l ---\n";
    foreach ($changes as $id => $c) {
        if ($c[0] !== $l) continue;
        echo sprintf("  %d  «%s»  ->  «%s»\n", $id, $c[1], $c[2]);
        if ($SAMPLE > 0 && ++$shown >= $SAMPLE) break;
    }
}
echo "\n";

if (!$APPLY) {
    echo "DRY-RUN (no se ha tocado nada). Ejecuta con APPLY=1 para aplicar.\n";
    exit(0);
}

// --- Aplica (title-only, sin tocar slug/cuerpo) ---
$done = 0;
foreach ($changes as $id => $c) {
    $ok = $wpdb->update($wpdb->posts, ['post_title' => $c[2]], ['ID' => $id], ['%s'], ['%d']);
    if ($ok !== false) {
        clean_post_cache($id);
        $done++;
    } else {
        fwrite(STDERR, "ERROR al actualizar ID $id\n");
    }
}
echo "APLICADOS: $done de " . count($changes) . "\n";
