<?php
/**
 * Fix local.php v2.0 - aplicar.php
 * ==================================
 * Dos modos:
 * 1. "groq_only"  -> Solo actualiza groq_api_key en todos los wikis
 * 2. "full"       -> Regenera local.php completo manteniendo datos unicos
 *
 * v2.0: Sin pantalla de login. Error handler global.
 */

// Error handler global - NUNCA pagina en blanco
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');

$_IS_AJAX = (isset($_GET['action']) || isset($_POST['action']));

set_exception_handler(function($e) {
    global $_IS_AJAX;
    if ($_IS_AJAX) {
        if (!headers_sent()) { header('Content-Type: application/json; charset=utf-8'); http_response_code(500); }
        echo json_encode(['status' => 'error', 'error' => 'Excepcion: ' . $e->getMessage()]);
    } else {
        if (!headers_sent()) header('Content-Type: text/html; charset=utf-8');
        echo '<div style="background:#c62828;color:white;padding:20px;font-family:monospace;border-radius:8px;margin:40px auto;max-width:800px">';
        echo '<h2>Error Fatal</h2><pre>' . htmlspecialchars($e->getMessage() . "\n" . $e->getTraceAsString()) . '</pre></div>';
    }
    exit(1);
});

set_error_handler(function($severity, $msg, $file, $line) {
    if (!(error_reporting() & $severity)) return false;
    throw new \ErrorException($msg, 0, $severity, $file, $line);
});

register_shutdown_function(function() {
    global $_IS_AJAX;
    $err = error_get_last();
    if ($err && in_array($err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        if ($_IS_AJAX) {
            if (!headers_sent()) { header('Content-Type: application/json; charset=utf-8'); http_response_code(500); }
            echo json_encode(['status' => 'error', 'error' => 'Fatal: ' . $err['message']]);
        } else {
            if (!headers_sent()) header('Content-Type: text/html; charset=utf-8');
            echo '<div style="background:#c62828;color:white;padding:20px;font-family:monospace">';
            echo '<h2>Error Fatal PHP</h2><pre>' . htmlspecialchars($err['message'] . ' en ' . basename($err['file']) . ':' . $err['line']) . '</pre></div>';
        }
    }
});

require_once __DIR__ . '/config.php';

@set_time_limit(MAX_EXECUTION_TIME);
@ini_set('memory_limit', MEMORY_LIMIT);

// ============================================================
// FUNCIONES UTILITARIAS
// ============================================================

function isDokuWiki($path) {
    return file_exists($path . '/doku.php')
        && (file_exists($path . '/conf/local.php') || file_exists($path . '/conf/dokuwiki.php'))
        && is_dir($path . '/data');
}

function scanWikis() {
    $sites = [];
    if (!is_dir(SEARCH_PATH)) return $sites;
    $items = @scandir(SEARCH_PATH);
    if (!$items) return $sites;
    foreach ($items as $item) {
        if ($item[0] === '.' || $item[0] === '_') continue;
        $full = SEARCH_PATH . '/' . $item;
        if (is_dir($full) && isDokuWiki($full)) {
            $sites[] = ['name' => $item, 'path' => $full];
        }
    }
    usort($sites, function($a, $b) { return strcasecmp($a['name'], $b['name']); });
    return $sites;
}

function _log($msg) {
    if (!is_dir(LOG_DIR)) @mkdir(LOG_DIR, 0755, true);
    $file = LOG_DIR . '/fix_localphp_' . date('Y-m-d') . '.log';
    @file_put_contents($file, date('H:i:s') . ' ' . $msg . "\n", FILE_APPEND);
}

/**
 * Lee valores preservables del local.php actual
 */
function readPreservedValues($localPhpPath) {
    $preserved = [
        'title'          => '',
        'baseurl'        => '',
        'notify'         => '',
        'registernotify' => '',
        'mailfrom'       => '',
        'mailreturnpath'  => '',
        'token_ia'       => '',
    ];
    if (!file_exists($localPhpPath)) return $preserved;

    $content = file_get_contents($localPhpPath);
    foreach (array_keys($preserved) as $key) {
        // Match $conf['key'] = 'value'; o $conf['key'] = "value";
        if (preg_match("/\\$" . "conf\\['" . preg_quote($key, '/') . "'\\]\\s*=\\s*['\"](.+?)['\"]/", $content, $m)) {
            $preserved[$key] = $m[1];
        }
    }
    return $preserved;
}

/**
 * Genera el contenido completo del local.php
 */
function generateLocalPhp($wikiName, $preserved, $groqKey) {
    global $FIXED_CONF;

    $date = date('Y-m-d H:i:s');
    $basedir = '/' . $wikiName . '/';
    $baseurl = $preserved['baseurl'] ?: 'https://' . $wikiName . '.sistemavirtualdegestion.com/';
    $title   = $preserved['title'] ?: strtoupper($wikiName) . ' - SGC';

    $out = "<?php\n";
    $out .= "/*\n";
    $out .= " *  Main Configuration SIE ASESORIAS - VERSION 2\n";
    $out .= " * Auto-generated by siedeployer fix_localphp\n";
    $out .= " * Date: {$date}\n";
    $out .= " */\n";
    $out .= "date_default_timezone_set('America/Bogota');\n\n";

    // Datos unicos del wiki
    $out .= "\$conf['title'] = " . var_export($title, true) . ";\n";
    $out .= "\$conf['start'] = " . var_export($FIXED_CONF['start'], true) . ";\n";
    $out .= "\$conf['lang'] = " . var_export($FIXED_CONF['lang'], true) . ";\n";
    $out .= "\$conf['template'] = " . var_export($FIXED_CONF['template'], true) . ";\n";
    $out .= "\$conf['sidebar'] = " . var_export($FIXED_CONF['sidebar'], true) . ";\n";
    $out .= "\$conf['license'] = " . var_export($FIXED_CONF['license'], true) . ";\n";
    $out .= "\$conf['basedir'] = " . var_export($basedir, true) . ";\n";
    $out .= "\$conf['baseurl'] = " . var_export($baseurl, true) . ";\n";
    $out .= "\$conf['useheading'] = " . var_export($FIXED_CONF['useheading'], true) . ";\n";
    $out .= "\$conf['useacl'] = " . var_export($FIXED_CONF['useacl'], true) . ";\n";
    $out .= "\$conf['passcrypt'] = " . var_export($FIXED_CONF['passcrypt'], true) . ";\n";
    $out .= "\$conf['defaultgroup'] = " . var_export($FIXED_CONF['defaultgroup'], true) . ";\n";
    $out .= "\$conf['superuser'] = " . var_export($FIXED_CONF['superuser'], true) . ";\n";
    $out .= "\$conf['manager'] = " . var_export($FIXED_CONF['manager'], true) . ";\n";
    $out .= "\$conf['disableactions'] = " . var_export($FIXED_CONF['disableactions'], true) . ";\n";
    $out .= "\$conf['subscribers'] = " . var_export($FIXED_CONF['subscribers'], true) . ";\n";

    // Correos (preservados)
    $notify = $preserved['notify'] ?: 'proyect@sieasesorias.com';
    $rnotify = $preserved['registernotify'] ?: $notify;
    $mailfrom = $preserved['mailfrom'] ?: $notify;
    $mailreturn = $preserved['mailreturnpath'] ?: $notify;
    $out .= "\$conf['notify'] = " . var_export($notify, true) . ";\n";
    $out .= "\$conf['registernotify'] = " . var_export($rnotify, true) . ";\n";
    $out .= "\$conf['mailfrom'] = " . var_export($mailfrom, true) . ";\n";
    $out .= "\$conf['mailreturnpath'] = " . var_export($mailreturn, true) . ";\n";
    $out .= "\$conf['mailprefix'] = " . var_export($FIXED_CONF['mailprefix'], true) . ";\n";
    $out .= "\$conf['dontlog'] = " . var_export($FIXED_CONF['dontlog'], true) . ";\n";
    $out .= "\$conf['updatecheck'] = " . var_export($FIXED_CONF['updatecheck'], true) . ";\n";
    $out .= "\$conf['defer_js'] = " . var_export($FIXED_CONF['defer_js'], true) . ";\n";
    $out .= "\$conf['hidewarnings'] = " . var_export($FIXED_CONF['hidewarnings'], true) . ";\n";

    // Proxy
    $out .= "\$conf['proxy']['user'] = 'manager';\n\n";

    // Plugins
    $out .= "// Plugins\n";
    $out .= "\$conf['plugin']['authldap']['attributes'] = array();\n";
    $out .= "\$conf['plugin']['authldap']['groupscope'] = 'one';\n";
    $out .= "\$conf['plugin']['authorlist']['heading'] = 'Autores';\n";
    $out .= "\$conf['plugin']['authorlist']['intro'] = '<p><b>Autores:</b></p>';\n";
    $out .= "\$conf['plugin']['authorlist']['creatortext'] = '<p>Creado por <i>%CREATOR%</i> on %DATE%.</p>';\n";
    $out .= "\$conf['plugin']['ckgedit']['open_upload'] = 1;\n";
    $out .= "\$conf['plugin']['ckgedit']['allow_ckg_filebrowser'] = 'dokuwiki';\n";
    $out .= "\$conf['plugin']['ckgedit']['default_ckg_filebrowser'] = 'dokuwiki';\n";
    $out .= "\$conf['plugin']['ckgedit']['scayt_lang'] = 'Spanish/es_ES';\n";
    $out .= "\$conf['plugin']['ckgedit']['style_sheet'] = 1;\n";
    $out .= "\$conf['plugin']['dropfiles']['insertFileLink'] = 1;\n";
    $out .= "\$conf['plugin']['include']['order'] = 'title';\n";
    $out .= "\$conf['plugin']['indexmenu']['aclcache'] = 'none';\n";
    $out .= "\$conf['plugin']['pagetitle']['usePersistent'] = 1;\n";
    $out .= "\$conf['plugin']['publish']['hide_approved_banner'] = 1;\n";
    $out .= "\$conf['plugin']['publish']['apr_approved_text'] = 'Aprobado';\n";
    $out .= "\$conf['plugin']['tag']['toolbar_icon'] = 1;\n";
    $out .= "\$conf['plugin']['tag']['list_tags_of_subns'] = 1;\n";
    $out .= "\$conf['plugin']['templatepagename']['current_pagename_tpl'] = '_template';\n";
    $out .= "\$conf['plugin']['templatepagename']['inherited_pagename_tpl'] = '_template2';\n";
    $out .= "\$conf['plugin']['versionswitch']['regexes'] = '|{{tag>VERSION';\n\n";

    // Token IA (preservado)
    $tokenIa = $preserved['token_ia'] ?: '';
    $out .= "// Token IA\n";
    $out .= "\$conf['token_ia'] = " . var_export($tokenIa, true) . ";\n\n";

    // SIE-IA Engine
    $out .= "// SIE-IA Engine\n";
    $out .= "\$conf['groq_api_key'] = " . var_export($groqKey, true) . ";\n";
    $out .= "\$conf['groq_model'] = " . var_export(DEFAULT_GROQ_MODEL, true) . ";\n";
    $out .= "\$conf['ia_tope_mes'] = " . var_export(DEFAULT_IA_TOPE_MES, true) . ";\n\n";

    // Bez plugin
    $out .= "// Bez plugin\n";
    $out .= "\$conf['plugin']['bez']['admin_group'] = 'director';\n\n";

    // Wasabi S3 Sync
    $out .= "// Wasabi S3 Sync\n";
    $out .= "\$conf['plugin']['wasabisync']['enabled'] = 1;\n";
    $out .= "\$conf['plugin']['wasabisync']['wasabi_key'] = " . var_export(WASABI_KEY, true) . ";\n";
    $out .= "\$conf['plugin']['wasabisync']['wasabi_secret'] = " . var_export(WASABI_SECRET, true) . ";\n";
    $out .= "\$conf['plugin']['wasabisync']['wasabi_bucket'] = " . var_export(WASABI_BUCKET, true) . ";\n";
    $out .= "\$conf['plugin']['wasabisync']['wasabi_region'] = " . var_export(WASABI_REGION, true) . ";\n";
    $out .= "\$conf['plugin']['wasabisync']['wasabi_endpoint'] = " . var_export(WASABI_ENDPOINT, true) . ";\n";
    $out .= "\$conf['plugin']['wasabisync']['url_expiry'] = " . var_export(WASABI_EXPIRY, true) . ";\n";
    $out .= "\$conf['plugin']['wasabisync']['admin_password'] = " . var_export(WASABI_ADMIN_PWD, true) . ";\n";

    return $out;
}

/**
 * Modo: Solo actualizar groq_api_key
 */
function updateGroqKeyOnly($wikiPath, $groqKey) {
    $localPhp = $wikiPath . '/conf/local.php';
    if (!file_exists($localPhp)) return ['ok' => false, 'error' => 'local.php no existe'];

    $content = file_get_contents($localPhp);
    $original = $content;

    // Reemplazar groq_api_key existente
    if (preg_match("/\\$" . "conf\\['groq_api_key'\\]/", $content)) {
        $content = preg_replace(
            "/(\\$" . "conf\\['groq_api_key'\\]\\s*=\\s*)['\"].*?['\"]/",
            "$1'" . addslashes($groqKey) . "'",
            $content
        );
    } else {
        // No existe, agregar al final
        $content = rtrim($content) . "\n\$conf['groq_api_key'] = '" . addslashes($groqKey) . "';\n";
    }

    // Tambien actualizar model y tope si no existen
    if (!preg_match("/\\$" . "conf\\['groq_model'\\]/", $content)) {
        $content = rtrim($content) . "\n\$conf['groq_model'] = '" . DEFAULT_GROQ_MODEL . "';\n";
    }
    if (!preg_match("/\\$" . "conf\\['ia_tope_mes'\\]/", $content)) {
        $content = rtrim($content) . "\n\$conf['ia_tope_mes'] = " . DEFAULT_IA_TOPE_MES . ";\n";
    }

    if ($content !== $original) {
        file_put_contents($localPhp, $content);
        return ['ok' => true, 'changed' => true];
    }
    return ['ok' => true, 'changed' => false];
}

/**
 * Modo: Regenerar local.php completo
 */
function regenerateFullLocalPhp($wikiName, $wikiPath, $groqKey) {
    $localPhp = $wikiPath . '/conf/local.php';

    // Leer valores a preservar
    $preserved = readPreservedValues($localPhp);

    // Backup
    $backupPath = $localPhp . '.bak_' . date('Ymd_His');
    if (file_exists($localPhp)) {
        copy($localPhp, $backupPath);
    }

    // Generar nuevo contenido
    $newContent = generateLocalPhp($wikiName, $preserved, $groqKey);

    // Escribir
    file_put_contents($localPhp, $newContent);

    return ['ok' => true, 'backup' => basename($backupPath)];
}

// ============================================================
// MANEJO DE PETICIONES AJAX Y UI
// ============================================================

$action = isset($_POST['action']) ? $_POST['action'] : (isset($_GET['action']) ? $_GET['action'] : '');

// ============================================================
// ACCIONES AJAX (sin autenticacion - protegido por DokuWiki admin)
// ============================================================
if ($action === 'scan') {
    header('Content-Type: application/json; charset=utf-8');
    $wikis = scanWikis();
    echo json_encode(['status' => 'ok', 'total' => count($wikis), 'wikis' => $wikis]);
    exit;
}

if ($action === 'apply_groq') {
    header('Content-Type: application/json; charset=utf-8');
    $groqKey = isset($_POST['groq_key']) ? trim($_POST['groq_key']) : DEFAULT_GROQ_KEY;
    $wikiName = isset($_POST['wiki']) ? trim($_POST['wiki']) : '';
    $wikiPath = SEARCH_PATH . '/' . $wikiName;

    if (!$wikiName || !isDokuWiki($wikiPath)) {
        echo json_encode(['status' => 'error', 'error' => 'Wiki no valido: ' . $wikiName]);
        exit;
    }

    $result = updateGroqKeyOnly($wikiPath, $groqKey);
    _log("GROQ_KEY: {$wikiName} -> " . ($result['ok'] ? 'OK' : 'ERROR: ' . ($result['error'] ?? '')));
    echo json_encode(['status' => $result['ok'] ? 'ok' : 'error', 'wiki' => $wikiName, 'result' => $result]);
    exit;
}

if ($action === 'apply_full') {
    header('Content-Type: application/json; charset=utf-8');
    $groqKey = isset($_POST['groq_key']) ? trim($_POST['groq_key']) : DEFAULT_GROQ_KEY;
    $wikiName = isset($_POST['wiki']) ? trim($_POST['wiki']) : '';
    $wikiPath = SEARCH_PATH . '/' . $wikiName;

    if (!$wikiName || !isDokuWiki($wikiPath)) {
        echo json_encode(['status' => 'error', 'error' => 'Wiki no valido: ' . $wikiName]);
        exit;
    }

    $result = regenerateFullLocalPhp($wikiName, $wikiPath, $groqKey);
    _log("FULL: {$wikiName} -> " . ($result['ok'] ? 'OK (backup: ' . $result['backup'] . ')' : 'ERROR'));
    echo json_encode(['status' => $result['ok'] ? 'ok' : 'error', 'wiki' => $wikiName, 'result' => $result]);
    exit;
}

if ($action === 'preview') {
    header('Content-Type: application/json; charset=utf-8');
    $groqKey = isset($_POST['groq_key']) ? trim($_POST['groq_key']) : DEFAULT_GROQ_KEY;
    $wikiName = isset($_POST['wiki']) ? trim($_POST['wiki']) : 'ejemplo';
    $wikiPath = SEARCH_PATH . '/' . $wikiName;

    $preserved = file_exists($wikiPath . '/conf/local.php')
        ? readPreservedValues($wikiPath . '/conf/local.php')
        : ['title' => strtoupper($wikiName) . ' - SGC', 'baseurl' => '', 'notify' => '', 'registernotify' => '', 'mailfrom' => '', 'mailreturnpath' => '', 'token_ia' => ''];

    $content = generateLocalPhp($wikiName, $preserved, $groqKey);
    echo json_encode(['status' => 'ok', 'content' => $content]);
    exit;
}

// ============================================================
// INTERFAZ HTML
// ============================================================
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fix local.php - SIE Deployer</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', sans-serif; background: #0a0e27; color: #e0e0e0; min-height: 100vh; padding: 20px; }
        h1 { color: #00e5ff; margin-bottom: 5px; }
        h2 { color: #ffd740; margin: 20px 0 10px; }
        .subtitle { color: #90a4ae; margin-bottom: 20px; }
        .card { background: #1a1e3a; border-radius: 12px; padding: 20px; margin-bottom: 20px; border: 1px solid #2a2e4a; }
        .info-bar { background: #1a237e; padding: 12px 18px; border-radius: 8px; color: #82b1ff; margin-bottom: 15px; font-family: monospace; font-size: 13px; }
        label { display: block; color: #b0bec5; margin-bottom: 5px; font-weight: bold; }
        input[type="text"], input[type="password"] { width: 100%; padding: 10px 14px; border: 1px solid #37474f; border-radius: 6px; background: #263238; color: #e0f7fa; font-family: monospace; font-size: 14px; margin-bottom: 15px; }
        input:focus { border-color: #00e5ff; outline: none; }
        .btn { padding: 12px 24px; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: bold; margin-right: 10px; margin-bottom: 10px; transition: all 0.2s; }
        .btn-primary { background: #1565c0; color: white; }
        .btn-primary:hover { background: #1976d2; }
        .btn-warning { background: #f57f17; color: white; }
        .btn-warning:hover { background: #ff8f00; }
        .btn-success { background: #2e7d32; color: white; }
        .btn-success:hover { background: #388e3c; }
        .btn-danger { background: #c62828; color: white; }
        .btn-danger:hover { background: #d32f2f; }
        .btn:disabled { opacity: 0.5; cursor: not-allowed; }
        .progress-bar { width: 100%; height: 30px; background: #1a1e3a; border-radius: 15px; overflow: hidden; margin: 15px 0; border: 1px solid #2a2e4a; }
        .progress-fill { height: 100%; background: linear-gradient(90deg, #00c853, #00e676); transition: width 0.3s; display: flex; align-items: center; justify-content: center; color: #000; font-weight: bold; font-size: 13px; }
        .stats { display: flex; gap: 20px; flex-wrap: wrap; margin: 15px 0; }
        .stat { background: #1a1e3a; border: 1px solid #2a2e4a; border-radius: 10px; padding: 15px 25px; text-align: center; min-width: 120px; }
        .stat .num { font-size: 28px; font-weight: bold; color: #00e5ff; }
        .stat .lbl { font-size: 12px; color: #78909c; margin-top: 4px; }
        #log { background: #0d1117; border: 1px solid #21262d; border-radius: 8px; padding: 12px; max-height: 300px; overflow-y: auto; font-family: monospace; font-size: 12px; line-height: 1.6; white-space: pre-wrap; }
        .log-ok { color: #4caf50; }
        .log-err { color: #f44336; }
        .log-skip { color: #ff9800; }
        .preview-box { background: #0d1117; border: 1px solid #21262d; border-radius: 8px; padding: 12px; max-height: 400px; overflow-y: auto; font-family: monospace; font-size: 12px; white-space: pre-wrap; color: #8bc34a; display: none; margin-top: 10px; }
        .login-box { max-width: 400px; margin: 80px auto; }
        .flex-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
    </style>
</head>
<body>

<h1>Fix local.php</h1>
<p class="subtitle">Corrige basedir, groq_api_key y regenera local.php en todos los wikis</p>

<div class="info-bar">
    Base: <?php echo SEARCH_PATH; ?> | Groq Key: <?php echo substr(DEFAULT_GROQ_KEY, 0, 12); ?>...
</div>

<div class="card">
    <h2>Configuracion</h2>
    <label for="groq_key">Groq API Key (modificable):</label>
    <input type="text" id="groq_key" value="<?php echo htmlspecialchars(DEFAULT_GROQ_KEY); ?>">

    <div class="flex-row">
        <button class="btn btn-primary" onclick="doScan()">1. Escanear Wikis</button>
        <button class="btn btn-success" onclick="doApply('groq_only')" id="btn-groq" disabled>2. Solo Groq Key</button>
        <button class="btn btn-warning" onclick="doApply('full')" id="btn-full" disabled>3. Local.php Completo</button>
        <button class="btn btn-danger" onclick="doCancel()" id="btn-cancel" style="display:none">Cancelar</button>
        <button class="btn btn-primary" onclick="doPreview()" id="btn-preview" disabled>Vista Previa</button>
    </div>
</div>

<div class="card">
    <h2>Progreso</h2>
    <div class="progress-bar"><div class="progress-fill" id="pbar" style="width:0%">0%</div></div>
    <div class="stats">
        <div class="stat"><div class="num" id="s-total">0</div><div class="lbl">Wikis</div></div>
        <div class="stat"><div class="num" id="s-ok">0</div><div class="lbl">Actualizados</div></div>
        <div class="stat"><div class="num" id="s-skip">0</div><div class="lbl">Sin cambios</div></div>
        <div class="stat"><div class="num" id="s-err">0</div><div class="lbl">Errores</div></div>
    </div>
</div>

<div class="card">
    <h2>Log</h2>
    <div id="log"></div>
</div>

<div class="card">
    <h2>Vista Previa</h2>
    <div class="preview-box" id="preview"></div>
</div>

<script>
var wikis = [];
var cancelled = false;
var running = false;
var counters = {ok: 0, skip: 0, err: 0};

function log(msg, color) {
    var el = document.getElementById('log');
    var line = document.createElement('div');
    line.style.color = color || '#e0e0e0';
    line.textContent = '[' + new Date().toLocaleTimeString() + '] ' + msg;
    el.appendChild(line);
    el.scrollTop = el.scrollHeight;
}

function updateProgress(current, total) {
    var pct = total > 0 ? Math.round((current/total)*100) : 0;
    document.getElementById('pbar').style.width = pct + '%';
    document.getElementById('pbar').textContent = pct + '% (' + current + '/' + total + ')';
    document.getElementById('s-total').textContent = total;
    document.getElementById('s-ok').textContent = counters.ok;
    document.getElementById('s-skip').textContent = counters.skip;
    document.getElementById('s-err').textContent = counters.err;
}

function doScan() {
    log('Escaneando wikis...', '');
    fetch('?action=scan')
    .then(r => r.json())
    .then(data => {
        wikis = data.wikis || [];
        log('Encontrados: ' + wikis.length + ' wikis', '#4caf50');
        updateProgress(0, wikis.length);
        document.getElementById('btn-groq').disabled = false;
        document.getElementById('btn-full').disabled = false;
        document.getElementById('btn-preview').disabled = false;
    })
    .catch(e => log('Error: ' + e, '#f44336'));
}

async function doApply(mode) {
    if (wikis.length === 0) { log('Primero escanee los wikis', '#f44336'); return; }
    if (running) return;
    running = true;
    cancelled = false;
    counters = {ok: 0, skip: 0, err: 0};
    document.getElementById('btn-cancel').style.display = '';
    document.getElementById('btn-groq').disabled = true;
    document.getElementById('btn-full').disabled = true;

    var groqKey = document.getElementById('groq_key').value.trim();
    var actionUrl = mode === 'groq_only' ? 'apply_groq' : 'apply_full';
    var modeLabel = mode === 'groq_only' ? 'GROQ KEY' : 'LOCAL.PHP COMPLETO';
    log('=== Iniciando modo: ' + modeLabel + ' ===', '#4caf50');

    for (var i = 0; i < wikis.length; i++) {
        if (cancelled) { log('--- CANCELADO ---', '#f44336'); break; }
        var wiki = wikis[i];
        try {
            var fd = new FormData();
            fd.append('action', actionUrl);
            fd.append('wiki', wiki.name);
            fd.append('groq_key', groqKey);

            var resp = await fetch('', {method: 'POST', body: fd});
            var data = await resp.json();

            if (data.status === 'ok') {
                if (data.result && data.result.changed === false) {
                    counters.skip++;
                    log('[SKIP] ' + wiki.name + ' (sin cambios)', '#ff9800');
                } else {
                    counters.ok++;
                    log('[OK] ' + wiki.name + (data.result && data.result.backup ? ' (backup: ' + data.result.backup + ')' : ''), '#4caf50');
                }
            } else {
                counters.err++;
                log('[ERROR] ' + wiki.name + ': ' + (data.error || 'desconocido'), '#f44336');
            }
        } catch(e) {
            counters.err++;
            log('[ERROR] ' + wiki.name + ': ' + e, '#f44336');
        }
        updateProgress(i + 1, wikis.length);
    }

    log('=== FINALIZADO: ' + counters.ok + ' OK, ' + counters.skip + ' sin cambios, ' + counters.err + ' errores ===', '#4caf50');
    running = false;
    document.getElementById('btn-cancel').style.display = 'none';
    document.getElementById('btn-groq').disabled = false;
    document.getElementById('btn-full').disabled = false;
}

function doCancel() {
    cancelled = true;
    log('Solicitando cancelacion...', '#f44336');
}

function doPreview() {
    var groqKey = document.getElementById('groq_key').value.trim();
    var wikiName = wikis.length > 0 ? wikis[0].name : 'ejemplo';
    var fd = new FormData();
    fd.append('action', 'preview');
    fd.append('token', '<?php echo SECURITY_TOKEN; ?>');
    fd.append('wiki', wikiName);
    fd.append('groq_key', groqKey);

    fetch('', {method: 'POST', body: fd})
    .then(r => r.json())
    .then(data => {
        var el = document.getElementById('preview');
        el.style.display = 'block';
        el.textContent = data.content || 'Error generando preview';
    })
    .catch(e => log('Error preview: ' + e, '#f44336'));
}
</script>

</body>
</html>
