<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('log_errors', '1');
ini_set('error_log', __DIR__ . '/corregir_rendimiento_error.log');

/**
 * CORRECTOR MASIVO DE RENDIMIENTO WEB - SUBDOMINIOS SIE
 * ======================================================
 * Corrige los problemas de rendimiento detectados por test_rendimiento.php
 * en la carpeta web/ de TODOS los subdominios.
 *
 * CORRECCIONES:
 *   FIX 1: Google Fonts - Agrega preconnect y display=swap para carga no bloqueante
 *   FIX 2: Quita html5shiv.js y respond.js (condicionales IE8/9 obsoletos)
 *   FIX 3: Scripts bloqueantes - Agrega defer a scripts locales sin async/defer
 *   FIX 4: Google Fonts duplicados - Elimina links duplicados de la misma fuente
 *   FIX 5: .htaccess rendimiento - Agrega compresion GZIP y cache del navegador
 *   FIX RUTAS: Corrige index.html con .htaccess RewriteRule (sin meta refresh)
 *
 * MODOS:
 *   ?modo=escanear   (default) - Solo muestra que se cambiaria, NO modifica nada
 *   ?modo=corregir              - Aplica las correcciones con backup (FIX 1-5)
 *   ?modo=rutas                 - Corrige index.html en los subdominios seleccionados
 *   ?sub=nombre                 - Solo un subdominio
 *
 * SEGURIDAD: Crea backup de cada archivo antes de modificar
 */

// =====================================================================
//  CONFIGURACION
// =====================================================================

$basePath = '/home/systeng3/public_html';

$excluir = ['.', '..', 'cgi-bin', '.well-known', '.trash', '.htaccess',
            'respaldo', 'diagnosticos', 'tmp', 'error_log'];

// =====================================================================
//  PARAMETROS
// =====================================================================

$esCLI = (php_sapi_name() === 'cli');
if (!$esCLI) header('Content-Type: text/html; charset=UTF-8');

// Evitar timeout en correcciones masivas
@set_time_limit(300);
@ini_set('max_execution_time', 300);
@ini_set('memory_limit', '256M');

$modo      = $esCLI ? ($argv[1] ?? 'escanear') : ($_GET['modo'] ?? 'escanear');
$targetSub = $esCLI ? ($argv[2] ?? '')          : ($_GET['sub'] ?? '');
$lote      = $esCLI ? 0 : max(0, intval($_GET['lote'] ?? 0));
$porLote   = 20; // Procesar 20 subdominios por vez en modo corregir

if (!empty($targetSub)) {
    if (preg_match('#^https?://#i', $targetSub)) {
        $parsed = parse_url($targetSub);
        if (isset($parsed['host'])) {
            $parts = explode('.', $parsed['host']);
            $targetSub = $parts[0];
        }
    }
    $targetSub = basename(preg_replace('/[^a-zA-Z0-9._-]/', '', $targetSub));
}

// =====================================================================
//  FUNCIONES DE CORRECCION
// =====================================================================

/**
 * Crea backup de un archivo
 */
function crearBackup($filePath)
{
    if (!file_exists($filePath)) return false;
    $timestamp = date('Ymd_His');
    $backupPath = $filePath . '.bak_rendimiento_' . $timestamp;
    return @copy($filePath, $backupPath) ? $backupPath : false;
}

/**
 * FIX 1: Google Fonts - Agregar preconnect y display=swap
 */
function fixGoogleFonts($html)
{
    $cambios = [];
    $nuevoHtml = $html;

    $tienePreconnect = (stripos($html, 'preconnect') !== false && stripos($html, 'fonts.googleapis.com') !== false);

    if (!$tienePreconnect) {
        $preconnect = "\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>";

        $patron = "/([ \t]*<link[^>]*fonts\.googleapis\.com[^>]*>)/i";
        if (preg_match($patron, $nuevoHtml, $m, PREG_OFFSET_CAPTURE)) {
            $pos = $m[1][1];
            $nuevoHtml = substr($nuevoHtml, 0, $pos) . $preconnect . "\n" . substr($nuevoHtml, $pos);
            $cambios[] = 'PRECONNECT_AGREGADO';
        }
    }

    // Agregar display=swap a URLs de Google Fonts que no lo tengan (css v1)
    $nuevoHtml = preg_replace_callback(
        "/(fonts\.googleapis\.com\/css\?[^'\"]*?)(['\"])/i",
        function ($m) use (&$cambios) {
            $url = $m[1];
            $cierre = $m[2];
            if (stripos($url, 'display=swap') === false) {
                $url = rtrim($url, '&');
                $cambios[] = 'DISPLAY_SWAP_AGREGADO';
                return $url . '&display=swap' . $cierre;
            }
            return $m[0];
        },
        $nuevoHtml
    );

    // Tambien para css2 (Google Fonts v2)
    $nuevoHtml = preg_replace_callback(
        "/(fonts\.googleapis\.com\/css2\?[^'\"]*?)(['\"])/i",
        function ($m) use (&$cambios) {
            $url = $m[1];
            $cierre = $m[2];
            if (stripos($url, 'display=swap') === false) {
                $url = rtrim($url, '&');
                $cambios[] = 'DISPLAY_SWAP_V2_AGREGADO';
                return $url . '&display=swap' . $cierre;
            }
            return $m[0];
        },
        $nuevoHtml
    );

    return ['html' => $nuevoHtml, 'cambios' => $cambios];
}

/**
 * FIX 2: Quitar bloques condicionales de IE (html5shiv + respond.js)
 */
function fixIEConditionals($html)
{
    $cambios = [];
    $nuevoHtml = $html;

    $patron = '/\s*<!--\[if\s+[^\]]*\]>\s*.*?<!\[endif\]-->\s*/is';

    if (preg_match($patron, $nuevoHtml)) {
        $nuevoHtml = preg_replace($patron, "\n", $nuevoHtml);
        $cambios[] = 'IE_CONDICIONALES_ELIMINADOS';
    }

    return ['html' => $nuevoHtml, 'cambios' => $cambios];
}

/**
 * FIX 3: Agregar defer a scripts locales bloqueantes (sin async/defer)
 * Solo afecta scripts con src= que NO sean externos (no empiezan con http//)
 * No toca jQuery (debe cargar primero como bloqueante para evitar errores)
 */
function fixScriptsBloqueantes($html)
{
    $cambios = [];
    $nuevoHtml = $html;

    // Buscar <script src="archivo.js"> sin async ni defer (scripts locales)
    $nuevoHtml = preg_replace_callback(
        '/<script([^>]*)\bsrc\s*=\s*["\']([^"\']+)["\']([^>]*)>/i',
        function ($m) use (&$cambios) {
            $antes = $m[1];
            $src   = $m[2];
            $desp  = $m[3];
            $fullAttrs = $antes . $desp;

            // Saltar si es externo
            if (preg_match('#^(https?:)?//#', $src)) return $m[0];

            // Saltar si ya tiene async o defer
            if (preg_match('/\b(async|defer)\b/i', $fullAttrs)) return $m[0];

            // Saltar jQuery — debe cargar como bloqueante (otros scripts dependen de el)
            if (preg_match('/jquery[\.\-]?(min\.)?js/i', $src)) return $m[0];

            // Agregar defer
            $cambios[] = 'DEFER:' . basename($src);
            return '<script' . $antes . 'src="' . $src . '"' . $desp . ' defer>';
        },
        $nuevoHtml
    );

    return ['html' => $nuevoHtml, 'cambios' => $cambios];
}

/**
 * FIX 4: Eliminar links duplicados de Google Fonts
 * Si la misma URL de fuente aparece mas de una vez, elimina las repetidas
 */
function fixGoogleFontsDuplicados($html)
{
    $cambios = [];
    $nuevoHtml = $html;

    // Encontrar todos los <link> de Google Fonts
    if (preg_match_all('/(<link[^>]*fonts\.googleapis\.com\/css[^>]*>)/i', $nuevoHtml, $matches, PREG_SET_ORDER)) {
        $urlsVistas = [];
        foreach ($matches as $match) {
            $tag = $match[1];
            // Extraer la URL del href
            if (preg_match('/href\s*=\s*["\']([^"\']+)["\']/i', $tag, $hrefM)) {
                $url = $hrefM[1];
                // Normalizar: quitar &display=swap para comparar base
                $urlBase = preg_replace('/[&?]display=swap/i', '', $url);
                $urlBase = rtrim($urlBase, '&?');

                if (in_array($urlBase, $urlsVistas)) {
                    // Duplicado — eliminar la linea completa
                    $nuevoHtml = str_replace($tag, '', $nuevoHtml);
                    $cambios[] = 'DUPLICADO_REMOVIDO';
                } else {
                    $urlsVistas[] = $urlBase;
                }
            }
        }
    }

    // Limpiar lineas vacias multiples que queden
    if (!empty($cambios)) {
        $nuevoHtml = preg_replace('/\n{3,}/', "\n\n", $nuevoHtml);
    }

    return ['html' => $nuevoHtml, 'cambios' => $cambios];
}

/**
 * FIX 5: Crear/actualizar .htaccess en web/ con compresion GZIP y cache del navegador
 * No sobreescribe reglas existentes, solo agrega las que faltan
 */
function fixHtaccessRendimiento($webPath)
{
    $cambios = [];
    $htFile = $webPath . '/.htaccess';
    $contenido = '';

    if (file_exists($htFile)) {
        $contenido = @file_get_contents($htFile);
        if ($contenido === false) {
            return ['cambios' => [], 'error' => 'No se pudo leer .htaccess'];
        }
    }

    $bloquesNuevos = [];

    // GZIP compression
    if (!preg_match('/mod_deflate|AddOutputFilterByType.*DEFLATE/i', $contenido)) {
        $bloquesNuevos[] = '
# === Compresion GZIP (agregado por corrector SIE) ===
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css
    AddOutputFilterByType DEFLATE application/javascript application/x-javascript text/javascript
    AddOutputFilterByType DEFLATE application/json application/xml text/xml
    AddOutputFilterByType DEFLATE image/svg+xml application/font-woff application/font-woff2
</IfModule>';
        $cambios[] = 'GZIP_AGREGADO';
    }

    // Browser cache
    if (!preg_match('/mod_expires|ExpiresActive|ExpiresByType/i', $contenido)) {
        $bloquesNuevos[] = '
# === Cache del navegador (agregado por corrector SIE) ===
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresByType application/font-woff "access plus 1 year"
    ExpiresByType application/font-woff2 "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
</IfModule>';
        $cambios[] = 'CACHE_AGREGADO';
    }

    if (empty($bloquesNuevos)) {
        return ['cambios' => [], 'ya_tiene' => true];
    }

    // Backup si existe
    if (file_exists($htFile)) {
        crearBackup($htFile);
    }

    $nuevoContenido = rtrim($contenido) . "\n" . implode("\n", $bloquesNuevos) . "\n";

    if (@file_put_contents($htFile, $nuevoContenido) !== false) {
        return ['cambios' => $cambios];
    }

    return ['cambios' => [], 'error' => 'No se pudo escribir .htaccess'];
}

/**
 * Genera .htaccess en raiz del subdominio para redireccion interna a web/index.php
 * Usa RewriteRule (redireccion interna del servidor, sin HTTP redirect visible)
 */
function getHtaccessRedirectWeb()
{
    return '# Redireccion interna a landing page (generado por corrector SIE)
# El navegador NO ve una redireccion — Apache sirve web/index.php directamente
RewriteEngine On
RewriteRule ^$ web/index.php [L]
';
}

/**
 * Genera .htaccess en raiz para redireccion interna a doku.php
 */
function getHtaccessRedirectDoku()
{
    return '# Redireccion interna a DokuWiki (generado por corrector SIE)
RewriteEngine On
RewriteRule ^$ doku.php [L]
';
}

/**
 * Genera el index.html minimo de fallback (para cuando mod_rewrite esta deshabilitado)
 */
function getIndexHtmlFallback($destino)
{
    $label = ($destino === 'web/index.php') ? 'pagina web' : 'sistema';
    return '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=' . $destino . '">
<title>Redirigiendo...</title>
</head>
<body>
<p>Redirigiendo a la ' . $label . '... <a href="' . $destino . '">Click aqui si no redirige</a></p>
</body>
</html>';
}

/**
 * Analiza el estado de la redireccion raiz de un subdominio
 * Verifica .htaccess RewriteRule Y index.html
 */
function analizarRutaRaiz($subPath, $tipo)
{
    $destino = ($tipo === 'web') ? 'web/index.php' : 'doku.php';
    $htFile = $subPath . '/.htaccess';
    $indexFile = $subPath . '/index.html';

    // Caso ideal: .htaccess tiene RewriteRule interna
    if (file_exists($htFile)) {
        $contenido = @file_get_contents($htFile);
        if ($contenido !== false) {
            // Verificar si tiene rewrite limpio a destino (sin pasar por index.html)
            if (preg_match('/RewriteRule\s+\^\$\s+' . preg_quote($destino, '/') . '/i', $contenido)) {
                return ['estado' => 'ok', 'detalle' => 'RewriteRule interna a ' . $destino, 'metodo' => 'htaccess'];
            }
        }
    }

    // Verificar index.html
    if (file_exists($indexFile)) {
        $contenido = @file_get_contents($indexFile);
        if ($contenido === false) {
            return ['estado' => 'malo', 'detalle' => 'No se puede leer index.html'];
        }

        // Tiene meta refresh al destino correcto?
        $tieneRefresh = (stripos($contenido, 'url=' . $destino) !== false);
        // Tiene JS redirect?
        $tieneJS = (stripos($contenido, $destino) !== false &&
                   (stripos($contenido, 'window.location') !== false || stripos($contenido, 'location.href') !== false));

        if ($tieneRefresh || $tieneJS) {
            // Funciona pero con meta refresh/JS — se puede mejorar con .htaccess
            return ['estado' => 'mejorable', 'detalle' => 'Usa meta refresh/JS (lento, se puede mejorar con .htaccess)', 'metodo' => 'index.html'];
        }

        // index.html existe pero no redirige al destino correcto
        return ['estado' => 'malo', 'detalle' => 'index.html no redirige a ' . $destino];
    }

    return ['estado' => 'falta', 'detalle' => 'No existe index.html ni .htaccess con RewriteRule'];
}

/**
 * Corrige la redireccion raiz de un subdominio
 * Crea .htaccess con RewriteRule interna + index.html como fallback
 */
function corregirRutaRaiz($subPath, $tipo)
{
    $destino = ($tipo === 'web') ? 'web/index.php' : 'doku.php';
    $htFile = $subPath . '/.htaccess';
    $indexFile = $subPath . '/index.html';
    $resultados = [];

    // --- Paso 1: .htaccess con RewriteRule ---
    $htContent = ($tipo === 'web') ? getHtaccessRedirectWeb() : getHtaccessRedirectDoku();

    if (file_exists($htFile)) {
        $existente = @file_get_contents($htFile);
        if ($existente !== false) {
            // Verificar si ya tiene la regla
            if (preg_match('/RewriteRule\s+\^\$\s+' . preg_quote($destino, '/') . '/i', $existente)) {
                $resultados[] = ['archivo' => '.htaccess', 'ok' => true, 'msg' => 'Ya tiene RewriteRule correcta'];
            } else {
                // Backup y agregar regla
                crearBackup($htFile);
                // Si ya tiene RewriteEngine On, solo agregar la regla
                if (preg_match('/RewriteEngine\s+On/i', $existente)) {
                    $regla = "\n# Redireccion interna (corrector SIE)\nRewriteRule ^$ {$destino} [L]\n";
                    if (@file_put_contents($htFile, rtrim($existente) . "\n" . $regla) !== false) {
                        $resultados[] = ['archivo' => '.htaccess', 'ok' => true, 'msg' => 'RewriteRule agregada'];
                    } else {
                        $resultados[] = ['archivo' => '.htaccess', 'ok' => false, 'msg' => 'No se pudo escribir'];
                    }
                } else {
                    // Agregar bloque completo al final
                    if (@file_put_contents($htFile, rtrim($existente) . "\n\n" . $htContent) !== false) {
                        $resultados[] = ['archivo' => '.htaccess', 'ok' => true, 'msg' => 'RewriteRule + Engine agregados'];
                    } else {
                        $resultados[] = ['archivo' => '.htaccess', 'ok' => false, 'msg' => 'No se pudo escribir'];
                    }
                }
            }
        }
    } else {
        // Crear .htaccess nuevo
        if (@file_put_contents($htFile, $htContent) !== false) {
            $resultados[] = ['archivo' => '.htaccess', 'ok' => true, 'msg' => 'Creado con RewriteRule a ' . $destino];
        } else {
            $resultados[] = ['archivo' => '.htaccess', 'ok' => false, 'msg' => 'No se pudo crear'];
        }
    }

    // --- Paso 2: index.html como fallback minimo ---
    if (file_exists($indexFile)) {
        crearBackup($indexFile);
    }
    $fallback = getIndexHtmlFallback($destino);
    if (@file_put_contents($indexFile, $fallback) !== false) {
        $resultados[] = ['archivo' => 'index.html', 'ok' => true, 'msg' => 'Fallback minimo creado'];
    } else {
        $resultados[] = ['archivo' => 'index.html', 'ok' => false, 'msg' => 'No se pudo escribir fallback'];
    }

    return $resultados;
}

/**
 * Analiza un subdominio y retorna que correcciones necesita
 */
function analizarSubdominio($subPath, $carpeta)
{
    $r = [
        'carpeta'       => $carpeta,
        'tiene_web'     => false,
        'tipo'          => 'desconocido',
        'destino'       => '',
        'fixes'         => [],
        'detalles'      => [],
        'ruta_estado'   => '',
        'ruta_detalle'  => '',
        'ruta_metodo'   => '',
    ];

    $webPath = $subPath . '/web';
    $tieneCarpetaWeb = is_dir($webPath);
    $tieneDokuPHP = file_exists($subPath . '/doku.php');

    if ($tieneCarpetaWeb) {
        $webIndex = null;
        if (file_exists($webPath . '/index.php')) {
            $webIndex = $webPath . '/index.php';
        } elseif (file_exists($webPath . '/index.html')) {
            $webIndex = $webPath . '/index.html';
        }
        if (!$webIndex) {
            if (!$tieneDokuPHP) return $r;
            $r['tiene_web'] = true;
            $r['tipo'] = 'dokuwiki';
            $r['destino'] = 'doku.php';
        } else {
            $r['tiene_web'] = true;
            $r['tipo'] = 'web';
            $r['destino'] = 'web/index.php';
            $r['archivo_web'] = basename($webIndex);

            $html = @file_get_contents($webIndex);
            if ($html !== false) {
                // CHECK 1: Google Fonts sin preconnect/swap
                if (preg_match('/fonts\.googleapis\.com\/css/i', $html)) {
                    $tieneSwap = (stripos($html, 'display=swap') !== false);
                    $tienePreconnect = (stripos($html, 'preconnect') !== false && stripos($html, 'fonts.g') !== false);
                    if (!$tieneSwap || !$tienePreconnect) {
                        $r['fixes'][] = 'GOOGLE_FONTS';
                        $detalle = [];
                        if (!$tienePreconnect) $detalle[] = 'falta preconnect';
                        if (!$tieneSwap) $detalle[] = 'falta display=swap';
                        $r['detalles']['GOOGLE_FONTS'] = implode(' + ', $detalle);
                    }
                }

                // CHECK 2: Condicionales IE (html5shiv, respond.js)
                if (preg_match('/<!--\[if\s+[^\]]*\]>/i', $html)) {
                    $r['fixes'][] = 'IE_CONDITIONALS';
                    $scripts = [];
                    if (stripos($html, 'html5shiv') !== false) $scripts[] = 'html5shiv.js';
                    if (stripos($html, 'respond.') !== false) $scripts[] = 'respond.js';
                    $r['detalles']['IE_CONDITIONALS'] = implode(', ', $scripts) ?: 'bloque IE detectado';
                }

                // CHECK 3: Scripts locales bloqueantes (sin async/defer)
                $scriptsBloq = [];
                if (preg_match_all('/<script([^>]*)\bsrc\s*=\s*["\']([^"\']+)["\']([^>]*)>/i', $html, $sm, PREG_SET_ORDER)) {
                    foreach ($sm as $scriptMatch) {
                        $src = $scriptMatch[2];
                        $attrs = $scriptMatch[1] . $scriptMatch[3];
                        // Saltar externos
                        if (preg_match('#^(https?:)?//#', $src)) continue;
                        // Saltar si ya tiene async/defer
                        if (preg_match('/\b(async|defer)\b/i', $attrs)) continue;
                        // Saltar jQuery
                        if (preg_match('/jquery[\.\-]?(min\.)?js/i', $src)) continue;
                        $scriptsBloq[] = basename($src);
                    }
                }
                if (!empty($scriptsBloq)) {
                    $r['fixes'][] = 'JS_BLOQUEANTES';
                    $r['detalles']['JS_BLOQUEANTES'] = count($scriptsBloq) . ' scripts: ' . implode(', ', array_slice($scriptsBloq, 0, 3));
                    if (count($scriptsBloq) > 3) $r['detalles']['JS_BLOQUEANTES'] .= '...';
                }

                // CHECK 4: Google Fonts duplicados (misma URL aparece >1 vez)
                if (preg_match_all('/<link[^>]*href\s*=\s*["\']([^"\']*fonts\.googleapis\.com\/css[^"\']*)["\'][^>]*>/i', $html, $fontMatches)) {
                    $urlsBases = [];
                    $duplicados = 0;
                    foreach ($fontMatches[1] as $fontUrl) {
                        $urlBase = preg_replace('/[&?]display=swap/i', '', $fontUrl);
                        $urlBase = rtrim($urlBase, '&?');
                        if (in_array($urlBase, $urlsBases)) {
                            $duplicados++;
                        } else {
                            $urlsBases[] = $urlBase;
                        }
                    }
                    if ($duplicados > 0) {
                        $r['fixes'][] = 'FONTS_DUPLICADOS';
                        $r['detalles']['FONTS_DUPLICADOS'] = $duplicados . ' link(s) duplicado(s)';
                    }
                }
            }

            // CHECK 5: .htaccess en web/ sin compresion ni cache
            $htWebFile = $webPath . '/.htaccess';
            $htProblemas = [];
            if (file_exists($htWebFile)) {
                $htContent = @file_get_contents($htWebFile);
                if ($htContent !== false) {
                    if (!preg_match('/mod_deflate|AddOutputFilterByType.*DEFLATE/i', $htContent)) {
                        $htProblemas[] = 'sin GZIP';
                    }
                    if (!preg_match('/mod_expires|ExpiresActive|ExpiresByType/i', $htContent)) {
                        $htProblemas[] = 'sin cache';
                    }
                }
            } else {
                $htProblemas[] = 'sin GZIP';
                $htProblemas[] = 'sin cache';
            }
            if (!empty($htProblemas)) {
                $r['fixes'][] = 'HTACCESS_RENDIMIENTO';
                $r['detalles']['HTACCESS_RENDIMIENTO'] = implode(' + ', $htProblemas);
            }
        }
    } elseif ($tieneDokuPHP) {
        $r['tiene_web'] = true;
        $r['tipo'] = 'dokuwiki';
        $r['destino'] = 'doku.php';
    } else {
        return $r;
    }

    // Analizar estado de la redireccion raiz
    $rutaCheck = analizarRutaRaiz($subPath, $r['tipo']);
    $r['ruta_estado'] = $rutaCheck['estado'];
    $r['ruta_detalle'] = $rutaCheck['detalle'];
    $r['ruta_metodo'] = $rutaCheck['metodo'] ?? '';

    return $r;
}

/**
 * Aplica las correcciones a un subdominio
 */
function corregirSubdominio($subPath, $carpeta, $fixes, $destino = 'web/index.php')
{
    $resultados = [];
    $timestamp = date('Ymd_His');

    // --- Fixes HTML: Google Fonts, IE, Scripts bloqueantes, Duplicados (solo web/) ---
    if ($destino === 'web/index.php') {
        $webFiles = [];
        if (file_exists($subPath . '/web/index.php')) $webFiles[] = $subPath . '/web/index.php';
        if (file_exists($subPath . '/web/index.html')) $webFiles[] = $subPath . '/web/index.html';

        foreach ($webFiles as $webFile) {
            $html = @file_get_contents($webFile);
            if ($html === false) {
                $resultados[] = ['archivo' => basename($webFile), 'ok' => false, 'msg' => 'No se pudo leer'];
                continue;
            }

            $modificado = false;
            $cambiosTotales = [];

            // FIX 4: Google Fonts duplicados (ANTES de fix 1 para evitar agregar swap a duplicados)
            if (in_array('FONTS_DUPLICADOS', $fixes)) {
                $fix = fixGoogleFontsDuplicados($html);
                if (!empty($fix['cambios'])) {
                    $html = $fix['html'];
                    $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                    $modificado = true;
                }
            }

            // FIX 1: Google Fonts
            if (in_array('GOOGLE_FONTS', $fixes)) {
                $fix = fixGoogleFonts($html);
                if (!empty($fix['cambios'])) {
                    $html = $fix['html'];
                    $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                    $modificado = true;
                }
            }

            // FIX 2: IE Conditionals
            if (in_array('IE_CONDITIONALS', $fixes)) {
                $fix = fixIEConditionals($html);
                if (!empty($fix['cambios'])) {
                    $html = $fix['html'];
                    $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                    $modificado = true;
                }
            }

            // FIX 3: Scripts bloqueantes
            if (in_array('JS_BLOQUEANTES', $fixes)) {
                $fix = fixScriptsBloqueantes($html);
                if (!empty($fix['cambios'])) {
                    $html = $fix['html'];
                    $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                    $modificado = true;
                }
            }

            if ($modificado) {
                $backup = $webFile . '.bak_rendimiento_' . $timestamp;
                if (!@copy($webFile, $backup)) {
                    $resultados[] = ['archivo' => basename($webFile), 'ok' => false, 'msg' => 'No se pudo crear backup'];
                    continue;
                }

                if (@file_put_contents($webFile, $html) !== false) {
                    $resultados[] = [
                        'archivo' => 'web/' . basename($webFile),
                        'ok' => true,
                        'msg' => implode(', ', $cambiosTotales),
                        'backup' => basename($backup),
                    ];
                } else {
                    @copy($backup, $webFile);
                    $resultados[] = ['archivo' => basename($webFile), 'ok' => false, 'msg' => 'No se pudo escribir'];
                }
            }
        }

        // FIX 5: .htaccess rendimiento (GZIP + cache) en web/
        if (in_array('HTACCESS_RENDIMIENTO', $fixes)) {
            $webPath = $subPath . '/web';
            $htFix = fixHtaccessRendimiento($webPath);
            if (!empty($htFix['cambios'])) {
                $resultados[] = [
                    'archivo' => 'web/.htaccess',
                    'ok' => true,
                    'msg' => implode(', ', $htFix['cambios']),
                ];
            } elseif (!empty($htFix['error'])) {
                $resultados[] = ['archivo' => 'web/.htaccess', 'ok' => false, 'msg' => $htFix['error']];
            }
        }
    }

    return $resultados;
}

// =====================================================================
//  EJECUCION
// =====================================================================

$tiempoInicio = microtime(true);
$resultados   = [];
$correcciones = [];

// Obtener carpetas
if (!empty($targetSub)) {
    $carpetas = [$targetSub];
} else {
    $carpetas = [];
    $scan = @scandir($basePath);
    if (!$scan) {
        echo $esCLI ? "ERROR: No se puede leer {$basePath}\n" : "<p style='color:red'>ERROR</p>";
        exit(1);
    }
    foreach ($scan as $c) {
        if (in_array($c, $excluir)) continue;
        if (!is_dir($basePath . '/' . $c)) continue;
        $carpetas[] = $c;
    }
    sort($carpetas);
}

// Escanear primero TODOS
foreach ($carpetas as $carpeta) {
    $subPath = $basePath . '/' . $carpeta;
    $r = analizarSubdominio($subPath, $carpeta);
    if (!$r['tiene_web']) continue;
    $resultados[] = $r;
}

// En modo corregir, procesar
$totalCorregidos = 0;

if ($modo === 'corregir') {
    @set_time_limit(600);
    @ini_set('max_execution_time', 600);

    if (!$esCLI) {
        header('Content-Type: text/html; charset=UTF-8');
        while (ob_get_level()) ob_end_flush();
        @ini_set('output_buffering', 'off');
        @ini_set('zlib.output_compression', false);
        if (function_exists('apache_setenv')) {
            @apache_setenv('no-gzip', '1');
        }
        echo "<!DOCTYPE html><html><head><title>Corrigiendo...</title></head><body><pre>\n";
    }

    $afectadosParaFix = [];
    foreach ($resultados as $r) {
        if (!empty($r['fixes'])) {
            $afectadosParaFix[] = $r;
        }
    }

    $totalAfectados = count($afectadosParaFix);

    echo "=== CORRECTOR DE RENDIMIENTO WEB - SIE ===\n";
    echo "Fecha: " . date('Y-m-d H:i:s') . "\n";
    echo "PHP: " . phpversion() . "\n";
    echo "Total con web: " . count($resultados) . " | Afectados: {$totalAfectados}\n";
    echo "Correcciones: FIX1=Fonts, FIX2=IE, FIX3=Scripts, FIX4=Duplicados, FIX5=GZIP+Cache\n";
    echo "========================================\n\n";
    if (!$esCLI) { flush(); }

    for ($i = 0; $i < $totalAfectados; $i++) {
        $r = $afectadosParaFix[$i];
        $subPath = $basePath . '/' . $r['carpeta'];
        echo "[" . ($i + 1) . "/{$totalAfectados}] {$r['carpeta']} [" . implode(',', $r['fixes']) . "] ... ";
        if (!$esCLI) { flush(); }

        try {
            $fix = corregirSubdominio($subPath, $r['carpeta'], $r['fixes'], $r['destino']);
            $correcciones[$r['carpeta']] = $fix;
            $totalCorregidos++;

            $resumen = [];
            foreach ($fix as $f) {
                $resumen[] = ($f['ok'] ? 'OK' : 'ERR') . ':' . $f['archivo'] . '(' . $f['msg'] . ')';
            }
            echo implode(' | ', $resumen) . "\n";
        } catch (\Throwable $e) {
            echo "EXCEPTION: " . $e->getMessage() . " en " . $e->getFile() . ":" . $e->getLine() . "\n";
        }
        if (!$esCLI) { flush(); }
    }

    echo "\n========================================\n";
    echo "Completados: {$totalCorregidos} de {$totalAfectados}\n";
    echo "Tiempo: " . round(microtime(true) - $tiempoInicio, 2) . "s\n";
    echo "========== TODOS COMPLETADOS ==========\n";

    if (!$esCLI) {
        echo "</pre>";
        echo "<div style='font-family:monospace;padding:20px;background:#f0fdf4;border:2px solid #16a34a;border-radius:10px;margin:20px;text-align:center;'>";
        echo "<p style='font-size:1.3em;font-weight:bold;color:#16a34a;'>TODOS COMPLETADOS</p>";
        echo "<p>{$totalCorregidos} de {$totalAfectados} subdominios corregidos</p>";
        echo "<p><a href='?' style='color:#2563eb;font-size:1.1em;'>Volver al panel de escaneo</a></p>";
        echo "</div>";
    }
    exit(0);
}

// =====================================================================
//  MODO RUTAS - Corregir redireccion raiz con .htaccess
// =====================================================================

if ($modo === 'rutas') {
    @set_time_limit(600);
    @ini_set('max_execution_time', 600);

    if (!$esCLI) {
        header('Content-Type: text/html; charset=UTF-8');
        while (ob_get_level()) ob_end_flush();
        @ini_set('output_buffering', 'off');
        @ini_set('zlib.output_compression', false);
        if (function_exists('apache_setenv')) {
            @apache_setenv('no-gzip', '1');
        }
        echo "<!DOCTYPE html><html><head><title>Corrigiendo rutas...</title></head><body><pre>\n";
    }

    // Filtrar los que tienen ruta mala, faltante, o mejorable
    $rutasParaFix = [];
    foreach ($resultados as $r) {
        if ($r['ruta_estado'] !== 'ok') {
            $rutasParaFix[] = $r;
        }
    }

    $totalRutas = count($rutasParaFix);

    echo "=== CORRECTOR DE RUTAS (.htaccess RewriteRule) - SIE ===\n";
    echo "Fecha: " . date('Y-m-d H:i:s') . "\n";
    echo "Total sistemas: " . count($resultados) . " | Por corregir: {$totalRutas}\n";
    echo "Metodo: .htaccess RewriteRule interna + index.html fallback\n";
    echo "========================================\n\n";
    if (!$esCLI) { flush(); }

    $corregidos = 0;
    for ($i = 0; $i < $totalRutas; $i++) {
        $r = $rutasParaFix[$i];
        $subPath = $basePath . '/' . $r['carpeta'];
        echo "[" . ($i + 1) . "/{$totalRutas}] {$r['carpeta']} (tipo: {$r['tipo']}, estado: {$r['ruta_estado']}) ... ";
        if (!$esCLI) { flush(); }

        try {
            $fixResults = corregirRutaRaiz($subPath, $r['tipo']);
            $allOk = true;
            $msgs = [];
            foreach ($fixResults as $fr) {
                $msgs[] = ($fr['ok'] ? 'OK' : 'ERR') . ':' . $fr['archivo'] . '(' . $fr['msg'] . ')';
                if (!$fr['ok']) $allOk = false;
            }
            echo implode(' | ', $msgs) . "\n";
            if ($allOk) $corregidos++;
        } catch (\Throwable $e) {
            echo "EXCEPTION: " . $e->getMessage() . "\n";
        }
        if (!$esCLI) { flush(); }
    }

    echo "\n========================================\n";
    echo "Corregidos: {$corregidos} de {$totalRutas}\n";
    echo "Tiempo: " . round(microtime(true) - $tiempoInicio, 2) . "s\n";
    echo "========== TODOS COMPLETADOS ==========\n";

    if (!$esCLI) {
        echo "</pre>";
        echo "<div style='font-family:monospace;padding:20px;background:#f0fdf4;border:2px solid #16a34a;border-radius:10px;margin:20px;text-align:center;'>";
        echo "<p style='font-size:1.3em;font-weight:bold;color:#16a34a;'>TODAS LAS RUTAS CORREGIDAS</p>";
        echo "<p>{$corregidos} de {$totalRutas} subdominios corregidos</p>";
        echo "<p style='font-size:0.88em;color:#475569;margin-top:6px;'>Metodo: .htaccess RewriteRule interna (sin redireccion HTTP visible)</p>";
        echo "<p><a href='?' style='color:#2563eb;font-size:1.1em;'>Volver al panel de escaneo</a></p>";
        echo "</div>";
    }
    exit(0);
}

$tiempoFin = round(microtime(true) - $tiempoInicio, 2);

// Estadisticas
$totalOK       = count(array_filter($resultados, fn($r) => empty($r['fixes'])));
$totalProblema = count(array_filter($resultados, fn($r) => !empty($r['fixes'])));
$afectados     = array_filter($resultados, fn($r) => !empty($r['fixes']));

// Contar por tipo de fix
$conteoFixes = [];
foreach ($resultados as $r) {
    foreach ($r['fixes'] as $f) {
        if (!isset($conteoFixes[$f])) $conteoFixes[$f] = 0;
        $conteoFixes[$f]++;
    }
}

$etiquetasFix = [
    'GOOGLE_FONTS'          => ['label' => 'Google Fonts bloqueante',   'color' => '#f59e0b', 'icon' => '&#9889;'],
    'IE_CONDITIONALS'       => ['label' => 'Scripts IE obsoletos',      'color' => '#8b5cf6', 'icon' => '&#128465;'],
    'JS_BLOQUEANTES'        => ['label' => 'JS sin defer',              'color' => '#ef4444', 'icon' => '&#9888;&#65039;'],
    'FONTS_DUPLICADOS'      => ['label' => 'Fonts duplicados',          'color' => '#f97316', 'icon' => '&#128260;'],
    'HTACCESS_RENDIMIENTO'  => ['label' => 'Sin GZIP/cache',           'color' => '#0ea5e9', 'icon' => '&#128230;'],
];

// Estadisticas de rutas
$rutasOK        = count(array_filter($resultados, fn($r) => $r['ruta_estado'] === 'ok'));
$rutasMejorables = count(array_filter($resultados, fn($r) => $r['ruta_estado'] === 'mejorable'));
$rutasMalas     = count(array_filter($resultados, fn($r) => $r['ruta_estado'] !== 'ok'));
$rutasParaFixLista = array_filter($resultados, fn($r) => $r['ruta_estado'] !== 'ok');

// =====================================================================
//  SALIDA CLI
// =====================================================================

if ($esCLI) {
    echo "================================================================\n";
    echo " CORRECTOR DE RENDIMIENTO WEB - SUBDOMINIOS SIE\n";
    echo " " . date('Y-m-d H:i:s') . " | Modo: {$modo} | Tiempo: {$tiempoFin}s\n";
    echo "================================================================\n\n";

    echo "Total web: " . count($resultados) . " | OK: {$totalOK} | Con problemas: {$totalProblema}\n\n";

    foreach ($conteoFixes as $tipo => $cnt) {
        echo "  {$tipo}: {$cnt}\n";
    }

    if (!empty($afectados)) {
        echo "\n=== SISTEMAS CON PROBLEMAS ===\n";
        foreach ($afectados as $r) {
            echo sprintf("  %-30s [%s]\n", $r['carpeta'], implode(', ', $r['fixes']));
            $fix = $correcciones[$r['carpeta']] ?? null;
            if ($fix) {
                foreach ($fix as $f) {
                    echo sprintf("    -> %s: %s %s\n", $f['archivo'], $f['ok'] ? 'OK' : 'ERROR', $f['msg']);
                }
            }
        }
    }
    exit(0);
}

// =====================================================================
//  SALIDA HTML
// =====================================================================
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Corrector de Rendimiento Web - SIE</title>
<style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f1f5f9; color: #1e293b; padding: 20px; }
    .container { max-width: 1500px; margin: 0 auto; }
    h1 { font-size: 1.5em; color: #0f172a; margin-bottom: 4px; }
    .subtitle { color: #64748b; font-size: 0.88em; margin-bottom: 20px; }

    .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 20px; }
    .card { background: #fff; border-radius: 10px; padding: 12px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .card .num { font-size: 1.6em; font-weight: 700; }
    .card .label { font-size: 0.75em; color: #64748b; }
    .green { color: #16a34a; } .red { color: #dc2626; } .yellow { color: #d97706; } .blue { color: #2563eb; } .purple { color: #8b5cf6; } .orange { color: #f97316; } .cyan { color: #0ea5e9; }

    .section { background: #fff; border-radius: 10px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .section h2 { font-size: 1.1em; margin-bottom: 12px; }

    .explain { background: #eff6ff; border: 1px solid #93c5fd; border-radius: 10px; padding: 16px; margin-bottom: 20px; }
    .explain h2 { color: #1e40af; margin-bottom: 8px; font-size: 1em; }
    .explain p { font-size: 0.84em; color: #334155; margin-bottom: 4px; }
    .explain .fix-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 4px 16px; }
    code { background: #f1f5f9; padding: 1px 4px; border-radius: 3px; font-size: 0.86em; }

    .actions { display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; align-items: center; }
    .btn { padding: 10px 20px; border: none; border-radius: 8px; font-size: 0.9em; cursor: pointer; text-decoration: none; display: inline-block; font-weight: 600; }
    .btn-blue { background: #2563eb; color: #fff; } .btn-blue:hover { background: #1d4ed8; }
    .btn-red { background: #dc2626; color: #fff; } .btn-red:hover { background: #b91c1c; }
    .btn-green { background: #16a34a; color: #fff; } .btn-gray { background: #64748b; color: #fff; }

    .fix-grupo { margin-bottom: 14px; padding: 12px 14px; border-radius: 8px; border: 1px solid #e2e8f0; }
    .fix-titulo { font-weight: 700; font-size: 0.92em; margin-bottom: 6px; display: flex; align-items: center; gap: 8px; }
    .fix-lista { font-size: 0.85em; line-height: 1.9; }
    .fix-lista span { display: inline-block; margin-right: 8px; }

    table { width: 100%; border-collapse: collapse; font-size: 0.8em; }
    th { text-align: left; padding: 7px 5px; border-bottom: 2px solid #e2e8f0; color: #475569; font-size: 0.82em; white-space: nowrap; }
    td { padding: 6px 5px; border-bottom: 1px solid #f1f5f9; }
    tr:hover { background: #f8fafc; }
    tr.row-err { background: #fef2f2; }
    tr.row-err:hover { background: #fee2e2; }

    .badge { display: inline-block; padding: 2px 6px; border-radius: 4px; font-size: 0.74em; font-weight: 600; margin-bottom: 1px; }
    .badge-ok { background: #dcfce7; color: #166534; }
    .badge-err { background: #fee2e2; color: #991b1b; }
    .badge-warn { background: #fef3c7; color: #92400e; }
    .badge-info { background: #dbeafe; color: #1e40af; }
    .badge-purple { background: #ede9fe; color: #5b21b6; }
    .badge-orange { background: #ffedd5; color: #c2410c; }
    .badge-cyan { background: #cffafe; color: #0e7490; }

    .filter-bar { margin-bottom: 12px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
    .filter-bar input, .filter-bar select { padding: 6px 10px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.86em; }
    .filter-bar input { width: 200px; }
</style>
</head>
<body>
<div class="container">

<h1>&#9889; Corrector de Rendimiento Web - SIE</h1>
<p class="subtitle">
    <?= date('Y-m-d H:i:s') ?> |
    Modo: <strong><?= $modo === 'corregir' ? '&#9888;&#65039; CORREGIR' : '&#128269; ESCANEAR' ?></strong> |
    Tiempo: <?= $tiempoFin ?>s |
    Subdominios: <?= count($resultados) ?>
</p>

<div class="explain">
    <h2>&#128161; Correcciones que aplica este script</h2>
    <div class="fix-list">
        <p><strong>FIX 1 - Google Fonts:</strong> Agrega <code>preconnect</code> y <code>display=swap</code> para carga no bloqueante.</p>
        <p><strong>FIX 2 - Scripts IE:</strong> Elimina bloques <code>&lt;!--[if lt IE 9]&gt;</code> con html5shiv.js y respond.js.</p>
        <p><strong>FIX 3 - JS bloqueantes:</strong> Agrega <code>defer</code> a scripts locales sin async/defer (excepto jQuery).</p>
        <p><strong>FIX 4 - Fonts duplicados:</strong> Elimina <code>&lt;link&gt;</code> duplicados de la misma fuente Google.</p>
        <p><strong>FIX 5 - GZIP + Cache:</strong> Agrega compresion GZIP y cache del navegador en <code>web/.htaccess</code>.</p>
        <p><strong>FIX Rutas:</strong> Reemplaza meta refresh con <code>.htaccess RewriteRule</code> interna (sin redireccion HTTP).</p>
    </div>
    <p style="margin-top:8px;"><strong>&#128274; Seguridad:</strong> Cada archivo se respalda como <code>archivo.bak_rendimiento_YYYYMMDD_HHMMSS</code> antes de modificar.</p>
</div>

<!-- Resumen -->
<div class="summary">
    <div class="card"><div class="num blue"><?= count($resultados) ?></div><div class="label">Total sistemas</div></div>
    <div class="card"><div class="num green"><?= $totalOK ?></div><div class="label">OK</div></div>
    <div class="card"><div class="num <?= $totalProblema > 0 ? 'red' : 'green' ?>"><?= $totalProblema ?></div><div class="label">Necesitan fix</div></div>
    <div class="card"><div class="num <?= $rutasMalas > 0 ? 'yellow' : 'green' ?>"><?= $rutasMalas ?></div><div class="label">&#128268; Rutas</div></div>
    <?php foreach ($conteoFixes as $tipo => $cnt):
        $et = $etiquetasFix[$tipo] ?? ['label' => $tipo, 'color' => '#64748b', 'icon' => '?'];
    ?>
    <div class="card"><div class="num" style="color:<?= $et['color'] ?>"><?= $cnt ?></div><div class="label"><?= $et['icon'] ?> <?= htmlspecialchars($et['label']) ?></div></div>
    <?php endforeach; ?>
</div>

<!-- Probar con UN solo sistema -->
<?php if (empty($targetSub) && $modo !== 'corregir'): ?>
<div class="section" style="border-left:4px solid #2563eb;">
    <h2 style="margin-bottom:10px;">&#127919; Probar con UN solo sistema</h2>
    <p style="font-size:0.85em;color:#64748b;margin-bottom:12px;">Selecciona un subdominio para escanear o corregir individualmente antes de aplicar masivamente.</p>
    <div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
        <select id="selectSub" style="padding:8px 12px;border:1px solid #cbd5e1;border-radius:8px;font-size:0.9em;min-width:250px;">
            <option value="">-- Seleccionar subdominio --</option>
            <?php foreach ($resultados as $r):
                $iconTipo = $r['tipo'] === 'web' ? '[web]' : '[doku]';
                $iconEstado = empty($r['fixes']) ? ' OK' : ' (' . count($r['fixes']) . ' fix)';
            ?>
            <option value="<?= htmlspecialchars($r['carpeta']) ?>"><?= htmlspecialchars($r['carpeta']) ?> <?= $iconTipo ?><?= $iconEstado ?></option>
            <?php endforeach; ?>
        </select>
        <button onclick="accionIndividual('escanear')" class="btn btn-blue">&#128269; Escanear</button>
        <button onclick="accionIndividual('corregir')" class="btn btn-red">&#128295; Corregir</button>
    </div>
</div>
<?php endif; ?>

<!-- Botones principales -->
<div class="actions">
    <?php if (!empty($targetSub)): ?>
        <a href="?" class="btn btn-gray">&#8592; Volver a todos</a>
        <?php if ($totalProblema > 0 && $modo !== 'corregir'): ?>
            <a href="?modo=corregir&sub=<?= urlencode($targetSub) ?>" class="btn btn-red"
               onclick="return confirm('Corregir SOLO <?= htmlspecialchars($targetSub) ?>?\n\nSe creara backup antes de modificar.')">
                &#128295; Corregir <?= htmlspecialchars($targetSub) ?>
            </a>
        <?php endif; ?>
    <?php else: ?>
        <a href="?modo=escanear" class="btn btn-blue">&#128269; Escanear todos</a>
        <?php if ($totalProblema > 0 && $modo !== 'corregir'): ?>
            <a href="?modo=corregir" class="btn btn-red"
               onclick="return confirm('ATENCION: Se van a corregir <?= $totalProblema ?> subdominios.\n\nCorrecciones:\n- Google Fonts: preconnect + display=swap\n- Scripts IE: eliminar html5shiv + respond.js\n- JS bloqueantes: agregar defer\n- Fonts duplicados: eliminar repetidos\n- .htaccess: GZIP + cache navegador\n\nSe creara backup de cada archivo.\n\nContinuar?')">
                &#128295; Corregir TODOS (<?= $totalProblema ?> subdominios)
            </a>
        <?php endif; ?>
    <?php endif; ?>
</div>

<!-- Boton Rutas -->
<?php if ($modo !== 'corregir' && $modo !== 'rutas'): ?>
<div class="section" style="border-left:4px solid #e11d48;">
    <h2 style="margin-bottom:8px;">&#128268; Corregir Rutas (redireccion raiz)</h2>
    <p style="font-size:0.85em;color:#64748b;margin-bottom:6px;">
        Configura <code>.htaccess RewriteRule</code> interna en la raiz de cada subdominio (sin redireccion HTTP visible al navegador):
    </p>
    <ul style="font-size:0.84em;color:#475569;margin:0 0 8px 20px;">
        <li>Sistemas <strong>con web/</strong> &rarr; <code>RewriteRule ^$ web/index.php [L]</code></li>
        <li>Sistemas <strong>sin web/</strong> (dokuwiki) &rarr; <code>RewriteRule ^$ doku.php [L]</code></li>
        <li>Conserva <code>index.html</code> minimo como fallback (por si mod_rewrite esta deshabilitado)</li>
    </ul>
    <div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
        <span style="font-size:0.88em;">
            <?php if ($rutasMalas > 0): ?>
                <span class="badge badge-ok"><?= $rutasOK ?> OK</span>
                <?php if ($rutasMejorables > 0): ?>
                    <span class="badge badge-warn"><?= $rutasMejorables ?> mejorables</span>
                <?php endif; ?>
                <span class="badge badge-err"><?= ($rutasMalas - $rutasMejorables) ?> malas/faltantes</span>
            <?php else: ?>
                <span class="badge badge-ok">Todas las rutas OK (<?= $rutasOK ?>)</span>
            <?php endif; ?>
        </span>
        <?php if ($rutasMalas > 0): ?>
            <?php if (!empty($targetSub)): ?>
                <a href="?modo=rutas&sub=<?= urlencode($targetSub) ?>" class="btn btn-red"
                   onclick="return confirm('Corregir ruta de <?= htmlspecialchars($targetSub) ?>?\n\nMetodo: .htaccess RewriteRule interna\nSe creara backup antes de modificar.')">
                    &#128268; Corregir ruta de <?= htmlspecialchars($targetSub) ?>
                </a>
            <?php else: ?>
                <a href="?modo=rutas" class="btn btn-red"
                   onclick="return confirm('ATENCION: Se van a corregir <?= $rutasMalas ?> redirecciones raiz.\n\nMetodo: .htaccess RewriteRule interna\n(sin redireccion HTTP visible)\n\nSe creara backup de cada archivo.\n\nContinuar?')">
                    &#128268; Corregir TODAS las rutas (<?= $rutasMalas ?>)
                </a>
            <?php endif; ?>
        <?php endif; ?>
    </div>
    <?php if ($rutasMalas > 0): ?>
    <details style="margin-top:12px;">
        <summary style="cursor:pointer;font-size:0.85em;color:#64748b;">Ver subdominios con ruta por corregir (<?= $rutasMalas ?>)</summary>
        <div style="margin-top:8px;font-size:0.83em;columns:3;column-gap:16px;">
        <?php foreach ($rutasParaFixLista as $r): ?>
            <div style="break-inside:avoid;margin-bottom:4px;">
                &#8226; <strong><?= htmlspecialchars($r['carpeta']) ?></strong>
                <span class="badge <?= $r['tipo'] === 'web' ? 'badge-info' : 'badge-warn' ?>"><?= $r['tipo'] ?></span>
                <span class="badge <?= $r['ruta_estado'] === 'mejorable' ? 'badge-warn' : 'badge-err' ?>"><?= $r['ruta_estado'] ?></span>
                <span style="color:#94a3b8;font-size:0.9em;"><?= htmlspecialchars($r['ruta_detalle']) ?></span>
            </div>
        <?php endforeach; ?>
        </div>
    </details>
    <?php endif; ?>
</div>
<?php endif; ?>


<?php if ($totalProblema > 0 && $modo !== 'corregir'): ?>
<!-- Problemas agrupados -->
<div class="section">
    <h2>&#9888;&#65039; Subdominios con problemas (<?= $totalProblema ?>)</h2>

    <?php foreach ($etiquetasFix as $tipo => $et):
        $items = array_filter($afectados, fn($r) => in_array($tipo, $r['fixes']));
        if (empty($items)) continue;
    ?>
    <div class="fix-grupo" style="border-left:4px solid <?= $et['color'] ?>;">
        <div class="fix-titulo" style="color:<?= $et['color'] ?>;">
            <?= $et['icon'] ?> <?= htmlspecialchars($et['label']) ?> (<?= count($items) ?>)
        </div>
        <div class="fix-lista">
            <?php foreach ($items as $r): ?>
                <span>&#8226; <strong><?= htmlspecialchars($r['carpeta']) ?></strong>
                <em style="color:#64748b;font-size:0.9em;"><?= htmlspecialchars($r['detalles'][$tipo] ?? '') ?></em></span>
            <?php endforeach; ?>
        </div>
    </div>
    <?php endforeach; ?>
</div>
<?php endif; ?>

<!-- Tabla completa -->
<div class="section">
    <h2>&#128203; Todos los subdominios SIE (<?= count($resultados) ?>)</h2>
    <div class="filter-bar">
        <input type="text" id="filtro" placeholder="Buscar..." oninput="filtrar()">
        <select id="filtroEstado" onchange="filtrar()">
            <option value="">Todos</option>
            <option value="err">Con problemas</option>
            <option value="ok">Solo OK</option>
        </select>
    </div>
    <div style="overflow-x:auto;">
    <table id="tabla">
        <thead>
            <tr>
                <th>#</th>
                <th>Subdominio</th>
                <th>Tipo</th>
                <th>Fonts</th>
                <th>IE</th>
                <th>JS defer</th>
                <th>Duplic.</th>
                <th>GZIP/Cache</th>
                <th>Estado</th>
                <th>Ruta</th>
            </tr>
        </thead>
        <tbody>
        <?php $i = 0; foreach ($resultados as $r): $i++; ?>
            <?php $tieneProblema = !empty($r['fixes']); ?>
            <tr class="<?= $tieneProblema ? 'row-err' : '' ?>"
                data-nombre="<?= strtolower($r['carpeta']) ?>"
                data-estado="<?= $tieneProblema ? 'err' : 'ok' ?>">
                <td><?= $i ?></td>
                <td><strong><?= htmlspecialchars($r['carpeta']) ?></strong></td>
                <td>
                    <?php if ($r['tipo'] === 'web'): ?>
                        <span class="badge badge-info">web</span>
                    <?php else: ?>
                        <span class="badge badge-warn">doku</span>
                    <?php endif; ?>
                </td>
                <!-- Google Fonts -->
                <td>
                    <?php if ($r['tipo'] !== 'web'): ?>
                        <span style="color:#cbd5e1;">-</span>
                    <?php elseif (in_array('GOOGLE_FONTS', $r['fixes'])): ?>
                        <span class="badge badge-err" title="<?= htmlspecialchars($r['detalles']['GOOGLE_FONTS'] ?? '') ?>">fix</span>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
                <!-- IE Conditionals -->
                <td>
                    <?php if ($r['tipo'] !== 'web'): ?>
                        <span style="color:#cbd5e1;">-</span>
                    <?php elseif (in_array('IE_CONDITIONALS', $r['fixes'])): ?>
                        <span class="badge badge-purple" title="<?= htmlspecialchars($r['detalles']['IE_CONDITIONALS'] ?? '') ?>">fix</span>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
                <!-- JS Bloqueantes -->
                <td>
                    <?php if ($r['tipo'] !== 'web'): ?>
                        <span style="color:#cbd5e1;">-</span>
                    <?php elseif (in_array('JS_BLOQUEANTES', $r['fixes'])): ?>
                        <span class="badge badge-err" title="<?= htmlspecialchars($r['detalles']['JS_BLOQUEANTES'] ?? '') ?>">fix</span>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
                <!-- Fonts Duplicados -->
                <td>
                    <?php if ($r['tipo'] !== 'web'): ?>
                        <span style="color:#cbd5e1;">-</span>
                    <?php elseif (in_array('FONTS_DUPLICADOS', $r['fixes'])): ?>
                        <span class="badge badge-orange" title="<?= htmlspecialchars($r['detalles']['FONTS_DUPLICADOS'] ?? '') ?>">fix</span>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
                <!-- HTACCESS Rendimiento -->
                <td>
                    <?php if ($r['tipo'] !== 'web'): ?>
                        <span style="color:#cbd5e1;">-</span>
                    <?php elseif (in_array('HTACCESS_RENDIMIENTO', $r['fixes'])): ?>
                        <span class="badge badge-cyan" title="<?= htmlspecialchars($r['detalles']['HTACCESS_RENDIMIENTO'] ?? '') ?>">fix</span>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
                <!-- Estado general -->
                <td>
                    <?php if ($tieneProblema): ?>
                        <span class="badge badge-err"><?= count($r['fixes']) ?> fix</span>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
                <!-- Ruta -->
                <td>
                    <?php if ($r['ruta_estado'] === 'ok'): ?>
                        <span class="badge badge-ok">OK</span>
                    <?php elseif ($r['ruta_estado'] === 'mejorable'): ?>
                        <span class="badge badge-warn" title="<?= htmlspecialchars($r['ruta_detalle']) ?>">mejorable</span>
                    <?php elseif ($r['ruta_estado'] === 'falta'): ?>
                        <span class="badge badge-err">falta</span>
                    <?php else: ?>
                        <span class="badge badge-err" title="<?= htmlspecialchars($r['ruta_detalle']) ?>">malo</span>
                    <?php endif; ?>
                </td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    </div>
</div>

</div>

<script>
function accionIndividual(modo) {
    var sub = document.getElementById('selectSub');
    if (!sub || !sub.value) {
        alert('Selecciona un subdominio primero');
        return;
    }
    if (modo === 'corregir') {
        if (!confirm('Corregir SOLO ' + sub.value + '?\n\nCorrecciones: Fonts, IE, JS defer, Duplicados, GZIP+Cache\nSe creara backup antes de modificar.')) return;
    }
    window.location.href = '?modo=' + modo + '&sub=' + encodeURIComponent(sub.value);
}

function filtrar() {
    var texto = document.getElementById('filtro').value.toLowerCase();
    var estado = document.getElementById('filtroEstado').value;
    document.querySelectorAll('#tabla tbody tr').forEach(function(f) {
        var mostrar = true;
        if (texto && f.getAttribute('data-nombre').indexOf(texto) === -1) mostrar = false;
        if (estado && f.getAttribute('data-estado') !== estado) mostrar = false;
        f.style.display = mostrar ? '' : 'none';
    });
}
</script>
</body>
</html>
<?php
