<?php
/**
 * TEST DE RENDIMIENTO - PAGINA WEB DE SUBDOMINIOS
 * ================================================
 * Diagnostica por que las paginas web (carpeta web/) tardan en cargar.
 *
 * Analiza:
 *  1. Recursos externos bloqueantes (Google Fonts, reCAPTCHA, CDNs)
 *  2. Cantidad y tamano de archivos CSS/JS locales
 *  3. Tamano de imagenes
 *  4. Configuracion de .htaccess (compresion, cache)
 *  5. Tiempo de respuesta HTTP real de cada recurso externo
 *  6. Problemas en el HTML (scripts bloqueantes, falta de async/defer)
 *  7. Configuracion de PHP (output buffering, etc.)
 *
 * MODOS DE USO:
 *   1. Analisis LOCAL (filesystem): Examina la carpeta web/ de un subdominio
 *      php test_rendimiento.php [ruta_subdominio]
 *
 *   2. Analisis REMOTO (HTTP): Mide tiempos reales de carga
 *      php test_rendimiento.php --url https://subdominio.dominio.com
 *
 *   3. Desde navegador: Acceder directamente, analiza el subdominio actual
 *
 * CONFIGURACION: Ajustar $basePath si es necesario
 */

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

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

// Timeout para pruebas HTTP (segundos)
$httpTimeout = 10;

// Tamano maximo aceptable de imagenes (KB)
$maxImagenKB = 500;

// =====================================================================
//  DETECCION DE MODO
// =====================================================================

$esCLI = (php_sapi_name() === 'cli');
$modoRemoto = false;
$urlRemota = '';
$targetPath = '';

if ($esCLI) {
    if (isset($argv[1])) {
        if ($argv[1] === '--url' && isset($argv[2])) {
            $modoRemoto = true;
            $urlRemota = $argv[2];
        } else {
            $targetPath = rtrim($argv[1], '/');
        }
    } else {
        echo "Uso:\n";
        echo "  php test_rendimiento.php /ruta/al/subdominio\n";
        echo "  php test_rendimiento.php --url https://subdominio.dominio.com\n";
        exit(0);
    }
} else {
    // Desde navegador: analizar el subdominio actual
    // Detectar la ruta del subdominio actual desde DOCUMENT_ROOT
    $docRoot = rtrim($_SERVER['DOCUMENT_ROOT'] ?? '', '/');
    if (isset($_GET['sub']) && !empty($_GET['sub'])) {
        $subParam = trim($_GET['sub']);
        // Si viene una URL completa, extraer el subdominio del host
        if (preg_match('#^https?://#i', $subParam)) {
            $parsed = parse_url($subParam);
            if (isset($parsed['host'])) {
                $parts = explode('.', $parsed['host']);
                $subParam = $parts[0]; // primer segmento = nombre subdominio
            }
        }
        // Limpiar: solo nombre de carpeta, sin rutas ni caracteres especiales
        $subParam = basename(preg_replace('/[^a-zA-Z0-9._-]/', '', $subParam));
        if (!empty($subParam)) {
            $targetPath = $basePath . '/' . $subParam;
        }
    } elseif (isset($_GET['path'])) {
        $targetPath = rtrim($_GET['path'], '/');
    } elseif ($docRoot && is_dir($docRoot . '/web')) {
        $targetPath = $docRoot;
    }
}

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

// =====================================================================
//  FUNCIONES DE ANALISIS LOCAL
// =====================================================================

function analizarRecursosExternos($html)
{
    $externos = [];

    // Eliminar contenido dentro de <noscript> para no contar fallbacks como bloqueantes
    $htmlSinNoscript = preg_replace('/<noscript[^>]*>.*?<\/noscript>/si', '', $html);

    // CSS externos (link href)
    if (preg_match_all('/<link[^>]*href\s*=\s*["\']((https?:)?\/\/[^"\']+)["\'][^>]*>/i', $htmlSinNoscript, $m, PREG_SET_ORDER)) {
        foreach ($m as $match) {
            $url = $match[1];
            if (strpos($url, '//') === 0) $url = 'https:' . $url;
            $fullTag = $match[0];
            // Preconnect no es un recurso CSS
            if (stripos($fullTag, 'preconnect') !== false) continue;
            // media="print" onload = carga no bloqueante (optimizado)
            $esNoBloqueante = (stripos($fullTag, 'media="print"') !== false && stripos($fullTag, 'onload') !== false);
            $externos[] = ['tipo' => 'CSS externo', 'url' => $url, 'bloqueante' => !$esNoBloqueante];
        }
    }

    // JS externos (script src)
    if (preg_match_all('/<script[^>]*src\s*=\s*["\']((https?:)?\/\/[^"\']+)["\'][^>]*>/i', $htmlSinNoscript, $m, PREG_SET_ORDER)) {
        foreach ($m as $match) {
            $url = $match[1];
            if (strpos($url, '//') === 0) $url = 'https:' . $url;
            $fullTag = $match[0];
            $tieneAsync = (stripos($fullTag, 'async') !== false);
            $tieneDefer = (stripos($fullTag, 'defer') !== false);
            $externos[] = [
                'tipo' => 'JS externo',
                'url' => $url,
                'bloqueante' => !$tieneAsync && !$tieneDefer,
                'async' => $tieneAsync,
                'defer' => $tieneDefer,
            ];
        }
    }

    return $externos;
}

function analizarRecursosLocales($html, $webPath)
{
    $locales = [];

    // CSS locales
    if (preg_match_all('/<link[^>]*href\s*=\s*["\']([^"\']+\.css)["\'][^>]*>/i', $html, $m, PREG_SET_ORDER)) {
        foreach ($m as $match) {
            $url = $match[1];
            if (preg_match('/^(https?:)?\/\//', $url)) continue; // saltar externos
            $fullTag = $match[0];
            $filePath = $webPath . '/' . ltrim($url, './');
            $size = file_exists($filePath) ? filesize($filePath) : -1;
            // media="print" onload = carga diferida (no bloqueante)
            $diferido = (stripos($fullTag, 'media="print"') !== false && stripos($fullTag, 'onload') !== false);
            $locales[] = ['tipo' => 'CSS', 'archivo' => $url, 'size' => $size, 'diferido' => $diferido];
        }
    }

    // JS locales
    if (preg_match_all('/<script[^>]*src\s*=\s*["\']([^"\']+\.js)["\'][^>]*>/i', $html, $m, PREG_SET_ORDER)) {
        foreach ($m as $match) {
            $url = $match[1];
            if (preg_match('/^(https?:)?\/\//', $url)) continue;
            $filePath = $webPath . '/' . ltrim($url, './');
            $size = file_exists($filePath) ? filesize($filePath) : -1;
            $fullTag = $match[0];
            $tieneAsync = (stripos($fullTag, 'async') !== false);
            $tieneDefer = (stripos($fullTag, 'defer') !== false);
            // jQuery debe cargar bloqueante (otros scripts dependen de el) — no es problema
            $esJquery = (bool) preg_match('/jquery[\.\-]?(min\.)?js$/i', basename($url));
            $locales[] = [
                'tipo' => 'JS',
                'archivo' => $url,
                'size' => $size,
                'bloqueante' => !$tieneAsync && !$tieneDefer,
                'es_jquery' => $esJquery,
            ];
        }
    }

    return $locales;
}

function analizarImagenes($webPath, $maxKB)
{
    $problemas = [];
    $totalSize = 0;
    $totalArchivos = 0;

    $imgDir = $webPath . '/images';
    if (!is_dir($imgDir)) return ['problemas' => [], 'total_size' => 0, 'total_archivos' => 0];

    $iter = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($imgDir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::LEAVES_ONLY
    );

    foreach ($iter as $file) {
        if (!$file->isFile()) continue;
        $ext = strtolower($file->getExtension());
        if (!in_array($ext, ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'ico', 'bmp'])) continue;

        $size = $file->getSize();
        $totalSize += $size;
        $totalArchivos++;
        $sizeKB = round($size / 1024, 1);

        if ($sizeKB > $maxKB) {
            $relativePath = str_replace($webPath . '/', '', $file->getRealPath());
            $relativePath = str_replace('\\', '/', $relativePath);
            $problemas[] = [
                'archivo' => $relativePath,
                'size_kb' => $sizeKB,
                'mensaje' => "Imagen grande: {$sizeKB} KB (limite: {$maxKB} KB)",
            ];
        }
    }

    return [
        'problemas' => $problemas,
        'total_size' => $totalSize,
        'total_archivos' => $totalArchivos,
    ];
}

function analizarHtaccess($webPath)
{
    $resultados = [
        'existe' => false,
        'tiene_compresion' => false,
        'tiene_cache' => false,
        'tiene_rewrite' => false,
        'contenido' => '',
        'problemas' => [],
        'recomendaciones' => [],
    ];

    $htFile = $webPath . '/.htaccess';
    if (!file_exists($htFile)) {
        $resultados['recomendaciones'][] = 'No existe .htaccess - no hay compresion ni cache del navegador configurados';
        return $resultados;
    }

    $resultados['existe'] = true;
    $contenido = file_get_contents($htFile);
    $resultados['contenido'] = $contenido;

    // Compresion GZIP
    if (preg_match('/mod_deflate|AddOutputFilterByType|mod_gzip/i', $contenido)) {
        $resultados['tiene_compresion'] = true;
    } else {
        $resultados['recomendaciones'][] = 'No tiene compresion GZIP configurada (mod_deflate). Los archivos CSS/JS se envian sin comprimir.';
    }

    // Cache del navegador
    if (preg_match('/mod_expires|ExpiresActive|Cache-Control|max-age/i', $contenido)) {
        $resultados['tiene_cache'] = true;
    } else {
        $resultados['recomendaciones'][] = 'No tiene cache del navegador configurado (mod_expires). Los archivos se descargan de nuevo en cada visita.';
    }

    // Rewrite rules
    if (preg_match('/RewriteEngine\s+On/i', $contenido)) {
        $resultados['tiene_rewrite'] = true;

        // Detectar reglas de rewrite que podrian causar redirecciones innecesarias
        if (preg_match_all('/RewriteRule\s+/i', $contenido, $m)) {
            $numReglas = count($m[0]);
            if ($numReglas > 5) {
                $resultados['problemas'][] = "Muchas reglas de rewrite ({$numReglas}). Cada regla agrega latencia al procesamiento.";
            }
        }
    }

    // WordPress leftover
    if (stripos($contenido, 'WordPress') !== false) {
        $resultados['problemas'][] = 'El .htaccess contiene reglas de WordPress que no son necesarias para esta pagina estatica/PHP.';
    }

    return $resultados;
}

function analizarHTML($html)
{
    $problemas = [];

    // Spinner/preloader — solo es problema si los CSS son bloqueantes (no diferidos)
    if (preg_match('/class\s*=\s*["\'][^"\']*spn_hol|spinner|preloader/i', $html)) {
        // Verificar si los CSS pesados (animate, owl, etc.) estan diferidos
        $cssNoCriticos = ['animate', 'owl', 'prettyPhoto', 'font-awesome', 'Pe-icon'];
        $cssBloqueantes = 0;
        foreach ($cssNoCriticos as $css) {
            if (preg_match('/<link[^>]*' . preg_quote($css) . '[^>]*>/i', $html, $cssM)) {
                if (stripos($cssM[0], 'media="print"') === false) {
                    $cssBloqueantes++;
                }
            }
        }
        if ($cssBloqueantes > 0) {
            $problemas[] = [
                'tipo' => 'PRELOADER',
                'mensaje' => "La pagina usa un spinner/preloader con {$cssBloqueantes} CSS pesados cargando de forma bloqueante.",
                'impacto' => 'medio',
                'solucion' => 'Diferir los CSS no criticos con media="print" onload="this.media=\'all\'".',
            ];
        }
    }

    // Scripts en el <head> sin async/defer
    $headContent = '';
    if (preg_match('/<head>(.*?)<\/head>/si', $html, $m)) {
        $headContent = $m[1];
    }
    if (preg_match_all('/<script[^>]*src\s*=\s*["\']([^"\']+)["\'][^>]*>/i', $headContent, $m, PREG_SET_ORDER)) {
        foreach ($m as $match) {
            $fullTag = $match[0];
            $src = $match[1];
            if (stripos($fullTag, 'async') === false && stripos($fullTag, 'defer') === false) {
                $problemas[] = [
                    'tipo' => 'SCRIPT_BLOQUEANTE_HEAD',
                    'mensaje' => "Script bloqueante en <head>: {$src}. Bloquea el renderizado hasta que se descargue.",
                    'impacto' => 'alto',
                    'solucion' => 'Agregar atributo async o defer, o mover al final del body.',
                ];
            }
        }
    }

    // Cantidad de CSS — contar solo los bloqueantes (no los diferidos con media="print")
    $cssBloqCount = 0;
    $cssTotalCount = 0;
    if (preg_match_all('/<link[^>]*\.css[^>]*>/i', $html, $cssMatches)) {
        foreach ($cssMatches[0] as $cssTag) {
            // Saltar noscript fallbacks
            if (preg_match('/<noscript/i', substr($html, 0, strpos($html, $cssTag)))) {
                // Verificar si estamos dentro de un <noscript>
                $posTag = strpos($html, $cssTag);
                $posNoscript = strrpos(substr($html, 0, $posTag), '<noscript');
                $posEndNoscript = strrpos(substr($html, 0, $posTag), '</noscript>');
                if ($posNoscript !== false && ($posEndNoscript === false || $posEndNoscript < $posNoscript)) {
                    continue; // Dentro de <noscript>, no contar
                }
            }
            $cssTotalCount++;
            if (stripos($cssTag, 'media="print"') === false || stripos($cssTag, 'onload') === false) {
                $cssBloqCount++;
            }
        }
    }
    if ($cssBloqCount > 6) {
        $problemas[] = [
            'tipo' => 'MUCHOS_CSS',
            'mensaje' => "Se cargan {$cssBloqCount} archivos CSS de forma bloqueante (de {$cssTotalCount} total). Cada archivo bloqueante es una peticion HTTP que detiene el renderizado.",
            'impacto' => 'medio',
            'solucion' => 'Diferir los CSS no criticos con media="print" onload="this.media=\'all\'" o combinar archivos.',
        ];
    }

    // Cantidad de JS — contar solo los que no tienen defer/async (excluir jQuery que debe ser bloqueante)
    $jsBloqCount = 0;
    $jsTotalCount = 0;
    if (preg_match_all('/<script[^>]*src\s*=\s*["\']([^"\']+)["\'][^>]*>/i', $html, $jsMatches, PREG_SET_ORDER)) {
        foreach ($jsMatches as $jsM) {
            $jsTotalCount++;
            $jsTag = $jsM[0];
            $jsSrc = $jsM[1];
            // jQuery debe ser bloqueante — no contarlo como problema
            if (preg_match('/jquery[\.\-]?(min\.)?js$/i', basename($jsSrc))) continue;
            if (stripos($jsTag, 'defer') === false && stripos($jsTag, 'async') === false) {
                $jsBloqCount++;
            }
        }
    }
    if ($jsBloqCount > 3) {
        $problemas[] = [
            'tipo' => 'MUCHOS_JS',
            'mensaje' => "Se cargan {$jsBloqCount} archivos JavaScript sin defer/async (de {$jsTotalCount} total). Los scripts bloqueantes detienen el renderizado.",
            'impacto' => 'medio',
            'solucion' => 'Agregar defer a los scripts que no son jQuery, o combinar archivos.',
        ];
    }

    // WOW.js — solo es problema si no tiene defer
    if (preg_match('/<script[^>]*wow[^>]*>/i', $html, $wowM)) {
        $wowTag = $wowM[0];
        if (stripos($wowTag, 'defer') === false && stripos($wowTag, 'async') === false) {
            $problemas[] = [
                'tipo' => 'ANIMACIONES',
                'mensaje' => 'WOW.js carga sin defer. Los elementos con clase "wow" son invisibles hasta que WOW.js ejecuta, y bloquea el renderizado.',
                'impacto' => 'medio',
                'solucion' => 'Agregar atributo defer al script de WOW.js.',
            ];
        }
    }

    // Google Fonts - verificar si esta optimizado
    if (preg_match('/fonts\.googleapis\.com/i', $html)) {
        // Verificar si los links de fonts tienen carga no bloqueante
        $fontsBloqueantes = false;
        if (preg_match_all('/<link[^>]*fonts\.googleapis\.com\/css[^>]*>/i', $html, $fontMatches)) {
            foreach ($fontMatches[0] as $fontTag) {
                // Saltar los que estan dentro de <noscript>
                $posTag = strpos($html, $fontTag);
                $posNoscript = strrpos(substr($html, 0, $posTag), '<noscript');
                $posEndNoscript = strrpos(substr($html, 0, $posTag), '</noscript>');
                if ($posNoscript !== false && ($posEndNoscript === false || $posEndNoscript < $posNoscript)) {
                    continue; // Dentro de <noscript>, ignorar
                }
                // Si no tiene media="print" onload, es bloqueante
                if (stripos($fontTag, 'media="print"') === false || stripos($fontTag, 'onload') === false) {
                    $fontsBloqueantes = true;
                    break;
                }
            }
        }

        if ($fontsBloqueantes) {
            // Verificar sub-problemas
            $tieneSwap = (stripos($html, 'display=swap') !== false);
            $tienePreconnect = (stripos($html, 'preconnect') !== false && stripos($html, 'fonts.g') !== false);

            $detalles = 'Google Fonts en <link> bloquea el renderizado.';
            $solucion = '';
            if (!$tienePreconnect) $solucion .= 'Agregar <link rel="preconnect">. ';
            if (!$tieneSwap) $solucion .= 'Agregar &display=swap a la URL. ';
            $solucion .= 'Usar media="print" onload="this.media=\'all\'" para carga no bloqueante.';

            $problemas[] = [
                'tipo' => 'GOOGLE_FONTS_BLOQUEANTE',
                'mensaje' => $detalles,
                'impacto' => 'alto',
                'solucion' => $solucion,
            ];
        }
    }

    // reCAPTCHA — solo es problema si carga de forma directa (no lazy)
    if (preg_match('/<script[^>]*recaptcha\/api\.js[^>]*><\/script>/i', $html)) {
        // Si tiene lazy load (loadRecaptcha, IntersectionObserver), no es problema
        if (stripos($html, 'loadRecaptcha') === false) {
            $problemas[] = [
                'tipo' => 'RECAPTCHA',
                'mensaje' => 'reCAPTCHA se carga directamente en el HTML. Descarga ~500KB de JS de Google al inicio.',
                'impacto' => 'alto',
                'solucion' => 'Cargar reCAPTCHA solo cuando el usuario interactua con el formulario (lazy load).',
            ];
        }
    }

    return $problemas;
}

function medirTiempoHTTP($url, $timeout = 10)
{
    if (!function_exists('curl_init')) {
        return ['error' => 'cURL no disponible'];
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => $timeout,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_USERAGENT => 'SIE-DiagnosticBot/1.0',
        CURLOPT_NOBODY => false,
    ]);

    $body = curl_exec($ch);
    $info = curl_getinfo($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        return ['error' => $error];
    }

    return [
        'url'            => $url,
        'http_code'      => $info['http_code'],
        'total_time'     => round($info['total_time'] * 1000, 1),       // ms
        'dns_time'       => round($info['namelookup_time'] * 1000, 1),  // ms
        'connect_time'   => round($info['connect_time'] * 1000, 1),     // ms
        'ttfb'           => round($info['starttransfer_time'] * 1000, 1), // ms (Time To First Byte)
        'download_size'  => $info['size_download'],
        'content_type'   => $info['content_type'] ?? '',
        'redirect_count' => $info['redirect_count'],
        'body'           => $body,
    ];
}

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

$tiempoInicio = microtime(true);
$diagnostico = [
    'modo'               => $modoRemoto ? 'remoto' : 'local',
    'target'             => $modoRemoto ? $urlRemota : $targetPath,
    'tiene_web'          => false,
    'externos'           => [],
    'locales'            => [],
    'imagenes'           => [],
    'htaccess'           => [],
    'html_problemas'     => [],
    'tiempos_http'       => [],
    'resumen_problemas'  => [],
    'recomendaciones'    => [],
];

if ($modoRemoto) {
    // === MODO REMOTO: Medir tiempos HTTP reales ===
    $resultado = medirTiempoHTTP($urlRemota, $httpTimeout);

    if (isset($resultado['error'])) {
        $diagnostico['resumen_problemas'][] = "Error conectando a {$urlRemota}: {$resultado['error']}";
    } else {
        $diagnostico['tiempos_http'][] = $resultado;

        // Analizar HTML descargado
        if ($resultado['body']) {
            $diagnostico['externos'] = analizarRecursosExternos($resultado['body']);
            $diagnostico['html_problemas'] = analizarHTML($resultado['body']);

            // Medir tiempos de recursos externos criticos
            foreach ($diagnostico['externos'] as $ext) {
                if ($ext['bloqueante']) {
                    $t = medirTiempoHTTP($ext['url'], 5);
                    if (!isset($t['error'])) {
                        $diagnostico['tiempos_http'][] = $t;
                    }
                }
            }
        }
    }

} else {
    // === MODO LOCAL: Analisis de archivos ===
    if (empty($targetPath)) {
        if ($esCLI) {
            echo "ERROR: Especifique la ruta del subdominio.\n";
            echo "Uso: php test_rendimiento.php /ruta/al/subdominio\n";
            exit(1);
        }
    }

    $webPath = $targetPath . '/web';
    $diagnostico['tiene_web'] = is_dir($webPath);

    if ($diagnostico['tiene_web']) {
        // Leer HTML principal
        $htmlFile = $webPath . '/index.html';
        if (!file_exists($htmlFile)) $htmlFile = $webPath . '/index.php';

        if (file_exists($htmlFile)) {
            $html = file_get_contents($htmlFile);

            $diagnostico['externos'] = analizarRecursosExternos($html);
            $diagnostico['locales'] = analizarRecursosLocales($html, $webPath);
            $diagnostico['imagenes'] = analizarImagenes($webPath, $maxImagenKB);
            $diagnostico['htaccess'] = analizarHtaccess($webPath);
            $diagnostico['html_problemas'] = analizarHTML($html);
        }
    }

    // Tambien analizar redireccion raiz (del subdominio, no de web/)
    if (is_dir($targetPath)) {
        $htRoot = $targetPath . '/.htaccess';
        $tieneRewriteDirecto = false;

        if (file_exists($htRoot)) {
            $contenidoHt = file_get_contents($htRoot);

            // Si tiene RewriteRule ^$ web/index.php [L] — redireccion interna optima (OK)
            if (preg_match('/RewriteRule\s+\^\$\s+web\/index\.php/i', $contenidoHt)) {
                $tieneRewriteDirecto = true; // OK, no hay problema
            }
            // Si tiene rewrite de index.html a web/ — redireccion innecesaria
            elseif (preg_match('/RewriteRule.*index\.html.*web/i', $contenidoHt)) {
                $diagnostico['resumen_problemas'][] = '.htaccess raiz tiene rewrite de index.html a web/. Mejor usar: RewriteRule ^$ web/index.php [L]';
            }
        }

        // Solo reportar problemas del index.html si NO hay .htaccess con rewrite directo
        if (!$tieneRewriteDirecto) {
            $indexRoot = $targetPath . '/index.html';
            if (file_exists($indexRoot)) {
                $indexContent = file_get_contents($indexRoot);
                if (preg_match('/meta.*http-equiv.*refresh.*url\s*=\s*web/i', $indexContent)) {
                    $diagnostico['resumen_problemas'][] = 'index.html raiz usa <meta http-equiv="refresh"> para redirigir a web/. Mejor usar .htaccess con RewriteRule ^$ web/index.php [L] para redireccion interna del servidor.';
                }
                if (preg_match('/window\.location\.href\s*=\s*["\']web/i', $indexContent)) {
                    $diagnostico['resumen_problemas'][] = 'index.html raiz usa JavaScript (window.location.href) para redirigir a web/. Mejor usar .htaccess con RewriteRule.';
                }
            }
        }
    }
}

// Generar recomendaciones consolidadas
$recomendaciones = [];

// Contar recursos bloqueantes
$bloqueantes = 0;
foreach ($diagnostico['externos'] as $ext) {
    if (!empty($ext['bloqueante'])) $bloqueantes++;
}
if ($bloqueantes > 0) {
    $recomendaciones[] = [
        'prioridad' => 'ALTA',
        'titulo' => "Eliminar {$bloqueantes} recurso(s) externo(s) bloqueante(s)",
        'detalle' => 'Los recursos externos bloqueantes (Google Fonts, reCAPTCHA, etc.) detienen el renderizado. El navegador no muestra nada hasta que se descargan.',
        'solucion' => "1. Google Fonts: agregar <link rel='preconnect' href='https://fonts.googleapis.com'> y usar &display=swap en la URL.\n2. reCAPTCHA: cargar solo cuando se necesite (lazy load en scroll al formulario).\n3. Scripts externos: agregar async o defer.",
    ];
}

// Redireccion doble
if (count($diagnostico['resumen_problemas']) > 0) {
    foreach ($diagnostico['resumen_problemas'] as $prob) {
        if (stripos($prob, 'redireccion') !== false || stripos($prob, 'redirect') !== false || stripos($prob, 'refresh') !== false) {
            $recomendaciones[] = [
                'prioridad' => 'ALTA',
                'titulo' => 'Eliminar redireccion innecesaria en la raiz',
                'detalle' => $prob,
                'solucion' => "Opcion 1: Usar .htaccess en la raiz con DirectoryIndex web/index.php para evitar la redireccion.\nOpcion 2: Hacer que el archivo raiz index.php incluya directamente web/index.php sin redireccion.\nOpcion 3 (mejor): Colocar un .htaccess raiz:\n  RewriteEngine On\n  RewriteRule ^$ web/index.php [L]\n  Esto hace la redireccion interna sin que el navegador haga un request adicional.",
            ];
        }
    }
}

// Compresion
if (isset($diagnostico['htaccess']['tiene_compresion']) && !$diagnostico['htaccess']['tiene_compresion']) {
    $totalCSS = 0;
    $totalJS = 0;
    foreach ($diagnostico['locales'] as $l) {
        if ($l['size'] > 0) {
            if ($l['tipo'] === 'CSS') $totalCSS += $l['size'];
            else $totalJS += $l['size'];
        }
    }
    $totalKB = round(($totalCSS + $totalJS) / 1024, 0);
    if ($totalKB > 50) {
        $recomendaciones[] = [
            'prioridad' => 'MEDIA',
            'titulo' => 'Habilitar compresion GZIP',
            'detalle' => "Se envian ~{$totalKB} KB de CSS/JS sin comprimir. GZIP puede reducir 60-80%.",
            'solucion' => "Agregar al .htaccess de web/:\n<IfModule mod_deflate.c>\n  AddOutputFilterByType DEFLATE text/html text/css application/javascript\n</IfModule>",
        ];
    }
}

// Cache
if (isset($diagnostico['htaccess']['tiene_cache']) && !$diagnostico['htaccess']['tiene_cache']) {
    $recomendaciones[] = [
        'prioridad' => 'MEDIA',
        'titulo' => 'Configurar cache del navegador',
        'detalle' => 'Sin cache, el navegador descarga todos los CSS, JS e imagenes en cada visita.',
        'solucion' => "Agregar al .htaccess de web/:\n<IfModule mod_expires.c>\n  ExpiresActive On\n  ExpiresByType text/css \"access plus 1 month\"\n  ExpiresByType application/javascript \"access plus 1 month\"\n  ExpiresByType image/png \"access plus 1 year\"\n  ExpiresByType image/jpeg \"access plus 1 year\"\n</IfModule>",
    ];
}

$diagnostico['recomendaciones'] = $recomendaciones;

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

// =====================================================================
//  SALIDA
// =====================================================================

if ($esCLI) {
    echo "=============================================================\n";
    echo " TEST DE RENDIMIENTO - PAGINA WEB\n";
    echo " Fecha: " . date('Y-m-d H:i:s') . "\n";
    echo " Modo: " . ($modoRemoto ? "REMOTO ({$urlRemota})" : "LOCAL ({$targetPath})") . "\n";
    echo "=============================================================\n\n";

    if (!empty($diagnostico['tiempos_http'])) {
        echo "--- TIEMPOS HTTP ---\n";
        foreach ($diagnostico['tiempos_http'] as $t) {
            echo sprintf("  %-60s %6s ms (TTFB: %s ms, DNS: %s ms)\n",
                substr($t['url'], 0, 60), $t['total_time'], $t['ttfb'], $t['dns_time']);
        }
        echo "\n";
    }

    if (!empty($diagnostico['externos'])) {
        echo "--- RECURSOS EXTERNOS (" . count($diagnostico['externos']) . ") ---\n";
        foreach ($diagnostico['externos'] as $ext) {
            $bloq = $ext['bloqueante'] ? '[BLOQUEANTE]' : '[OK]';
            echo "  {$bloq} {$ext['tipo']}: {$ext['url']}\n";
        }
        echo "\n";
    }

    if (!empty($diagnostico['html_problemas'])) {
        echo "--- PROBLEMAS HTML (" . count($diagnostico['html_problemas']) . ") ---\n";
        foreach ($diagnostico['html_problemas'] as $p) {
            echo "  [{$p['impacto']}] {$p['mensaje']}\n";
            if (isset($p['solucion'])) echo "    Solucion: {$p['solucion']}\n";
        }
        echo "\n";
    }

    if (!empty($recomendaciones)) {
        echo "=== RECOMENDACIONES ===\n\n";
        foreach ($recomendaciones as $i => $r) {
            echo ($i + 1) . ". [{$r['prioridad']}] {$r['titulo']}\n";
            echo "   {$r['detalle']}\n";
            echo "   SOLUCION: {$r['solucion']}\n\n";
        }
    }

    echo "Tiempo diagnostico: {$tiempoDiag}s\n";

} else {
    // === SALIDA HTML ===
    ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Test de Rendimiento - Pagina 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: 1100px; margin: 0 auto; }
    h1 { font-size: 1.5em; color: #0f172a; margin-bottom: 4px; }
    .subtitle { color: #64748b; font-size: 0.9em; margin-bottom: 20px; }
    .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.15em; margin-bottom: 12px; }
    .problem-card { border-radius: 8px; padding: 14px; margin-bottom: 10px; }
    .problem-alto { background: #fef2f2; border: 1px solid #fecaca; }
    .problem-medio { background: #fffbeb; border: 1px solid #fde68a; }
    .problem-bajo { background: #f0f9ff; border: 1px solid #bae6fd; }
    .problem-card .label { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.78em; font-weight: 700; margin-right: 6px; }
    .label-alto { background: #fee2e2; color: #991b1b; }
    .label-medio { background: #fef3c7; color: #92400e; }
    .label-bajo { background: #dbeafe; color: #1e40af; }
    .problem-card .msg { font-size: 0.92em; margin-top: 4px; }
    .problem-card .sol { font-size: 0.85em; color: #475569; margin-top: 6px; background: #f8fafc; padding: 8px; border-radius: 4px; white-space: pre-wrap; }
    .rec-card { background: #eff6ff; border: 1px solid #93c5fd; border-radius: 10px; padding: 16px; margin-bottom: 12px; }
    .rec-card h3 { font-size: 1em; color: #1e40af; margin-bottom: 6px; }
    .rec-card .detalle { font-size: 0.88em; color: #475569; margin-bottom: 8px; }
    .rec-card .solucion { font-size: 0.85em; background: #f0f9ff; padding: 10px; border-radius: 6px; white-space: pre-wrap; font-family: monospace; }
    .rec-card .badge-pri { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.75em; font-weight: 700; margin-right: 6px; }
    .pri-alta { background: #fee2e2; color: #991b1b; }
    .pri-media { background: #fef3c7; color: #92400e; }
    table { width: 100%; border-collapse: collapse; font-size: 0.88em; }
    table th { text-align: left; padding: 8px; border-bottom: 2px solid #e2e8f0; color: #475569; }
    table td { padding: 8px; border-bottom: 1px solid #f1f5f9; }
    code { background: #f1f5f9; padding: 1px 5px; border-radius: 3px; font-size: 0.9em; }
    .badge { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 0.78em; font-weight: 600; }
    .badge-red { background: #fee2e2; color: #991b1b; }
    .badge-green { background: #dcfce7; color: #166534; }
    .badge-yellow { background: #fef3c7; color: #92400e; }
    .form-bar { margin-bottom: 20px; background: #fff; border-radius: 10px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
    .form-bar input { padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.9em; flex: 1; min-width: 200px; }
    .form-bar button { padding: 8px 16px; background: #2563eb; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9em; }
    .form-bar button:hover { background: #1d4ed8; }
</style>
</head>
<body>
<div class="container">
    <h1>&#9889; Test de Rendimiento - Pagina Web</h1>
    <p class="subtitle">
        Modo: <?= $diagnostico['modo'] ?> |
        Target: <code><?= htmlspecialchars($diagnostico['target'] ?: 'no especificado') ?></code> |
        Tiempo diagnostico: <?= $tiempoDiag ?>s
    </p>

    <!-- Formulario para analizar otro subdominio -->
    <div class="form-bar">
        <form method="get" style="display:flex;gap:10px;width:100%;align-items:center;flex-wrap:wrap;">
            <label style="font-size:0.88em;color:#64748b;">Subdominio:</label>
            <input type="text" name="sub" placeholder="Nombre o URL (ej: aywgonzalez o https://aywgonzalez.sistemavirtualdegestion.com)" value="<?= htmlspecialchars($_GET['sub'] ?? '') ?>">
            <button type="submit">Analizar</button>
        </form>
    </div>

    <?php if (empty($targetPath) && !$modoRemoto): ?>
    <div class="section" style="text-align:center;color:#64748b;padding:40px;">
        <p>Ingrese el nombre de un subdominio para analizar su pagina web.</p>
        <p style="font-size:0.85em;margin-top:8px;">Base: <code><?= htmlspecialchars($basePath) ?></code></p>
    </div>
    <?php else: ?>

    <?php if (!empty($diagnostico['tiempos_http'])): ?>
    <!-- TIEMPOS HTTP -->
    <div class="section">
        <h2>&#9200; Tiempos de respuesta HTTP</h2>
        <table>
            <tr><th>URL</th><th>Codigo</th><th>Total</th><th>TTFB</th><th>DNS</th><th>Tamano</th></tr>
            <?php foreach ($diagnostico['tiempos_http'] as $t): ?>
            <tr>
                <td><code style="word-break:break-all;font-size:0.82em;"><?= htmlspecialchars($t['url']) ?></code></td>
                <td><span class="badge <?= $t['http_code'] == 200 ? 'badge-green' : 'badge-red' ?>"><?= $t['http_code'] ?></span></td>
                <td><strong><?= $t['total_time'] ?> ms</strong></td>
                <td><?= $t['ttfb'] ?> ms</td>
                <td><?= $t['dns_time'] ?> ms</td>
                <td><?= round($t['download_size'] / 1024, 1) ?> KB</td>
            </tr>
            <?php endforeach; ?>
        </table>
    </div>
    <?php endif; ?>

    <?php if (!empty($diagnostico['html_problemas'])): ?>
    <!-- PROBLEMAS HTML -->
    <div class="section">
        <h2>&#9888;&#65039; Problemas detectados en HTML (<?= count($diagnostico['html_problemas']) ?>)</h2>
        <?php foreach ($diagnostico['html_problemas'] as $p): ?>
            <div class="problem-card problem-<?= $p['impacto'] ?>">
                <span class="label label-<?= $p['impacto'] ?>"><?= strtoupper($p['impacto']) ?></span>
                <span class="badge"><?= htmlspecialchars($p['tipo']) ?></span>
                <div class="msg"><?= htmlspecialchars($p['mensaje']) ?></div>
                <?php if (isset($p['solucion'])): ?>
                    <div class="sol"><strong>Solucion:</strong> <?= htmlspecialchars($p['solucion']) ?></div>
                <?php endif; ?>
            </div>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php if (!empty($diagnostico['resumen_problemas'])): ?>
    <div class="section">
        <h2>&#128680; Problemas de infraestructura</h2>
        <?php foreach ($diagnostico['resumen_problemas'] as $prob): ?>
            <div class="problem-card problem-alto">
                <span class="label label-alto">INFRAESTRUCTURA</span>
                <div class="msg"><?= htmlspecialchars($prob) ?></div>
            </div>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php if (!empty($diagnostico['externos'])): ?>
    <!-- RECURSOS EXTERNOS -->
    <div class="section">
        <h2>&#127760; Recursos externos (<?= count($diagnostico['externos']) ?>)</h2>
        <table>
            <tr><th>Tipo</th><th>URL</th><th>Estado</th></tr>
            <?php foreach ($diagnostico['externos'] as $ext): ?>
            <tr>
                <td><?= htmlspecialchars($ext['tipo']) ?></td>
                <td><code style="word-break:break-all;font-size:0.82em;"><?= htmlspecialchars($ext['url']) ?></code></td>
                <td>
                    <?php if ($ext['bloqueante']): ?>
                        <span class="badge badge-red">BLOQUEANTE</span>
                    <?php else: ?>
                        <span class="badge badge-green">OK (async/defer)</span>
                    <?php endif; ?>
                </td>
            </tr>
            <?php endforeach; ?>
        </table>
    </div>
    <?php endif; ?>

    <?php if (!empty($diagnostico['locales'])): ?>
    <!-- RECURSOS LOCALES -->
    <div class="section">
        <h2>&#128193; Recursos locales CSS/JS (<?= count($diagnostico['locales']) ?>)</h2>
        <?php
        $totalLocalSize = 0;
        foreach ($diagnostico['locales'] as $l) { if ($l['size'] > 0) $totalLocalSize += $l['size']; }
        ?>
        <p style="font-size:0.88em;color:#64748b;margin-bottom:10px;">Total: <?= round($totalLocalSize / 1024, 1) ?> KB</p>
        <table>
            <tr><th>Tipo</th><th>Archivo</th><th>Tamano</th><th>Bloqueante</th></tr>
            <?php foreach ($diagnostico['locales'] as $l): ?>
            <tr>
                <td><?= htmlspecialchars($l['tipo']) ?></td>
                <td><code><?= htmlspecialchars($l['archivo']) ?></code></td>
                <td><?= $l['size'] > 0 ? round($l['size'] / 1024, 1) . ' KB' : '<span style="color:#dc2626;">No existe</span>' ?></td>
                <td>
                    <?php if (isset($l['bloqueante']) && $l['bloqueante'] && !empty($l['es_jquery'])): ?>
                        <span class="badge" style="background:#e0e7ff;color:#3730a3;">Requerido</span>
                    <?php elseif (isset($l['bloqueante']) && $l['bloqueante']): ?>
                        <span class="badge badge-yellow">Bloqueante</span>
                    <?php elseif (isset($l['diferido']) && $l['diferido']): ?>
                        <span class="badge badge-green">diferido</span>
                    <?php elseif (isset($l['bloqueante'])): ?>
                        <span class="badge badge-green">async/defer</span>
                    <?php else: ?>
                        -
                    <?php endif; ?>
                </td>
            </tr>
            <?php endforeach; ?>
        </table>
    </div>
    <?php endif; ?>

    <?php if (!empty($diagnostico['imagenes']['problemas'])): ?>
    <!-- IMAGENES GRANDES -->
    <div class="section">
        <h2>&#128248; Imagenes grandes</h2>
        <p style="font-size:0.88em;color:#64748b;margin-bottom:10px;">
            Total imagenes: <?= $diagnostico['imagenes']['total_archivos'] ?> |
            Tamano total: <?= round($diagnostico['imagenes']['total_size'] / 1024, 0) ?> KB |
            Limite: <?= $maxImagenKB ?> KB
        </p>
        <table>
            <tr><th>Archivo</th><th>Tamano</th></tr>
            <?php foreach ($diagnostico['imagenes']['problemas'] as $img): ?>
            <tr>
                <td><code><?= htmlspecialchars($img['archivo']) ?></code></td>
                <td><span class="badge badge-red"><?= $img['size_kb'] ?> KB</span></td>
            </tr>
            <?php endforeach; ?>
        </table>
    </div>
    <?php endif; ?>

    <?php if (!empty($recomendaciones)): ?>
    <!-- RECOMENDACIONES -->
    <div class="section">
        <h2>&#128161; Recomendaciones</h2>
        <?php foreach ($recomendaciones as $i => $r): ?>
            <div class="rec-card">
                <h3>
                    <span class="badge-pri <?= $r['prioridad'] === 'ALTA' ? 'pri-alta' : 'pri-media' ?>"><?= $r['prioridad'] ?></span>
                    <?= ($i + 1) ?>. <?= htmlspecialchars($r['titulo']) ?>
                </h3>
                <div class="detalle"><?= htmlspecialchars($r['detalle']) ?></div>
                <div class="solucion"><?= htmlspecialchars($r['solucion']) ?></div>
            </div>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php endif; // fin de target especificado ?>
</div>
</body>
</html>
    <?php
}
