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

/**
 * CORRECTOR MASIVO DE LANDING PAGES - SUBDOMINIOS SIE
 * =====================================================
 * Aplica optimizaciones de rendimiento a web/index.html y web/index.php
 * de TODOS los subdominios que tengan carpeta web/.
 *
 * CORRECCIONES:
 *   FIX 1: Google Fonts — carga no bloqueante (media="print" + onload)
 *   FIX 2: CSS no criticos — carga diferida (animate, prettyPhoto, owl, etc.)
 *   FIX 3: JS con defer — todos los scripts excepto jQuery
 *   FIX 4: reCAPTCHA lazy — carga solo al llegar al formulario
 *   FIX 5: HTML roto — corrige tags mal formados (<sec<section>, etc.)
 *   FIX 6: .htaccess — agrega GZIP + cache del navegador
 *
 * MODOS:
 *   ?modo=escanear   (default) — Solo muestra que se cambiaria, NO modifica nada
 *   ?modo=corregir              — Aplica correcciones con backup
 *   ?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',
            '_siedeployer_patch', 'backup_sie-system'];

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

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

@set_time_limit(600);
@ini_set('max_execution_time', 600);
@ini_set('memory_limit', '256M');

$modo      = $esCLI ? ($argv[1] ?? 'escanear') : ($_GET['modo'] ?? 'escanear');
$targetSub = $esCLI ? ($argv[2] ?? '')          : ($_GET['sub'] ?? '');

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));
}

// =====================================================================
//  CSS QUE SE DEBEN DIFERIR (no criticos para primera pintura)
// =====================================================================

$cssNoCriticos = [
    'owl.carousel',
    'owl.theme',
    'Pe-icon-7-stroke',
    'font-awesome',
    'prettyPhoto',
    'animate',
];

// JS que necesitan defer (todos excepto jQuery)
$jsConDefer = [
    'bootstrap',
    'owl.carousel',
    'jquery.fitvids',
    'smoothscroll',
    'jquery.parallax',
    'jquery.prettyPhoto',
    'jquery.ajaxchimp',
    'wow',
    'waypoints',
    'jquery.counterup',
    'script.js',
];

// =====================================================================
//  FUNCIONES DE BACKUP
// =====================================================================

function crearBackup($filePath) {
    if (!file_exists($filePath)) return false;
    $backupPath = $filePath . '.bak_landing_' . date('Ymd_His');
    return @copy($filePath, $backupPath) ? $backupPath : false;
}

// =====================================================================
//  FIX 1: Google Fonts — carga no bloqueante
// =====================================================================

function fixGoogleFonts($html) {
    $cambios = [];

    // Patron para links de Google Fonts (con comillas simples o dobles)
    $patron = '/<link[^>]*href=[\'"]([^"\']*fonts\.googleapis\.com\/css[^"\']*)[\'"][^>]*>/i';

    if (!preg_match_all($patron, $html, $matches, PREG_SET_ORDER)) {
        return ['html' => $html, 'cambios' => $cambios];
    }

    // Primero: reemplazar cada link de Google Fonts por version no bloqueante
    // (antes de insertar preconnect, para que las posiciones coincidan)
    $urlsOriginales = [];
    foreach ($matches as $m) {
        $original = $m[0];
        $url = $m[1];

        // Asegurar display=swap
        if (stripos($url, 'display=swap') === false) {
            $url = rtrim($url, '&') . '&display=swap';
        }

        $urlsOriginales[] = $url;

        // Carga no bloqueante: media="print" onload="this.media='all'"
        $nuevo = '<link href="' . $url . '" rel="stylesheet" media="print" onload="this.media=\'all\'">';

        $html = str_replace($original, $nuevo, $html);
        $cambios[] = 'FONT_DEFER';
    }

    // Segundo: agregar preconnect si no existe
    $tienePreconnect = (stripos($html, 'preconnect') !== false && stripos($html, 'fonts.googleapis') !== false);
    if (!$tienePreconnect) {
        $preconnect = "    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" crossorigin>\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n";
        // Insertar antes del primer link de Google Fonts (ya modificado)
        $posFont = stripos($html, 'fonts.googleapis.com');
        if ($posFont !== false) {
            // Buscar el inicio del <link antes de esa posicion
            $posLink = strrpos(substr($html, 0, $posFont), '<link');
            if ($posLink !== false) {
                $html = substr($html, 0, $posLink) . $preconnect . substr($html, $posLink);
                $cambios[] = 'PRECONNECT';
            }
        }
    }

    // Tercero: agregar noscript fallback antes de </head>
    $tieneNoscriptFonts = (!empty($cambios) && preg_match('/<noscript[^>]*>.*?fonts\.googleapis.*?<\/noscript>/is', $html));
    if (!empty($cambios) && !$tieneNoscriptFonts) {
        $noscript = "\n    <noscript>\n";
        foreach ($urlsOriginales as $url) {
            $noscript .= '        <link href="' . $url . '" rel="stylesheet">' . "\n";
        }
        $noscript .= "    </noscript>\n";
        $html = str_replace('</head>', $noscript . '</head>', $html);
        $cambios[] = 'NOSCRIPT_FALLBACK';
    }

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

// =====================================================================
//  FIX 2: CSS no criticos — carga diferida
// =====================================================================

function fixCssNoCriticos($html, $cssNoCriticos) {
    $cambios = [];

    foreach ($cssNoCriticos as $nombre) {
        // Buscar <link href="css/nombre.css" rel="stylesheet">
        $patron = '/(<link[^>]*href=[\'"][^"\']*' . preg_quote($nombre, '/') . '[^"\']*\.css[\'"][^>]*)(>)/i';

        if (preg_match($patron, $html, $m)) {
            $linkOriginal = $m[0];

            // Si ya tiene media="print" onload, skip
            if (stripos($linkOriginal, 'media="print"') !== false) continue;

            // Agregar media="print" onload="this.media='all'"
            $linkNuevo = $m[1] . ' media="print" onload="this.media=\'all\'"' . $m[2];
            $html = str_replace($linkOriginal, $linkNuevo, $html);
            $cambios[] = 'CSS_DEFER:' . $nombre;
        }
    }

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

// =====================================================================
//  FIX 3: JS con defer
// =====================================================================

function fixJsDefer($html, $jsConDefer) {
    $cambios = [];

    foreach ($jsConDefer as $nombre) {
        // Buscar TODOS los <script src="...nombre..."> sin defer (puede haber multiples, ej: jquery.ajaxchimp.min.js + jquery.ajaxchimp.langs.js)
        $patron = '/(<script[^>]*src=[\'"][^"\']*' . preg_quote($nombre, '/') . '[^"\']*[\'"])([^>]*>)/i';

        if (preg_match_all($patron, $html, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $m) {
                $tagOriginal = $m[0];

                // Si ya tiene defer, skip
                if (stripos($tagOriginal, 'defer') !== false) continue;

                // Agregar defer
                $tagNuevo = $m[1] . ' defer' . $m[2];
                $html = str_replace($tagOriginal, $tagNuevo, $html);
                $cambios[] = 'JS_DEFER:' . basename($m[0]);
            }
        }
    }

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

// =====================================================================
//  FIX 4: reCAPTCHA lazy load
// =====================================================================

function fixRecaptchaLazy($html) {
    $cambios = [];

    // Buscar <script src="https://www.google.com/recaptcha/api.js" ...></script>
    $patron = '/<script[^>]*src=[\'"][^"\']*recaptcha\/api\.js[^"\']*[\'"][^>]*><\/script>/i';

    if (preg_match($patron, $html, $m)) {
        $original = $m[0];

        $lazy = '<!-- reCAPTCHA: lazy load al llegar al formulario -->
        <script>
        var recaptchaLoaded = false;
        function loadRecaptcha() {
            if (recaptchaLoaded) return;
            recaptchaLoaded = true;
            var s = document.createElement(\'script\');
            s.src = \'https://www.google.com/recaptcha/api.js\';
            s.async = true; s.defer = true;
            document.head.appendChild(s);
        }
        var cs = document.getElementById(\'CONTACT\');
        if (cs && window.IntersectionObserver) {
            new IntersectionObserver(function(e) {
                if (e[0].isIntersecting) { loadRecaptcha(); this.disconnect(); }
            }, { rootMargin: \'200px\' }).observe(cs);
        }
        setTimeout(loadRecaptcha, 5000);
        </script>';

        $html = str_replace($original, $lazy, $html);
        $cambios[] = 'RECAPTCHA_LAZY';
    }

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

// =====================================================================
//  FIX 5: HTML roto
// =====================================================================

function fixHtmlRoto($html) {
    $cambios = [];

    // Fix <sec<section> → <section>
    if (strpos($html, '<sec<section') !== false) {
        $html = str_replace('<sec<section', '<section', $html);
        $cambios[] = 'HTML_TAG_ROTO';
    }

    // Fix DOCTYPE viejo → HTML5
    if (stripos($html, 'HTML 4.01') !== false || stripos($html, 'DTD HTML') !== false) {
        $html = preg_replace('/<!DOCTYPE[^>]*>/i', '<!DOCTYPE html>', $html);
        $cambios[] = 'DOCTYPE_HTML5';
    }

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

// =====================================================================
//  FIX 6: .htaccess — GZIP + cache
// =====================================================================

function getHtaccessOptimizacion() {
    return '
# =============================================
# Optimizacion de rendimiento - Landing Page
# Aplicado por siedeployer/corregir_landing.php
# =============================================

# GZIP: Comprime CSS, JS, HTML, SVG (~60-80% reduccion)
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/css application/javascript application/x-javascript text/javascript
    AddOutputFilterByType DEFLATE image/svg+xml application/json application/xml text/xml
</IfModule>

# Cache del navegador: evita re-descargar recursos estaticos
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 week"
    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/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType application/font-woff2 "access plus 1 year"
</IfModule>

# Headers de cache
<IfModule mod_headers.c>
    <FilesMatch "\.(css|js|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$">
        Header set Cache-Control "public, max-age=2592000"
    </FilesMatch>
</IfModule>';
}

function fixHtaccess($webPath) {
    $htaccessPath = $webPath . '/.htaccess';
    $bloque = getHtaccessOptimizacion();
    $marcador = 'Aplicado por siedeployer/corregir_landing.php';

    if (file_exists($htaccessPath)) {
        $contenido = @file_get_contents($htaccessPath);
        if ($contenido === false) return ['ok' => false, 'msg' => 'No se pudo leer .htaccess'];

        // Si ya tiene nuestro bloque, skip
        if (strpos($contenido, $marcador) !== false) {
            return ['ok' => true, 'msg' => 'Ya tiene optimizaciones', 'skip' => true];
        }

        // Backup
        crearBackup($htaccessPath);

        // Agregar al final
        $contenido .= "\n" . $bloque . "\n";
    } else {
        $contenido = $bloque . "\n";
    }

    if (@file_put_contents($htaccessPath, $contenido) !== false) {
        return ['ok' => true, 'msg' => 'GZIP + cache agregados'];
    }
    return ['ok' => false, 'msg' => 'No se pudo escribir .htaccess'];
}

// =====================================================================
//  ANALIZAR SUBDOMINIO
// =====================================================================

function analizarSubdominio($subPath, $carpeta, $cssNoCriticos, $jsConDefer) {
    $r = [
        'carpeta'     => $carpeta,
        'tiene_web'   => false,
        'archivos'    => [],     // index.html, index.php que tiene en web/
        'fixes'       => [],
        'detalles'    => [],
        'htaccess_ok' => false,
    ];

    $webPath = $subPath . '/web';
    if (!is_dir($webPath)) return $r;

    $r['tiene_web'] = true;

    // Buscar archivos index en web/
    $archivosWeb = [];
    if (file_exists($webPath . '/index.html')) $archivosWeb[] = 'index.html';
    if (file_exists($webPath . '/index.php'))  $archivosWeb[] = 'index.php';

    if (empty($archivosWeb)) return $r;

    $r['archivos'] = $archivosWeb;

    // Analizar el primer archivo para detectar problemas
    $archivoAnalisis = $webPath . '/' . $archivosWeb[0];
    $html = @file_get_contents($archivoAnalisis);
    if ($html === false) return $r;

    // CHECK 1: Google Fonts bloqueante
    if (preg_match('/fonts\.googleapis\.com\/css/i', $html)) {
        $yaDeferido = (stripos($html, 'media="print"') !== false && stripos($html, 'fonts.googleapis') !== false);
        if (!$yaDeferido) {
            $r['fixes'][] = 'GOOGLE_FONTS';
            $tieneSwap = (stripos($html, 'display=swap') !== false);
            $tienePreconnect = (stripos($html, 'preconnect') !== false);
            $detalle = [];
            if (!$tienePreconnect) $detalle[] = 'sin preconnect';
            if (!$tieneSwap) $detalle[] = 'sin display=swap';
            $detalle[] = 'carga bloqueante';
            $r['detalles']['GOOGLE_FONTS'] = implode(', ', $detalle);
        }
    }

    // CHECK 2: CSS no criticos sin diferir
    $cssSinDiferir = 0;
    foreach ($cssNoCriticos as $nombre) {
        if (preg_match('/<link[^>]*' . preg_quote($nombre, '/') . '[^>]*>/i', $html, $m)) {
            if (stripos($m[0], 'media="print"') === false) {
                $cssSinDiferir++;
            }
        }
    }
    if ($cssSinDiferir > 0) {
        $r['fixes'][] = 'CSS_BLOQUEANTE';
        $r['detalles']['CSS_BLOQUEANTE'] = $cssSinDiferir . ' CSS no criticos sin diferir';
    }

    // CHECK 3: JS sin defer (preg_match_all para capturar multiples archivos con mismo patron, ej: jquery.ajaxchimp.min.js + jquery.ajaxchimp.langs.js)
    $jsSinDefer = 0;
    foreach ($jsConDefer as $nombre) {
        if (preg_match_all('/<script[^>]*' . preg_quote($nombre, '/') . '[^>]*>/i', $html, $allM)) {
            foreach ($allM[0] as $tag) {
                if (stripos($tag, 'defer') === false) {
                    $jsSinDefer++;
                }
            }
        }
    }
    if ($jsSinDefer > 0) {
        $r['fixes'][] = 'JS_BLOQUEANTE';
        $r['detalles']['JS_BLOQUEANTE'] = $jsSinDefer . ' scripts sin defer';
    }

    // CHECK 4: reCAPTCHA bloqueante
    if (preg_match('/<script[^>]*recaptcha\/api\.js[^>]*>/i', $html)) {
        // Verificar si ya es lazy
        if (stripos($html, 'loadRecaptcha') === false) {
            $r['fixes'][] = 'RECAPTCHA';
            $r['detalles']['RECAPTCHA'] = 'reCAPTCHA carga al inicio';
        }
    }

    // CHECK 5: HTML roto
    if (strpos($html, '<sec<section') !== false || stripos($html, 'HTML 4.01') !== false || stripos($html, 'DTD HTML') !== false) {
        $r['fixes'][] = 'HTML_ROTO';
        $detalles = [];
        if (strpos($html, '<sec<section') !== false) $detalles[] = 'tag roto';
        if (stripos($html, 'HTML 4.01') !== false || stripos($html, 'DTD HTML') !== false) $detalles[] = 'DOCTYPE viejo';
        $r['detalles']['HTML_ROTO'] = implode(', ', $detalles);
    }

    // CHECK 6: .htaccess sin GZIP/cache
    $htaccessPath = $webPath . '/.htaccess';
    if (file_exists($htaccessPath)) {
        $htContent = @file_get_contents($htaccessPath);
        $tieneGzip = (stripos($htContent, 'mod_deflate') !== false);
        $tieneCache = (stripos($htContent, 'mod_expires') !== false);
        if (!$tieneGzip || !$tieneCache) {
            $r['fixes'][] = 'HTACCESS';
            $falta = [];
            if (!$tieneGzip) $falta[] = 'sin GZIP';
            if (!$tieneCache) $falta[] = 'sin cache';
            $r['detalles']['HTACCESS'] = implode(', ', $falta);
        } else {
            $r['htaccess_ok'] = true;
        }
    } else {
        $r['fixes'][] = 'HTACCESS';
        $r['detalles']['HTACCESS'] = 'no existe .htaccess';
    }

    return $r;
}

// =====================================================================
//  CORREGIR SUBDOMINIO
// =====================================================================

function corregirSubdominio($subPath, $carpeta, $fixes, $archivos, $cssNoCriticos, $jsConDefer) {
    $resultados = [];
    $webPath = $subPath . '/web';

    // Corregir cada archivo (index.html y/o index.php)
    foreach ($archivos as $archivo) {
        $filePath = $webPath . '/' . $archivo;
        $html = @file_get_contents($filePath);
        if ($html === false) {
            $resultados[] = ['archivo' => $archivo, 'ok' => false, 'msg' => 'No se pudo leer'];
            continue;
        }

        $modificado = false;
        $cambiosTotales = [];

        // FIX 5: HTML roto (primero para evitar que regex falle)
        if (in_array('HTML_ROTO', $fixes)) {
            $fix = fixHtmlRoto($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: CSS no criticos
        if (in_array('CSS_BLOQUEANTE', $fixes)) {
            $fix = fixCssNoCriticos($html, $cssNoCriticos);
            if (!empty($fix['cambios'])) {
                $html = $fix['html'];
                $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                $modificado = true;
            }
        }

        // FIX 3: JS defer
        if (in_array('JS_BLOQUEANTE', $fixes)) {
            $fix = fixJsDefer($html, $jsConDefer);
            if (!empty($fix['cambios'])) {
                $html = $fix['html'];
                $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                $modificado = true;
            }
        }

        // FIX 4: reCAPTCHA lazy
        if (in_array('RECAPTCHA', $fixes)) {
            $fix = fixRecaptchaLazy($html);
            if (!empty($fix['cambios'])) {
                $html = $fix['html'];
                $cambiosTotales = array_merge($cambiosTotales, $fix['cambios']);
                $modificado = true;
            }
        }

        if ($modificado) {
            $backup = crearBackup($filePath);
            if (!$backup) {
                $resultados[] = ['archivo' => $archivo, 'ok' => false, 'msg' => 'No se pudo crear backup'];
                continue;
            }

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

    // FIX 6: .htaccess
    if (in_array('HTACCESS', $fixes)) {
        $fix = fixHtaccess($webPath);
        if (!isset($fix['skip'])) {
            $resultados[] = [
                'archivo' => 'web/.htaccess',
                'ok' => $fix['ok'],
                'msg' => $fix['msg'],
            ];
        }
    }

    return $resultados;
}

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

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

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

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

// =====================================================================
//  MODO CORREGIR
// =====================================================================

if ($modo === 'corregir') {
    @set_time_limit(600);
    while (ob_get_level()) ob_end_flush();
    @ini_set('output_buffering', 'off');
    @ini_set('zlib.output_compression', false);

    echo "<!DOCTYPE html><html><head><title>Corrigiendo landing pages...</title>";
    echo "<style>body{font-family:monospace;background:#0f172a;color:#e2e8f0;padding:20px;line-height:1.7;} ";
    echo ".ok{color:#4ade80;} .err{color:#f87171;} .warn{color:#fbbf24;} ";
    echo "a{color:#38bdf8;} .btn{display:inline-block;padding:8px 16px;background:#2563eb;color:#fff;border-radius:6px;text-decoration:none;margin:4px;}</style>";
    echo "</head><body><pre>\n";
    flush();

    $afectados = array_filter($resultados, fn($r) => !empty($r['fixes']));
    $totalAfectados = count($afectados);

    echo "=== CORRECTOR DE LANDING PAGES - SIE ===\n";
    echo "Fecha: " . date('Y-m-d H:i:s') . "\n";
    echo "Total con web/: " . count($resultados) . " | Afectados: {$totalAfectados}\n";
    echo "=========================================\n\n";
    flush();

    $corregidos = 0;
    $i = 0;
    foreach ($afectados as $r) {
        $i++;
        $subPath = $basePath . '/' . $r['carpeta'];
        echo "[{$i}/{$totalAfectados}] <span class='warn'>{$r['carpeta']}</span> (" . implode(', ', $r['archivos']) . ") ... ";
        flush();

        try {
            $fixes = corregirSubdominio($subPath, $r['carpeta'], $r['fixes'], $r['archivos'], $cssNoCriticos, $jsConDefer);
            $corregidos++;

            foreach ($fixes as $f) {
                $clase = $f['ok'] ? 'ok' : 'err';
                echo "\n  <span class='{$clase}'>" . ($f['ok'] ? 'OK' : 'ERR') . "</span> {$f['archivo']}: {$f['msg']}";
            }
            echo "\n";
        } catch (\Throwable $e) {
            echo "<span class='err'>EXCEPTION: " . htmlspecialchars($e->getMessage()) . "</span>\n";
        }
        flush();
    }

    echo "\n=========================================\n";
    echo "<span class='ok'>Completados: {$corregidos} de {$totalAfectados}</span>\n";
    echo "Tiempo: " . round(microtime(true) - $tiempoInicio, 2) . "s\n";
    echo "</pre>";
    echo "<div style='text-align:center;margin:20px;'>";
    echo "<a href='?' class='btn'>Volver al escaneo</a>";
    echo "</div></body></html>";
    exit(0);
}

// =====================================================================
//  MODO ESCANEAR (dashboard HTML)
// =====================================================================

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

$totalConWeb    = count($resultados);
$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) {
        $conteoFixes[$f] = ($conteoFixes[$f] ?? 0) + 1;
    }
}

$etiquetasFix = [
    'GOOGLE_FONTS'   => ['label' => 'Google Fonts bloqueante', 'color' => '#f59e0b', 'icon' => '&#9889;'],
    'CSS_BLOQUEANTE' => ['label' => 'CSS no criticos bloqueantes', 'color' => '#ec4899', 'icon' => '&#127912;'],
    'JS_BLOQUEANTE'  => ['label' => 'JS sin defer', 'color' => '#8b5cf6', 'icon' => '&#9881;'],
    'RECAPTCHA'      => ['label' => 'reCAPTCHA bloqueante', 'color' => '#06b6d4', 'icon' => '&#128274;'],
    'HTML_ROTO'      => ['label' => 'HTML roto/obsoleto', 'color' => '#ef4444', 'icon' => '&#128295;'],
    'HTACCESS'       => ['label' => 'Sin GZIP/Cache', 'color' => '#22c55e', 'icon' => '&#128230;'],
];

?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Corrector de Landing Pages - SIE</title>
<style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f1f5f9; color: #1e293b; padding: 20px; }
    .container { max-width: 1400px; 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(140px, 1fr)); gap: 12px; margin-bottom: 20px; }
    .card { background: #fff; border-radius: 10px; padding: 14px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .card .num { font-size: 1.8em; font-weight: 700; }
    .card .label { font-size: 0.8em; color: #64748b; }
    .green { color: #16a34a; } .red { color: #dc2626; } .yellow { color: #d97706; } .blue { color: #2563eb; } .purple { color: #8b5cf6; }

    .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.86em; color: #334155; margin-bottom: 4px; }

    .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-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; }

    table { width: 100%; border-collapse: collapse; font-size: 0.85em; }
    th { text-align: left; padding: 8px 6px; border-bottom: 2px solid #e2e8f0; color: #64748b; font-size: 0.82em; position: sticky; top: 0; background: #fff; }
    td { padding: 6px; border-bottom: 1px solid #f1f5f9; }
    tr:hover { background: #f8fafc; }
    .badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.75em; font-weight: 600; margin: 1px; }

    .filter-bar { margin-bottom: 10px; }
    .filter-bar input { padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.9em; width: 250px; }
</style>
</head>
<body>
<div class="container">

<h1>&#128640; Corrector de Landing Pages</h1>
<p class="subtitle">Escaneo: <?= date('Y-m-d H:i:s') ?> | Tiempo: <?= $tiempoFin ?>s | Solo subdominios con carpeta <code>web/</code></p>

<!-- Resumen -->
<div class="summary">
    <div class="card"><div class="num blue"><?= $totalConWeb ?></div><div class="label">Con carpeta web/</div></div>
    <div class="card"><div class="num green"><?= $totalOK ?></div><div class="label">Ya optimizados</div></div>
    <div class="card"><div class="num red"><?= $totalProblema ?></div><div class="label">Necesitan correccion</div></div>
    <?php foreach ($conteoFixes as $fix => $cnt): ?>
    <?php $e = $etiquetasFix[$fix] ?? ['label' => $fix, 'color' => '#64748b', 'icon' => '?']; ?>
    <div class="card"><div class="num" style="color:<?= $e['color'] ?>"><?= $cnt ?></div><div class="label"><?= $e['icon'] ?> <?= $e['label'] ?></div></div>
    <?php endforeach; ?>
</div>

<!-- Que hace este corrector -->
<div class="explain">
    <h2>&#128214; Que corrige este parche</h2>
    <p><strong>FIX 1:</strong> Google Fonts — carga no bloqueante con <code>media="print" onload</code></p>
    <p><strong>FIX 2:</strong> CSS no criticos (animate, prettyPhoto, owl, font-awesome) — carga diferida</p>
    <p><strong>FIX 3:</strong> JavaScript — agrega <code>defer</code> a todos los scripts excepto jQuery</p>
    <p><strong>FIX 4:</strong> reCAPTCHA — carga lazy solo cuando el usuario llega al formulario</p>
    <p><strong>FIX 5:</strong> HTML roto — corrige tags mal formados y DOCTYPE obsoleto</p>
    <p><strong>FIX 6:</strong> .htaccess — agrega compresion GZIP y cache del navegador</p>
    <p style="margin-top:8px;color:#1e40af;"><strong>Aplica a:</strong> <code>web/index.html</code> y <code>web/index.php</code> (ambos si existen). Crea backup antes de modificar.</p>
</div>

<!-- Botones de accion -->
<div class="actions">
    <a href="?" class="btn btn-blue">&#128269; Re-escanear</a>
    <?php if ($totalProblema > 0): ?>
    <a href="?modo=corregir" class="btn btn-green" onclick="return confirm('Aplicar correcciones a <?= $totalProblema ?> subdominios?\n\nSe creara backup de cada archivo antes de modificar.')">
        &#128295; Corregir <?= $totalProblema ?> subdominios
    </a>
    <?php endif; ?>
    <?php if (!empty($targetSub)): ?>
    <a href="?" class="btn btn-gray">Ver todos</a>
    <?php endif; ?>
</div>

<!-- Tabla de subdominios -->
<?php if (!empty($resultados)): ?>
<div class="section">
    <h2>&#128203; Subdominios con carpeta web/ (<?= $totalConWeb ?>)</h2>
    <div class="filter-bar">
        <input type="text" id="filtro" placeholder="Buscar subdominio..." oninput="filtrar()">
    </div>
    <div style="max-height:600px;overflow-y:auto;">
    <table id="tabla">
        <thead>
            <tr>
                <th>#</th>
                <th>Subdominio</th>
                <th>Archivos</th>
                <th>Estado</th>
                <th>Problemas detectados</th>
                <th>Accion</th>
            </tr>
        </thead>
        <tbody>
        <?php $n = 0; foreach ($resultados as $r): $n++;
            $esOK = empty($r['fixes']);
        ?>
            <tr data-name="<?= htmlspecialchars(strtolower($r['carpeta'])) ?>">
                <td><?= $n ?></td>
                <td><strong><?= htmlspecialchars($r['carpeta']) ?></strong></td>
                <td style="font-size:0.82em;"><?= implode(', ', $r['archivos']) ?></td>
                <td>
                    <?php if ($esOK): ?>
                        <span class="badge" style="background:#dcfce7;color:#166534;">&#10003; OK</span>
                    <?php else: ?>
                        <span class="badge" style="background:#fef2f2;color:#991b1b;"><?= count($r['fixes']) ?> fixes</span>
                    <?php endif; ?>
                </td>
                <td>
                    <?php foreach ($r['fixes'] as $fix):
                        $e = $etiquetasFix[$fix] ?? ['label' => $fix, 'color' => '#64748b', 'icon' => '?'];
                        $detalle = $r['detalles'][$fix] ?? '';
                    ?>
                        <span class="badge" style="background:<?= $e['color'] ?>22;color:<?= $e['color'] ?>;" title="<?= htmlspecialchars($detalle) ?>"><?= $e['icon'] ?> <?= $e['label'] ?></span>
                    <?php endforeach; ?>
                    <?php if ($r['htaccess_ok']): ?>
                        <span class="badge" style="background:#dcfce7;color:#166534;">&#128230; GZIP OK</span>
                    <?php endif; ?>
                </td>
                <td>
                    <?php if (!$esOK): ?>
                        <a href="?modo=corregir&sub=<?= urlencode($r['carpeta']) ?>" style="color:#2563eb;font-size:0.85em;" onclick="return confirm('Corregir <?= htmlspecialchars($r['carpeta']) ?>?')">Corregir</a>
                    <?php else: ?>
                        <span style="color:#94a3b8;font-size:0.85em;">—</span>
                    <?php endif; ?>
                </td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    </div>
</div>
<?php else: ?>
<div class="section">
    <p style="text-align:center;color:#64748b;padding:40px;">No se encontraron subdominios con carpeta <code>web/</code>.</p>
</div>
<?php endif; ?>

</div>

<script>
function filtrar() {
    var texto = document.getElementById('filtro').value.toLowerCase();
    document.querySelectorAll('#tabla tbody tr').forEach(function(row) {
        var name = row.dataset.name || '';
        row.style.display = (!texto || name.indexOf(texto) !== -1) ? '' : 'none';
    });
}
</script>
</body>
</html>
