<?php
/**
 * VERIFICADOR DE ENLACES DE SUBDOMINIOS
 * ======================================
 * Escanea todos los subdominios en public_html y verifica que los
 * hipervinculos a doku.php en las paginas web (web/index.html, web/index.php)
 * apunten correctamente al subdominio y dominio esperado.
 *
 * Detecta dos tipos de errores:
 *   ERROR 1 (SUBDOMINIO): El nombre del subdominio en el href no coincide
 *           con el nombre real de la carpeta. Ej: carpeta "nombrea" pero
 *           href apunta a "nombreb.dominio.com/doku.php"
 *
 *   ERROR 2 (DOMINIO):    El dominio base en el href no coincide con el
 *           dominio esperado. Ej: deberia ser "sistemavirtualdegestion.com"
 *           pero usa "systemsie.site"
 *
 * USO: Subir a la raiz del servidor y ejecutar desde el navegador.
 *      Tambien puede ejecutarse via CLI: php verificar_enlaces.php
 *
 * CONFIGURACION: Ajustar las variables $basePath y $dominiosValidos
 */

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

/**
 * Genera el contenido correcto del .htaccess segun si tiene web/ o no
 */
function generarHtaccessCorrecto($tieneWeb)
{
    if ($tieneWeb) {
        return "# SIE - Redirect raiz a pagina web\n"
             . "<IfModule mod_rewrite.c>\n"
             . "RewriteEngine On\n"
             . "RewriteRule ^$ web/index.php [L]\n"
             . "</IfModule>\n";
    } else {
        return "# SIE - Redirect raiz a DokuWiki (sistema sin pagina web)\n"
             . "<IfModule mod_rewrite.c>\n"
             . "RewriteEngine On\n"
             . "RewriteRule ^$ doku.php [L]\n"
             . "</IfModule>\n";
    }
}

/**
 * Genera el contenido correcto del index.html raiz segun si tiene web/ o no
 */
function generarIndexHtmlCorrecto($tieneWeb)
{
    $destino = $tieneWeb ? 'web/index.php' : 'doku.php';
    return "<!DOCTYPE html>\n"
         . "<html>\n"
         . "<head>\n"
         . "<meta charset=\"UTF-8\">\n"
         . "<meta http-equiv=\"refresh\" content=\"0; url={$destino}\">\n"
         . "<script>window.location.href = \"{$destino}\";</script>\n"
         . "</head>\n"
         . "<body></body>\n"
         . "</html>\n";
}

/**
 * Corrige .htaccess e index.html de un subdominio
 * Retorna array con resultado de la correccion
 */
function corregirSubdominio($basePath, $carpeta)
{
    $subPath = $basePath . '/' . $carpeta;
    $resultado = [
        'carpeta' => $carpeta,
        'corregidos' => [],
        'errores_fix' => [],
    ];

    // Verificar que es un subdominio valido
    if (!file_exists($subPath . '/doku.php')) {
        $resultado['errores_fix'][] = "No es un subdominio valido (no tiene doku.php)";
        return $resultado;
    }

    $tieneWeb = is_dir($subPath . '/web');

    // --- Corregir .htaccess ---
    $htaccessPath = $subPath . '/.htaccess';
    $htaccessCorrecto = generarHtaccessCorrecto($tieneWeb);
    $htaccessActual = @file_get_contents($htaccessPath);

    // Normalizar para comparar (quitar espacios extra y \r)
    $normalizar = function($s) {
        return trim(str_replace("\r", "", $s));
    };

    if ($htaccessActual === false || $normalizar($htaccessActual) !== $normalizar($htaccessCorrecto)) {
        if (@file_put_contents($htaccessPath, $htaccessCorrecto) !== false) {
            $resultado['corregidos'][] = '.htaccess';
        } else {
            $resultado['errores_fix'][] = "No se pudo escribir .htaccess (permisos?)";
        }
    }

    // --- Corregir index.html raiz ---
    $indexPath = $subPath . '/index.html';
    $indexCorrecto = generarIndexHtmlCorrecto($tieneWeb);
    $indexActual = @file_get_contents($indexPath);

    if ($indexActual === false || $normalizar($indexActual) !== $normalizar($indexCorrecto)) {
        if (@file_put_contents($indexPath, $indexCorrecto) !== false) {
            $resultado['corregidos'][] = 'index.html';
        } else {
            $resultado['errores_fix'][] = "No se pudo escribir index.html (permisos?)";
        }
    }

    return $resultado;
}

// =====================================================================
//  HANDLER AJAX DE CORRECCION
// =====================================================================

if (isset($_GET['action']) && $_GET['action'] === 'fix') {
    header('Content-Type: application/json; charset=UTF-8');

    $basePath_fix = '/home/systeng3/public_html';
    $modo = isset($_GET['modo']) ? $_GET['modo'] : '';
    $carpeta = isset($_GET['carpeta']) ? basename($_GET['carpeta']) : '';

    $respuesta = ['ok' => false, 'resultados' => [], 'mensaje' => ''];

    if ($modo === 'uno' && !empty($carpeta)) {
        // Corregir un solo subdominio
        $r = corregirSubdominio($basePath_fix, $carpeta);
        $respuesta['resultados'][] = $r;
        if (!empty($r['corregidos'])) {
            $respuesta['ok'] = true;
            $respuesta['mensaje'] = "{$carpeta}: corregido " . implode(', ', $r['corregidos']);
        } elseif (!empty($r['errores_fix'])) {
            $respuesta['mensaje'] = "{$carpeta}: " . implode(', ', $r['errores_fix']);
        } else {
            $respuesta['ok'] = true;
            $respuesta['mensaje'] = "{$carpeta}: ya estaba correcto";
        }
    } elseif ($modo === 'todos') {
        // Corregir todos los subdominios
        $excluir_fix = ['.', '..', 'cgi-bin', '.well-known', '.trash', '.htaccess', 'respaldo', 'diagnosticos', 'tmp', 'error_log'];
        $carpetas_fix = @scandir($basePath_fix);
        $totalCorregidos = 0;
        $totalFallidos = 0;

        if ($carpetas_fix) {
            foreach ($carpetas_fix as $c) {
                if (in_array($c, $excluir_fix)) continue;
                if (!is_dir($basePath_fix . '/' . $c)) continue;
                if (!file_exists($basePath_fix . '/' . $c . '/doku.php')) continue;

                $r = corregirSubdominio($basePath_fix, $c);
                $respuesta['resultados'][] = $r;
                if (!empty($r['corregidos'])) $totalCorregidos++;
                if (!empty($r['errores_fix'])) $totalFallidos++;
            }
        }

        $respuesta['ok'] = ($totalFallidos === 0);
        $respuesta['mensaje'] = "Corregidos: {$totalCorregidos} | Fallidos: {$totalFallidos} | Total: " . count($respuesta['resultados']);
    } else {
        $respuesta['mensaje'] = "Parametros invalidos. Use ?action=fix&modo=uno&carpeta=nombre o ?action=fix&modo=todos";
    }

    echo json_encode($respuesta, JSON_UNESCAPED_UNICODE);
    exit;
}

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

// Ruta base donde estan los subdominios (public_html del servidor)
$basePath = '/home/systeng3/public_html';

// Dominios validos - los subdominios deben apuntar a uno de estos
$dominiosValidos = [
    'sistemavirtualdegestion.com',
    'systemsie.site',
    'susprofesionales.com',
    'sieasesorias.com',
    'gestioncontrolada.com',
];

// Dominio principal esperado (el que deberian usar la mayoria)
// Dejar vacio para no verificar dominio especifico, solo que sea uno de $dominiosValidos
$dominioPrincipal = '';

// Carpetas a excluir del escaneo (no son subdominios)
$excluir = [
    '.', '..', 'cgi-bin', '.well-known', '.trash', '.htaccess',
    'respaldo', 'diagnosticos', 'tmp', 'error_log',
];

// =====================================================================
//  LOGICA PRINCIPAL
// =====================================================================

$esCLI = (php_sapi_name() === 'cli');

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

// Funciones de utilidad
function extraerHrefsDokuphp($contenido)
{
    $hrefs = [];
    // Buscar todos los href que contengan doku.php
    if (preg_match_all('/href\s*=\s*["\']([^"\']*doku\.php[^"\']*)["\']/', $contenido, $matches)) {
        $hrefs = $matches[1];
    }
    return $hrefs;
}

function parsearUrl($href)
{
    $parsed = parse_url($href);
    $result = [
        'original' => $href,
        'subdominio' => null,
        'dominio' => null,
        'dominio_completo' => null,
    ];

    if (isset($parsed['host'])) {
        $host = $parsed['host'];
        $result['dominio_completo'] = $host;

        // Separar subdominio del dominio base
        // Ej: "nombrea.sistemavirtualdegestion.com" => sub="nombrea", dom="sistemavirtualdegestion.com"
        $parts = explode('.', $host);
        if (count($parts) >= 3) {
            $result['subdominio'] = $parts[0];
            $result['dominio'] = implode('.', array_slice($parts, 1));
        } elseif (count($parts) === 2) {
            // Sin subdominio, solo dominio base
            $result['dominio'] = $host;
        }
    }

    return $result;
}

function verificarSubdominio($basePath, $carpeta, $dominiosValidos, $dominioPrincipal)
{
    $resultado = [
        'carpeta'    => $carpeta,
        'tiene_web'  => false,
        'archivos'   => [],
        'hrefs'      => [],
        'errores'    => [],
        'advertencias' => [],
    ];

    $subPath = $basePath . '/' . $carpeta;

    // Verificar si tiene carpeta web/
    $webPath = $subPath . '/web';
    if (is_dir($webPath)) {
        $resultado['tiene_web'] = true;
    }

    // Archivos a revisar (en orden de prioridad)
    $archivosRevisar = [];

    // Si tiene web/, revisar web/index.html y web/index.php
    if ($resultado['tiene_web']) {
        if (file_exists($webPath . '/index.html')) {
            $archivosRevisar[] = 'web/index.html';
        }
        if (file_exists($webPath . '/index.php')) {
            $archivosRevisar[] = 'web/index.php';
        }
    }

    // Tambien revisar index.html raiz (podria tener hrefs directos)
    if (file_exists($subPath . '/index.html')) {
        $archivosRevisar[] = 'index.html';
    }

    $resultado['archivos'] = $archivosRevisar;

    if (empty($archivosRevisar)) {
        return $resultado;
    }

    // Leer cada archivo y extraer hrefs a doku.php
    $hrefsEncontrados = [];
    foreach ($archivosRevisar as $archivo) {
        $contenido = @file_get_contents($subPath . '/' . $archivo);
        if ($contenido === false) continue;

        $hrefs = extraerHrefsDokuphp($contenido);
        foreach ($hrefs as $href) {
            $hrefsEncontrados[] = [
                'archivo' => $archivo,
                'href'    => $href,
            ];
        }
    }

    $resultado['hrefs'] = $hrefsEncontrados;

    if (empty($hrefsEncontrados)) {
        // Si tiene web/ pero no tiene href a doku.php, es una advertencia
        if ($resultado['tiene_web']) {
            $resultado['advertencias'][] = 'Tiene carpeta web/ pero no se encontro ningun href a doku.php';
        }
        return $resultado;
    }

    // Verificar cada href encontrado
    foreach ($hrefsEncontrados as $info) {
        $parsed = parsearUrl($info['href']);

        if ($parsed['subdominio'] === null && $parsed['dominio'] === null) {
            // URL relativa (ej: "doku.php" sin dominio) - OK, no hay error
            continue;
        }

        // ERROR 1: Subdominio no coincide con nombre de carpeta
        if ($parsed['subdominio'] !== null && $parsed['subdominio'] !== $carpeta) {
            $resultado['errores'][] = [
                'tipo'     => 'ERROR_SUBDOMINIO',
                'archivo'  => $info['archivo'],
                'href'     => $info['href'],
                'esperado' => $carpeta,
                'actual'   => $parsed['subdominio'],
                'mensaje'  => "Subdominio incorrecto: carpeta es '{$carpeta}' pero href apunta a '{$parsed['subdominio']}'",
            ];
        }

        // ERROR 2: Dominio no es uno de los validos
        if ($parsed['dominio'] !== null && !in_array($parsed['dominio'], $dominiosValidos)) {
            $resultado['errores'][] = [
                'tipo'     => 'ERROR_DOMINIO',
                'archivo'  => $info['archivo'],
                'href'     => $info['href'],
                'esperado' => implode(' o ', $dominiosValidos),
                'actual'   => $parsed['dominio'],
                'mensaje'  => "Dominio no reconocido: '{$parsed['dominio']}' no esta en la lista de dominios validos",
            ];
        }

        // ADVERTENCIA: Si hay dominio principal definido y no lo usa
        if (!empty($dominioPrincipal) && $parsed['dominio'] !== null && $parsed['dominio'] !== $dominioPrincipal) {
            // Solo advertencia si el dominio ES valido pero no es el principal
            if (in_array($parsed['dominio'], $dominiosValidos)) {
                $resultado['advertencias'][] = "Usa dominio '{$parsed['dominio']}' en vez del principal '{$dominioPrincipal}' en {$info['archivo']}";
            }
        }
    }

    // =====================================================================
    //  VERIFICAR .htaccess e index.html RAIZ
    // =====================================================================
    // Reglas:
    //   SIN web/ => .htaccess redirige a doku.php, index.html redirige a doku.php
    //   CON web/ => .htaccess redirige a web/index.php, index.html redirige a web/index.php

    $destinoEsperado = $resultado['tiene_web'] ? 'web/index.php' : 'doku.php';
    $tipoSistema = $resultado['tiene_web'] ? 'con pagina web' : 'sin pagina web';

    // --- Verificar .htaccess ---
    $htaccessPath = $subPath . '/.htaccess';
    if (file_exists($htaccessPath)) {
        $htaccessContent = @file_get_contents($htaccessPath);
        if ($htaccessContent !== false) {
            // Buscar RewriteRule que redirige la raiz (^$)
            if (preg_match('/RewriteRule\s+\^\$\s+(\S+)/m', $htaccessContent, $mHt)) {
                $destinoActualHt = $mHt[1];
                // Limpiar flags [L] etc
                $destinoActualHt = preg_replace('/\s*\[.*\]$/', '', $destinoActualHt);

                if ($destinoActualHt !== $destinoEsperado) {
                    $resultado['errores'][] = [
                        'tipo'     => 'ERROR_HTACCESS_DESTINO',
                        'archivo'  => '.htaccess',
                        'href'     => $destinoActualHt,
                        'esperado' => $destinoEsperado,
                        'actual'   => $destinoActualHt,
                        'mensaje'  => "Sistema {$tipoSistema}: .htaccess redirige a '{$destinoActualHt}' pero deberia redirigir a '{$destinoEsperado}'",
                    ];
                }
            } else {
                $resultado['advertencias'][] = ".htaccess existe pero no tiene RewriteRule para raiz (^$)";
            }

            // Verificar que NO tenga regla para index.html (causa conflicto con el archivo fisico)
            if (preg_match('/RewriteRule\s+\^index/', $htaccessContent)) {
                $resultado['advertencias'][] = ".htaccess tiene RewriteRule para index.html - puede causar conflicto con el archivo fisico index.html";
            }
        }
    } else {
        $resultado['errores'][] = [
            'tipo'     => 'ERROR_HTACCESS_FALTANTE',
            'archivo'  => '.htaccess',
            'href'     => '',
            'esperado' => $destinoEsperado,
            'actual'   => '(no existe)',
            'mensaje'  => "Sistema {$tipoSistema}: falta .htaccess en la raiz del subdominio",
        ];
    }

    // --- Verificar index.html raiz (redirect/fallback) ---
    $indexPath = $subPath . '/index.html';
    if (file_exists($indexPath)) {
        $indexContent = @file_get_contents($indexPath);
        if ($indexContent !== false) {
            // Buscar meta http-equiv refresh
            $indexDestinoOk = false;
            if (preg_match('/content\s*=\s*["\'][^"\']*url\s*=\s*([^"\';\s]+)/i', $indexContent, $mMeta)) {
                $destinoMeta = trim($mMeta[1]);
                if ($destinoMeta !== $destinoEsperado) {
                    $resultado['errores'][] = [
                        'tipo'     => 'ERROR_INDEX_DESTINO',
                        'archivo'  => 'index.html',
                        'href'     => $destinoMeta,
                        'esperado' => $destinoEsperado,
                        'actual'   => $destinoMeta,
                        'mensaje'  => "Sistema {$tipoSistema}: index.html meta-refresh apunta a '{$destinoMeta}' pero deberia apuntar a '{$destinoEsperado}'",
                    ];
                } else {
                    $indexDestinoOk = true;
                }
            }

            // Buscar window.location en JS
            if (preg_match('/window\.location\.href\s*=\s*["\']([^"\']+)["\']/', $indexContent, $mJs)) {
                $destinoJs = trim($mJs[1]);
                if ($destinoJs !== $destinoEsperado) {
                    $resultado['errores'][] = [
                        'tipo'     => 'ERROR_INDEX_DESTINO',
                        'archivo'  => 'index.html (JS)',
                        'href'     => $destinoJs,
                        'esperado' => $destinoEsperado,
                        'actual'   => $destinoJs,
                        'mensaje'  => "Sistema {$tipoSistema}: index.html JS redirect apunta a '{$destinoJs}' pero deberia apuntar a '{$destinoEsperado}'",
                    ];
                } else {
                    $indexDestinoOk = true;
                }
            }

            // Si no tiene ningun redirect
            if (!preg_match('/meta\s+http-equiv\s*=\s*["\']refresh/i', $indexContent) &&
                !preg_match('/window\.location/i', $indexContent)) {
                $resultado['advertencias'][] = "index.html existe pero no tiene redirect (ni meta-refresh ni JS)";
            }
        }
    } else {
        $resultado['errores'][] = [
            'tipo'     => 'ERROR_INDEX_FALTANTE',
            'archivo'  => 'index.html',
            'href'     => '',
            'esperado' => $destinoEsperado,
            'actual'   => '(no existe)',
            'mensaje'  => "Sistema {$tipoSistema}: falta index.html en la raiz del subdominio",
        ];
    }

    // Verificar tambien conf/local.php y conf/local_act.php para baseurl
    foreach (['conf/local.php', 'conf/local_act.php'] as $confFile) {
        $confPath = $subPath . '/' . $confFile;
        if (!file_exists($confPath)) continue;

        $confContent = @file_get_contents($confPath);
        if ($confContent === false) continue;

        if (preg_match("/\\\$conf\['baseurl'\]\s*=\s*'([^']+)'/", $confContent, $m)) {
            $baseUrl = $m[1];
            $parsedConf = parsearUrl($baseUrl);

            if ($parsedConf['subdominio'] !== null && $parsedConf['subdominio'] !== $carpeta) {
                $resultado['errores'][] = [
                    'tipo'     => 'ERROR_SUBDOMINIO_CONFIG',
                    'archivo'  => $confFile,
                    'href'     => $baseUrl,
                    'esperado' => $carpeta,
                    'actual'   => $parsedConf['subdominio'],
                    'mensaje'  => "baseurl en {$confFile}: subdominio '{$parsedConf['subdominio']}' no coincide con carpeta '{$carpeta}'",
                ];
            }

            if ($parsedConf['dominio'] !== null && !in_array($parsedConf['dominio'], $dominiosValidos)) {
                $resultado['errores'][] = [
                    'tipo'     => 'ERROR_DOMINIO_CONFIG',
                    'archivo'  => $confFile,
                    'href'     => $baseUrl,
                    'esperado' => implode(' o ', $dominiosValidos),
                    'actual'   => $parsedConf['dominio'],
                    'mensaje'  => "baseurl en {$confFile}: dominio '{$parsedConf['dominio']}' no esta en lista valida",
                ];
            }
        }
    }

    return $resultado;
}

// =====================================================================
//  EJECUCION DEL ESCANEO
// =====================================================================

$tiempoInicio = microtime(true);

// Verificar que existe el directorio base
if (!is_dir($basePath)) {
    $msg = "ERROR: No se encuentra el directorio base: {$basePath}\n";
    $msg .= "Ajuste la variable \$basePath en la configuracion del script.\n";
    if ($esCLI) {
        echo $msg;
    } else {
        echo "<pre style='color:red;'>" . htmlspecialchars($msg) . "</pre>";
    }
    exit(1);
}

// Listar carpetas (subdominios)
$carpetas = @scandir($basePath);
if (!$carpetas) {
    echo $esCLI ? "ERROR: No se puede leer {$basePath}\n" : "<pre>ERROR: No se puede leer {$basePath}</pre>";
    exit(1);
}

$resultados = [];
$totalErrores = 0;
$totalAdvertencias = 0;
$totalConWeb = 0;
$totalSinWeb = 0;
$totalConHrefs = 0;

foreach ($carpetas as $carpeta) {
    if (in_array($carpeta, $excluir)) continue;
    if (!is_dir($basePath . '/' . $carpeta)) continue;

    // Verificar que es un subdominio (tiene doku.php)
    if (!file_exists($basePath . '/' . $carpeta . '/doku.php')) continue;

    $r = verificarSubdominio($basePath, $carpeta, $dominiosValidos, $dominioPrincipal);
    $resultados[] = $r;

    if ($r['tiene_web']) $totalConWeb++;
    else $totalSinWeb++;
    if (!empty($r['hrefs'])) $totalConHrefs++;
    $totalErrores += count($r['errores']);
    $totalAdvertencias += count($r['advertencias']);
}

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

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

if ($esCLI) {
    // === SALIDA CLI ===
    echo "=============================================================\n";
    echo " VERIFICADOR DE ENLACES DE SUBDOMINIOS\n";
    echo " Fecha: " . date('Y-m-d H:i:s') . "\n";
    echo "=============================================================\n\n";

    echo "Resumen:\n";
    echo "  Subdominios escaneados: " . count($resultados) . "\n";
    echo "  Con pagina web (web/): {$totalConWeb}\n";
    echo "  Sin pagina web:        {$totalSinWeb}\n";
    echo "  Con hrefs a doku.php:  {$totalConHrefs}\n";
    echo "  ERRORES encontrados:   {$totalErrores}\n";
    echo "  Advertencias:          {$totalAdvertencias}\n";
    echo "  Tiempo de escaneo:     {$tiempoTotal}s\n\n";

    if ($totalErrores > 0) {
        echo "=== ERRORES ===\n\n";
        foreach ($resultados as $r) {
            if (empty($r['errores'])) continue;
            echo "--- {$r['carpeta']} ---\n";
            foreach ($r['errores'] as $e) {
                echo "  [{$e['tipo']}] {$e['mensaje']}\n";
                echo "    Archivo: {$e['archivo']}\n";
                echo "    Href:    {$e['href']}\n";
                echo "    Esperado: {$e['esperado']}\n";
                echo "    Actual:   {$e['actual']}\n\n";
            }
        }
    }

    if ($totalAdvertencias > 0) {
        echo "=== ADVERTENCIAS ===\n\n";
        foreach ($resultados as $r) {
            if (empty($r['advertencias'])) continue;
            echo "--- {$r['carpeta']} ---\n";
            foreach ($r['advertencias'] as $adv) {
                echo "  [ADVERTENCIA] {$adv}\n";
            }
            echo "\n";
        }
    }

    if ($totalErrores === 0 && $totalAdvertencias === 0) {
        echo "Todos los enlaces estan correctos.\n";
    }

} else {
    // === SALIDA HTML ===
    ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Verificador de Enlaces - Subdominios 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: 1200px; margin: 0 auto; }
    h1 { font-size: 1.5em; color: #0f172a; margin-bottom: 4px; }
    .subtitle { color: #64748b; font-size: 0.9em; margin-bottom: 20px; }
    .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 24px; }
    .summary-card { background: #fff; border-radius: 10px; padding: 16px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .summary-card .num { font-size: 2em; font-weight: 700; }
    .summary-card .label { font-size: 0.82em; color: #64748b; margin-top: 2px; }
    .num-green { color: #16a34a; }
    .num-red { color: #dc2626; }
    .num-yellow { color: #d97706; }
    .num-blue { color: #2563eb; }
    .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; display: flex; align-items: center; gap: 8px; }
    .error-row { background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; padding: 14px; margin-bottom: 10px; }
    .error-row .tipo { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.78em; font-weight: 700; margin-right: 6px; }
    .tipo-sub { background: #fee2e2; color: #991b1b; }
    .tipo-dom { background: #fef3c7; color: #92400e; }
    .tipo-conf { background: #ede9fe; color: #5b21b6; }
    .tipo-htaccess { background: #fce7f3; color: #9d174d; }
    .tipo-index { background: #e0f2fe; color: #075985; }
    .error-row .carpeta { font-weight: 700; color: #0f172a; }
    .error-row .detalle { font-size: 0.88em; color: #64748b; margin-top: 4px; }
    .error-row code { background: #f1f5f9; padding: 1px 5px; border-radius: 3px; font-size: 0.9em; }
    .warn-row { background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; padding: 12px; margin-bottom: 8px; font-size: 0.9em; }
    .ok-banner { background: #f0fdf4; border: 1px solid #86efac; border-radius: 8px; padding: 16px; text-align: center; color: #166534; font-weight: 600; }
    table { width: 100%; border-collapse: collapse; font-size: 0.88em; }
    table th { text-align: left; padding: 8px; border-bottom: 2px solid #e2e8f0; color: #475569; font-weight: 600; }
    table td { padding: 8px; border-bottom: 1px solid #f1f5f9; }
    table tr:hover { background: #f8fafc; }
    .badge { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 0.78em; font-weight: 600; }
    .badge-ok { background: #dcfce7; color: #166534; }
    .badge-err { background: #fee2e2; color: #991b1b; }
    .badge-warn { background: #fef3c7; color: #92400e; }
    .badge-na { background: #f1f5f9; color: #94a3b8; }
    .filter-bar { margin-bottom: 16px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
    .filter-bar input { padding: 6px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.9em; width: 250px; }
    .filter-bar select { padding: 6px 10px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.9em; }
    .filter-bar label { font-size: 0.85em; color: #64748b; }
    .btn-fix { padding: 4px 10px; border: none; border-radius: 5px; cursor: pointer; font-size: 0.8em; font-weight: 600; transition: background 0.2s; }
    .btn-fix-one { background: #dbeafe; color: #1d4ed8; }
    .btn-fix-one:hover { background: #bfdbfe; }
    .btn-fix-all { padding: 8px 18px; background: #7c3aed; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9em; font-weight: 600; }
    .btn-fix-all:hover { background: #6d28d9; }
    .btn-fix-all:disabled, .btn-fix-one:disabled { opacity: 0.5; cursor: not-allowed; }
    .fix-result { display: inline-block; margin-left: 8px; font-size: 0.82em; font-weight: 600; }
    .fix-ok { color: #16a34a; }
    .fix-err { color: #dc2626; }
    .fix-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
    .fix-progress { background: #e2e8f0; border-radius: 6px; height: 8px; flex: 1; min-width: 120px; overflow: hidden; display: none; }
    .fix-progress-inner { background: #7c3aed; height: 100%; width: 0%; transition: width 0.3s; border-radius: 6px; }
</style>
</head>
<body>
<div class="container">
    <h1>&#128269; Verificador de Enlaces de Subdominios</h1>
    <p class="subtitle">Escaneado: <?= date('Y-m-d H:i:s') ?> | Base: <code><?= htmlspecialchars($basePath) ?></code> | Tiempo: <?= $tiempoTotal ?>s</p>

    <!-- RESUMEN -->
    <div class="summary">
        <div class="summary-card"><div class="num num-blue"><?= count($resultados) ?></div><div class="label">Subdominios</div></div>
        <div class="summary-card"><div class="num num-blue"><?= $totalConWeb ?></div><div class="label">Con pagina web</div></div>
        <div class="summary-card"><div class="num"><?= $totalSinWeb ?></div><div class="label">Sin pagina web</div></div>
        <div class="summary-card"><div class="num <?= $totalErrores > 0 ? 'num-red' : 'num-green' ?>"><?= $totalErrores ?></div><div class="label">Errores</div></div>
        <div class="summary-card"><div class="num <?= $totalAdvertencias > 0 ? 'num-yellow' : 'num-green' ?>"><?= $totalAdvertencias ?></div><div class="label">Advertencias</div></div>
    </div>

    <?php if ($totalErrores > 0): ?>
    <!-- ERRORES -->
    <div class="section">
        <h2>&#9888;&#65039; Errores encontrados (<?= $totalErrores ?>)</h2>
        <?php
        // Recopilar subdominios con errores de htaccess/index para el boton corregir todos
        $subdsConErrorFix = [];
        foreach ($resultados as $r) {
            if (empty($r['errores'])) continue;
            foreach ($r['errores'] as $e) {
                if (in_array($e['tipo'], ['ERROR_HTACCESS_DESTINO','ERROR_HTACCESS_FALTANTE','ERROR_INDEX_DESTINO','ERROR_INDEX_FALTANTE'])) {
                    $subdsConErrorFix[$r['carpeta']] = true;
                }
            }
        }
        ?>
        <?php if (!empty($subdsConErrorFix)): ?>
        <div class="fix-bar">
            <button class="btn-fix-all" onclick="corregirTodos()" id="btnFixAll">
                &#9874; Corregir TODOS .htaccess e index.html (<?= count($subdsConErrorFix) ?> subdominios)
            </button>
            <div class="fix-progress" id="fixProgress"><div class="fix-progress-inner" id="fixProgressBar"></div></div>
            <span class="fix-result" id="fixAllResult"></span>
        </div>
        <?php endif; ?>

        <?php foreach ($resultados as $r): ?>
            <?php if (empty($r['errores'])) continue; ?>
            <?php foreach ($r['errores'] as $e): ?>
                <div class="error-row" id="err-<?= htmlspecialchars($r['carpeta']) ?>-<?= htmlspecialchars($e['tipo']) ?>">
                    <?php
                    $tipoClass = 'tipo-sub';
                    $tipoLabel = 'SUBDOMINIO';
                    $esCorregible = false;
                    if (strpos($e['tipo'], 'HTACCESS') !== false) {
                        $tipoClass = 'tipo-htaccess';
                        $tipoLabel = '.HTACCESS';
                        $esCorregible = true;
                    } elseif (strpos($e['tipo'], 'INDEX') !== false) {
                        $tipoClass = 'tipo-index';
                        $tipoLabel = 'INDEX.HTML';
                        $esCorregible = true;
                    } elseif (strpos($e['tipo'], 'DOMINIO') !== false && strpos($e['tipo'], 'SUBDOMINIO') === false) {
                        $tipoClass = 'tipo-dom';
                        $tipoLabel = 'DOMINIO';
                    }
                    if (strpos($e['tipo'], 'CONFIG') !== false) {
                        $tipoClass = 'tipo-conf';
                        $tipoLabel .= ' (CONFIG)';
                    }
                    ?>
                    <span class="tipo <?= $tipoClass ?>"><?= $tipoLabel ?></span>
                    <span class="carpeta"><?= htmlspecialchars($r['carpeta']) ?></span>
                    <?php if ($esCorregible): ?>
                    <button class="btn-fix btn-fix-one" onclick="corregirUno('<?= htmlspecialchars($r['carpeta']) ?>', this)">&#9874; Corregir</button>
                    <span class="fix-result" id="fix-<?= htmlspecialchars($r['carpeta']) ?>"></span>
                    <?php endif; ?>
                    <div class="detalle">
                        <?= htmlspecialchars($e['mensaje']) ?><br>
                        Archivo: <code><?= htmlspecialchars($e['archivo']) ?></code> |
                        Href: <code><?= htmlspecialchars($e['href']) ?></code><br>
                        Esperado: <code><?= htmlspecialchars($e['esperado']) ?></code> |
                        Actual: <code><?= htmlspecialchars($e['actual']) ?></code>
                    </div>
                </div>
            <?php endforeach; ?>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php if ($totalAdvertencias > 0): ?>
    <!-- ADVERTENCIAS -->
    <div class="section">
        <h2>&#9888; Advertencias (<?= $totalAdvertencias ?>)</h2>
        <?php foreach ($resultados as $r): ?>
            <?php if (empty($r['advertencias'])) continue; ?>
            <?php foreach ($r['advertencias'] as $adv): ?>
                <div class="warn-row">
                    <strong><?= htmlspecialchars($r['carpeta']) ?></strong>: <?= htmlspecialchars($adv) ?>
                </div>
            <?php endforeach; ?>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php if ($totalErrores === 0 && $totalAdvertencias === 0): ?>
    <div class="ok-banner">&#9989; Todos los enlaces verificados estan correctos.</div>
    <?php endif; ?>

    <!-- TABLA COMPLETA -->
    <div class="section">
        <h2>&#128203; Detalle completo</h2>
        <div class="filter-bar">
            <label>Filtrar:</label>
            <input type="text" id="filtro" placeholder="Buscar subdominio..." oninput="filtrarTabla()">
            <select id="filtroEstado" onchange="filtrarTabla()">
                <option value="">Todos</option>
                <option value="error">Solo con errores</option>
                <option value="warn">Solo con advertencias</option>
                <option value="ok">Solo correctos</option>
                <option value="noweb">Sin pagina web</option>
            </select>
        </div>
        <table id="tablaResultados">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Subdominio</th>
                    <th>Web</th>
                    <th>Estado</th>
                    <th>Hrefs encontrados</th>
                    <th>Detalle</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($resultados as $i => $r): ?>
                <?php
                    $estado = 'ok';
                    $badgeClass = 'badge-ok';
                    $badgeText = 'OK';
                    if (!empty($r['errores'])) { $estado = 'error'; $badgeClass = 'badge-err'; $badgeText = count($r['errores']) . ' error(es)'; }
                    elseif (!empty($r['advertencias'])) { $estado = 'warn'; $badgeClass = 'badge-warn'; $badgeText = count($r['advertencias']) . ' adv.'; }
                    elseif (!$r['tiene_web'] && empty($r['hrefs'])) { $estado = 'noweb'; $badgeClass = 'badge-na'; $badgeText = 'Sin web'; }
                ?>
                <tr data-carpeta="<?= htmlspecialchars(strtolower($r['carpeta'])) ?>" data-estado="<?= $estado ?>">
                    <td><?= $i + 1 ?></td>
                    <td><strong><?= htmlspecialchars($r['carpeta']) ?></strong></td>
                    <td><?= $r['tiene_web'] ? '&#9989;' : '&#10060;' ?></td>
                    <td><span class="badge <?= $badgeClass ?>"><?= $badgeText ?></span></td>
                    <td>
                        <?php if (!empty($r['hrefs'])): ?>
                            <?php foreach ($r['hrefs'] as $h): ?>
                                <code style="font-size:0.82em;word-break:break-all;"><?= htmlspecialchars($h['href']) ?></code><br>
                            <?php endforeach; ?>
                        <?php else: ?>
                            <span style="color:#94a3b8;">-</span>
                        <?php endif; ?>
                    </td>
                    <td>
                        <?php if (!empty($r['errores'])): ?>
                            <?php foreach ($r['errores'] as $e): ?>
                                <span style="color:#dc2626;font-size:0.82em;"><?= htmlspecialchars($e['mensaje']) ?></span><br>
                            <?php endforeach; ?>
                        <?php elseif (!empty($r['advertencias'])): ?>
                            <?php foreach ($r['advertencias'] as $adv): ?>
                                <span style="color:#d97706;font-size:0.82em;"><?= htmlspecialchars($adv) ?></span><br>
                            <?php endforeach; ?>
                        <?php else: ?>
                            <span style="color:#94a3b8;font-size:0.82em;">-</span>
                        <?php endif; ?>
                    </td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div>

    <!-- JSON EXPORT -->
    <div class="section">
        <h2>&#128190; Exportar resultados</h2>
        <button onclick="exportarJSON()" style="padding:8px 16px;background:#2563eb;color:#fff;border:none;border-radius:6px;cursor:pointer;font-size:0.9em;">Descargar JSON</button>
        <button onclick="exportarCSV()" style="padding:8px 16px;background:#16a34a;color:#fff;border:none;border-radius:6px;cursor:pointer;font-size:0.9em;margin-left:8px;">Descargar CSV (errores)</button>
    </div>
</div>

<script>
var resultadosJSON = <?= json_encode($resultados, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) ?>;

function filtrarTabla() {
    var texto = document.getElementById('filtro').value.toLowerCase();
    var estado = document.getElementById('filtroEstado').value;
    var filas = document.querySelectorAll('#tablaResultados tbody tr');

    filas.forEach(function(fila) {
        var carpeta = fila.getAttribute('data-carpeta');
        var est = fila.getAttribute('data-estado');
        var mostrar = true;

        if (texto && carpeta.indexOf(texto) === -1) mostrar = false;
        if (estado && est !== estado) mostrar = false;

        fila.style.display = mostrar ? '' : 'none';
    });
}

function exportarJSON() {
    var blob = new Blob([JSON.stringify(resultadosJSON, null, 2)], {type: 'application/json'});
    var url = URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = url;
    a.download = 'verificacion_enlaces_' + new Date().toISOString().slice(0,10) + '.json';
    a.click();
    URL.revokeObjectURL(url);
}

// --- Funciones de correccion ---
function corregirUno(carpeta, btn) {
    if (!confirm('¿Corregir .htaccess e index.html de "' + carpeta + '"?')) return;
    btn.disabled = true;
    btn.textContent = 'Corrigiendo...';
    var span = document.getElementById('fix-' + carpeta);

    fetch('?action=fix&modo=uno&carpeta=' + encodeURIComponent(carpeta))
        .then(function(r) { return r.json(); })
        .then(function(data) {
            if (data.ok) {
                if (span) { span.className = 'fix-result fix-ok'; span.textContent = '✓ ' + data.mensaje; }
                btn.textContent = '✓ Corregido';
                btn.style.background = '#dcfce7';
                btn.style.color = '#166534';
            } else {
                if (span) { span.className = 'fix-result fix-err'; span.textContent = '✗ ' + data.mensaje; }
                btn.disabled = false;
                btn.textContent = '⚒ Corregir';
            }
        })
        .catch(function(err) {
            if (span) { span.className = 'fix-result fix-err'; span.textContent = '✗ Error de red'; }
            btn.disabled = false;
            btn.textContent = '⚒ Corregir';
        });
}

function corregirTodos() {
    if (!confirm('¿Corregir .htaccess e index.html de TODOS los subdominios con errores?\n\nEsto reescribira los archivos con el contenido correcto.')) return;
    var btn = document.getElementById('btnFixAll');
    var progress = document.getElementById('fixProgress');
    var progressBar = document.getElementById('fixProgressBar');
    var resultado = document.getElementById('fixAllResult');

    btn.disabled = true;
    btn.textContent = '⏳ Corrigiendo todos...';
    progress.style.display = 'block';
    progressBar.style.width = '30%';

    fetch('?action=fix&modo=todos')
        .then(function(r) { return r.json(); })
        .then(function(data) {
            progressBar.style.width = '100%';
            if (data.ok) {
                resultado.className = 'fix-result fix-ok';
                resultado.textContent = '✓ ' + data.mensaje;
                btn.textContent = '✓ Completado';
                btn.style.background = '#16a34a';
            } else {
                resultado.className = 'fix-result fix-err';
                resultado.textContent = '⚠ ' + data.mensaje;
                btn.textContent = '⚠ Completado con errores';
                btn.style.background = '#d97706';
            }
            // Mostrar detalle de cada subdominio
            if (data.resultados && data.resultados.length > 0) {
                var detalle = '';
                data.resultados.forEach(function(r) {
                    if (r.corregidos.length > 0) {
                        detalle += r.carpeta + ': corregido ' + r.corregidos.join(', ') + '\n';
                    }
                    if (r.errores_fix.length > 0) {
                        detalle += r.carpeta + ': ERROR - ' + r.errores_fix.join(', ') + '\n';
                    }
                });
                if (detalle) {
                    resultado.textContent += ' | Ver consola para detalle';
                    console.log('=== Detalle de correcciones ===\n' + detalle);
                }
            }
            // Deshabilitar todos los botones individuales ya corregidos
            var btns = document.querySelectorAll('.btn-fix-one');
            btns.forEach(function(b) { b.disabled = true; b.textContent = '✓ Corregido'; b.style.background = '#dcfce7'; b.style.color = '#166534'; });
        })
        .catch(function(err) {
            progressBar.style.width = '100%';
            progressBar.style.background = '#dc2626';
            resultado.className = 'fix-result fix-err';
            resultado.textContent = '✗ Error de conexion';
            btn.disabled = false;
            btn.textContent = '⚒ Corregir TODOS';
        });
}

function exportarCSV() {
    var csv = 'Carpeta,Tipo Error,Mensaje,Archivo,Href,Esperado,Actual\n';
    resultadosJSON.forEach(function(r) {
        if (!r.errores || r.errores.length === 0) return;
        r.errores.forEach(function(e) {
            csv += '"' + r.carpeta + '","' + e.tipo + '","' + e.mensaje.replace(/"/g,'""') + '","' + e.archivo + '","' + e.href.replace(/"/g,'""') + '","' + e.esperado + '","' + e.actual + '"\n';
        });
    });
    var blob = new Blob([csv], {type: 'text/csv'});
    var url = URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = url;
    a.download = 'errores_enlaces_' + new Date().toISOString().slice(0,10) + '.csv';
    a.click();
    URL.revokeObjectURL(url);
}
</script>
</body>
</html>
    <?php
}
