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

/**
 * CONFIGURADOR MASIVO DE GRUPO BEZ ADMIN - SUBDOMINIOS SIE
 * =========================================================
 * Configura el grupo administrador del plugin BEZ en todos los subdominios.
 *
 * OPERACIONES:
 *   OP 1: conf/local.php - Agrega $conf['plugin']['bez']['admin_group'] = 'nombre';
 *         Si ya existe, actualiza el valor. Si no existe, lo agrega al final.
 *   OP 2: conf/users.auth.php - Busca usuarios con grupo 'sie' y les agrega
 *         el grupo BEZ admin configurado (sin quitar 'sie').
 *
 * MODOS:
 *   ?modo=escanear     (default) - Solo muestra estado actual, NO modifica nada
 *   ?modo=corregir                - Aplica los cambios con backup
 *   ?sub=nombre                   - Solo un subdominio
 *   ?grupo=bez_admin              - Nombre del grupo (default: bez_admin)
 *
 * SEGURIDAD: Crea backup de cada archivo antes de modificar
 */

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

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

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

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

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

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

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

// Sanitizar grupo: solo letras, numeros, guion bajo
$grupoBez = preg_replace('/[^a-zA-Z0-9_]/', '', $grupoBez);
if (empty($grupoBez)) $grupoBez = 'bez_admin';

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

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

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

/**
 * Analiza el estado de conf/local.php respecto al admin_group
 */
function analizarLocalPhp($subPath, $grupoBez)
{
    $localFile = $subPath . '/conf/local.php';
    $r = [
        'existe'    => false,
        'tiene_conf' => false,
        'valor_actual' => '',
        'correcto'  => false,
        'necesita_fix' => true,
    ];

    if (!file_exists($localFile)) {
        return $r;
    }
    $r['existe'] = true;

    $contenido = @file_get_contents($localFile);
    if ($contenido === false) return $r;

    // Buscar si ya tiene la linea de admin_group
    if (preg_match('/\$conf\s*\[\s*[\'"]plugin[\'"]\s*\]\s*\[\s*[\'"]bez[\'"]\s*\]\s*\[\s*[\'"]admin_group[\'"]\s*\]\s*=\s*[\'"]([^"\']*)[\'"]/', $contenido, $m)) {
        $r['tiene_conf'] = true;
        $r['valor_actual'] = $m[1];
        if ($m[1] === $grupoBez) {
            $r['correcto'] = true;
            $r['necesita_fix'] = false;
        }
    }

    return $r;
}

/**
 * Valores esperados para las directivas DokuWiki en conf/local.php
 */
function getDirectivasEsperadas()
{
    return [
        'defaultgroup' => 'lectura',
        'superuser'    => '@admin',
        'manager'      => 'manager',
    ];
}

/**
 * Analiza el estado de las directivas DokuWiki (defaultgroup, superuser, manager)
 */
function analizarDirectivas($subPath)
{
    $localFile = $subPath . '/conf/local.php';
    $esperadas = getDirectivasEsperadas();

    $r = [
        'existe'     => false,
        'directivas' => [], // clave => ['actual' => valor|null, 'esperado' => valor, 'correcto' => bool]
        'necesita_fix' => false,
    ];

    foreach ($esperadas as $k => $v) {
        $r['directivas'][$k] = ['actual' => null, 'esperado' => $v, 'correcto' => false];
    }

    if (!file_exists($localFile)) return $r;
    $r['existe'] = true;

    $contenido = @file_get_contents($localFile);
    if ($contenido === false) return $r;

    foreach ($esperadas as $clave => $valorEsperado) {
        // Buscar $conf['clave'] = 'valor';
        $patron = '/\$conf\s*\[\s*[\'"]' . preg_quote($clave, '/') . '[\'"]\s*\]\s*=\s*[\'"]([^"\']*)[\'"]/' ;
        if (preg_match($patron, $contenido, $m)) {
            $r['directivas'][$clave]['actual'] = $m[1];
            $r['directivas'][$clave]['correcto'] = ($m[1] === $valorEsperado);
        }
        if (!$r['directivas'][$clave]['correcto']) {
            $r['necesita_fix'] = true;
        }
    }

    return $r;
}

/**
 * Analiza el estado de conf/users.auth.php respecto a usuarios sie
 */
function analizarUsersAuth($subPath, $grupoBez)
{
    $usersFile = $subPath . '/conf/users.auth.php';
    $r = [
        'existe'         => false,
        'total_usuarios' => 0,
        'usuarios_sie'   => [],
        'ya_tienen_grupo' => [],
        'necesitan_grupo' => [],
    ];

    if (!file_exists($usersFile)) {
        return $r;
    }
    $r['existe'] = true;

    $lineas = @file($usersFile, FILE_IGNORE_NEW_LINES);
    if ($lineas === false) return $r;

    foreach ($lineas as $linea) {
        // Saltar comentarios y lineas vacias
        $lineaTrim = trim($linea);
        if ($lineaTrim === '' || $lineaTrim[0] === '#') continue;

        // Formato: usuario:hash:nombre:email:grupos
        $partes = explode(':', $linea);
        if (count($partes) < 5) continue;

        $r['total_usuarios']++;
        $usuario = $partes[0];
        $grupos = explode(',', $partes[4]);

        // Buscar usuarios con grupo 'sie'
        if (in_array('sie', $grupos)) {
            $r['usuarios_sie'][] = [
                'usuario' => $usuario,
                'grupos'  => $partes[4],
            ];

            if (in_array($grupoBez, $grupos)) {
                $r['ya_tienen_grupo'][] = $usuario;
            } else {
                $r['necesitan_grupo'][] = $usuario;
            }
        }
    }

    return $r;
}

/**
 * Analiza un subdominio completo
 */
function analizarSubdominio($subPath, $carpeta, $grupoBez)
{
    $r = [
        'carpeta'       => $carpeta,
        'es_dokuwiki'   => false,
        'local_php'     => null,
        'directivas'    => null,
        'users_auth'    => null,
        'fixes'         => [],
        'detalles'      => [],
    ];

    // Verificar que es un sistema DokuWiki
    if (!file_exists($subPath . '/doku.php') && !file_exists($subPath . '/inc/init.php')) {
        return $r;
    }
    $r['es_dokuwiki'] = true;

    // Analizar conf/local.php
    $r['local_php'] = analizarLocalPhp($subPath, $grupoBez);
    if ($r['local_php']['necesita_fix']) {
        $r['fixes'][] = 'LOCAL_PHP';
        if (!$r['local_php']['existe']) {
            $r['detalles']['LOCAL_PHP'] = 'conf/local.php no existe';
        } elseif (!$r['local_php']['tiene_conf']) {
            $r['detalles']['LOCAL_PHP'] = 'falta $conf[plugin][bez][admin_group]';
        } else {
            $r['detalles']['LOCAL_PHP'] = 'valor actual: "' . $r['local_php']['valor_actual'] . '" → cambiar a "' . $grupoBez . '"';
        }
    }

    // Analizar directivas DokuWiki (defaultgroup, superuser, manager)
    $r['directivas'] = analizarDirectivas($subPath);
    if ($r['directivas']['necesita_fix']) {
        $r['fixes'][] = 'DIRECTIVAS';
        $malas = [];
        foreach ($r['directivas']['directivas'] as $k => $d) {
            if (!$d['correcto']) {
                $actual = $d['actual'] !== null ? '"' . $d['actual'] . '"' : 'no definido';
                $malas[] = $k . ': ' . $actual . ' → "' . $d['esperado'] . '"';
            }
        }
        $r['detalles']['DIRECTIVAS'] = implode(', ', $malas);
    }

    // Analizar conf/users.auth.php
    $r['users_auth'] = analizarUsersAuth($subPath, $grupoBez);
    if (!empty($r['users_auth']['necesitan_grupo'])) {
        $r['fixes'][] = 'USERS_AUTH';
        $cnt = count($r['users_auth']['necesitan_grupo']);
        $nombres = implode(', ', array_slice($r['users_auth']['necesitan_grupo'], 0, 5));
        if ($cnt > 5) $nombres .= '...';
        $r['detalles']['USERS_AUTH'] = $cnt . ' usuario(s) sie sin grupo: ' . $nombres;
    }

    return $r;
}

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

/**
 * FIX 1: Agregar/actualizar admin_group en conf/local.php
 */
function fixLocalPhp($subPath, $grupoBez)
{
    $localFile = $subPath . '/conf/local.php';
    $resultado = ['ok' => false, 'msg' => '', 'archivo' => 'conf/local.php'];

    if (!file_exists($localFile)) {
        $resultado['msg'] = 'conf/local.php no existe - no se puede crear';
        return $resultado;
    }

    $contenido = @file_get_contents($localFile);
    if ($contenido === false) {
        $resultado['msg'] = 'No se pudo leer';
        return $resultado;
    }

    // Backup
    $backup = crearBackup($localFile);
    if (!$backup) {
        $resultado['msg'] = 'No se pudo crear backup';
        return $resultado;
    }

    $linea_nueva = "\$conf['plugin']['bez']['admin_group'] = '$grupoBez';";

    // Verificar si ya existe la linea
    if (preg_match('/\$conf\s*\[\s*[\'"]plugin[\'"]\s*\]\s*\[\s*[\'"]bez[\'"]\s*\]\s*\[\s*[\'"]admin_group[\'"]\s*\]\s*=\s*[\'"][^"\']*[\'"];?/', $contenido)) {
        // Ya existe: reemplazar
        $nuevoContenido = preg_replace(
            '/\$conf\s*\[\s*[\'"]plugin[\'"]\s*\]\s*\[\s*[\'"]bez[\'"]\s*\]\s*\[\s*[\'"]admin_group[\'"]\s*\]\s*=\s*[\'"][^"\']*[\'"];?/',
            $linea_nueva,
            $contenido
        );
        if ($nuevoContenido === null) {
            $resultado['msg'] = 'Error en regex al reemplazar';
            return $resultado;
        }
        $accion = 'actualizado';
    } else {
        // No existe: agregar antes del cierre o al final
        $nuevoContenido = rtrim($contenido);

        // Buscar un buen lugar para insertar (despues de la ULTIMA linea $conf['plugin']['bez'])
        if (preg_match_all('/(\$conf\s*\[\s*[\'"]plugin[\'"]\s*\]\s*\[\s*[\'"]bez[\'"]\s*\][^\n]*\n)/s', $nuevoContenido, $matches, PREG_OFFSET_CAPTURE)) {
            // Insertar despues de la ULTIMA linea bez existente
            $lastMatch = end($matches[0]);
            $pos = $lastMatch[1] + strlen($lastMatch[0]);
            $nuevoContenido = substr($nuevoContenido, 0, $pos) . $linea_nueva . "\n" . substr($nuevoContenido, $pos);
        } else {
            // Agregar al final (antes de posible cierre PHP)
            if (preg_match('/\?' . '>\s*$/', $nuevoContenido)) {
                $nuevoContenido = preg_replace('/\?' . '>\s*$/', "\n" . $linea_nueva . "\n", $nuevoContenido);
            } else {
                $nuevoContenido .= "\n" . $linea_nueva . "\n";
            }
        }
        $accion = 'agregado';
    }

    if (@file_put_contents($localFile, $nuevoContenido) !== false) {
        $resultado['ok'] = true;
        $resultado['msg'] = $accion . ' → ' . $grupoBez;
        $resultado['backup'] = basename($backup);
    } else {
        // Restaurar backup
        @copy($backup, $localFile);
        $resultado['msg'] = 'Error al escribir, backup restaurado';
    }

    return $resultado;
}

/**
 * FIX 2: Corregir directivas DokuWiki (defaultgroup, superuser, manager) en conf/local.php
 */
function fixDirectivas($subPath)
{
    $localFile = $subPath . '/conf/local.php';
    $resultado = ['ok' => false, 'msg' => '', 'archivo' => 'conf/local.php (directivas)'];
    $esperadas = getDirectivasEsperadas();

    if (!file_exists($localFile)) {
        $resultado['msg'] = 'conf/local.php no existe';
        return $resultado;
    }

    $contenido = @file_get_contents($localFile);
    if ($contenido === false) {
        $resultado['msg'] = 'No se pudo leer';
        return $resultado;
    }

    // Backup (solo si no se hizo ya por fixLocalPhp en este mismo ciclo)
    $timestamp = date('Ymd_His');
    $backupExiste = glob($localFile . '.bak_bezadmin_' . date('Ymd') . '_*');
    if (empty($backupExiste)) {
        $backup = crearBackup($localFile);
        if (!$backup) {
            $resultado['msg'] = 'No se pudo crear backup';
            return $resultado;
        }
    }

    $nuevoContenido = $contenido;
    $cambios = [];

    foreach ($esperadas as $clave => $valorEsperado) {
        $patronBuscar = '/\$conf\s*\[\s*[\'"]' . preg_quote($clave, '/') . '[\'"]\s*\]\s*=\s*[\'"][^"\']*[\'"];?/';
        $lineaNueva = "\$conf['" . $clave . "'] = '" . $valorEsperado . "';";

        if (preg_match($patronBuscar, $nuevoContenido, $m)) {
            // Verificar si ya tiene el valor correcto
            $patronValor = '/\$conf\s*\[\s*[\'"]' . preg_quote($clave, '/') . '[\'"]\s*\]\s*=\s*[\'"]' . preg_quote($valorEsperado, '/') . '[\'"];?/';
            if (preg_match($patronValor, $nuevoContenido)) {
                continue; // Ya correcto, saltar
            }
            // Reemplazar valor existente
            $nuevoContenido = preg_replace($patronBuscar, $lineaNueva, $nuevoContenido, 1);
            if ($nuevoContenido === null) {
                $resultado['msg'] = 'Error regex en ' . $clave;
                return $resultado;
            }
            $cambios[] = $clave . '→' . $valorEsperado;
        } else {
            // No existe: agregar al final
            $nuevoContenido = rtrim($nuevoContenido) . "\n" . $lineaNueva . "\n";
            $cambios[] = '+' . $clave . '=' . $valorEsperado;
        }
    }

    if (empty($cambios)) {
        $resultado['ok'] = true;
        $resultado['msg'] = 'Sin cambios necesarios';
        return $resultado;
    }

    if (@file_put_contents($localFile, $nuevoContenido) !== false) {
        $resultado['ok'] = true;
        $resultado['msg'] = implode(', ', $cambios);
    } else {
        // Restaurar backup si existe
        if (!empty($backupExiste)) {
            @copy(end($backupExiste), $localFile);
        }
        $resultado['msg'] = 'Error al escribir';
    }

    return $resultado;
}

/**
 * FIX 3: Agregar grupo bez_admin a usuarios con grupo 'sie' en users.auth.php
 */
function fixUsersAuth($subPath, $grupoBez)
{
    $usersFile = $subPath . '/conf/users.auth.php';
    $resultado = ['ok' => false, 'msg' => '', 'archivo' => 'conf/users.auth.php', 'modificados' => 0];

    if (!file_exists($usersFile)) {
        $resultado['msg'] = 'users.auth.php no existe';
        return $resultado;
    }

    $contenido = @file_get_contents($usersFile);
    if ($contenido === false) {
        $resultado['msg'] = 'No se pudo leer';
        return $resultado;
    }

    // Backup
    $backup = crearBackup($usersFile);
    if (!$backup) {
        $resultado['msg'] = 'No se pudo crear backup';
        return $resultado;
    }

    $lineas = explode("\n", $contenido);
    $totalLineas = count($lineas);
    $modificados = 0;
    $nombresModificados = [];

    for ($i = 0; $i < $totalLineas; $i++) {
        $linea = $lineas[$i];
        $lineaTrim = trim($linea);
        if ($lineaTrim === '' || $lineaTrim[0] === '#') continue;

        $partes = explode(':', $linea);
        if (count($partes) < 5) continue;

        $usuario = $partes[0];
        $grupos = explode(',', $partes[4]);

        // Si tiene grupo 'sie' y NO tiene el grupo bez_admin
        if (in_array('sie', $grupos) && !in_array($grupoBez, $grupos)) {
            $grupos[] = $grupoBez;
            $partes[4] = implode(',', $grupos);
            $lineas[$i] = implode(':', $partes);
            $modificados++;
            $nombresModificados[] = $usuario;
        }
    }

    if ($modificados === 0) {
        $resultado['ok'] = true;
        $resultado['msg'] = 'Sin cambios necesarios';
        return $resultado;
    }

    $nuevoContenido = implode("\n", $lineas);

    if (@file_put_contents($usersFile, $nuevoContenido) !== false) {
        $resultado['ok'] = true;
        $resultado['modificados'] = $modificados;
        $nombres = implode(', ', array_slice($nombresModificados, 0, 5));
        if ($modificados > 5) $nombres .= '...';
        $resultado['msg'] = $modificados . ' usuario(s): ' . $nombres;
        $resultado['backup'] = basename($backup);
    } else {
        @copy($backup, $usersFile);
        $resultado['msg'] = 'Error al escribir, backup restaurado';
    }

    return $resultado;
}

/**
 * Aplica todas las correcciones a un subdominio
 */
function corregirSubdominio($subPath, $carpeta, $fixes, $grupoBez)
{
    $resultados = [];

    if (in_array('LOCAL_PHP', $fixes)) {
        $resultados[] = fixLocalPhp($subPath, $grupoBez);
    }

    if (in_array('DIRECTIVAS', $fixes)) {
        $resultados[] = fixDirectivas($subPath);
    }

    if (in_array('USERS_AUTH', $fixes)) {
        $resultados[] = fixUsersAuth($subPath, $grupoBez);
    }

    return $resultados;
}

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

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

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

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

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

$totalCorregidos = 0;

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

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

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

    $totalAfectados = count($afectadosParaFix);

    echo "=== CONFIGURADOR DE GRUPO BEZ ADMIN - SIE ===\n";
    echo "Fecha: " . date('Y-m-d H:i:s') . "\n";
    echo "PHP: " . phpversion() . "\n";
    echo "Grupo BEZ Admin: " . htmlspecialchars($grupoBez) . "\n";
    echo "Total DokuWiki: " . count($resultados) . " | Afectados: {$totalAfectados}\n";
    echo "Operaciones: OP1=conf/local.php, OP2=users.auth.php\n";
    echo "========================================\n\n";
    if (!$esCLI) { flush(); }

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

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

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

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

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

// =====================================================================
//  ESTADISTICAS PARA DASHBOARD
// =====================================================================

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

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

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

$etiquetasFix = [
    'LOCAL_PHP'   => ['label' => 'bez admin_group',    'color' => '#6366f1', 'icon' => '&#9881;'],
    'DIRECTIVAS'  => ['label' => 'directivas DokuWiki','color' => '#f59e0b', 'icon' => '&#9874;'],
    'USERS_AUTH'  => ['label' => 'users.auth.php',     'color' => '#e94560', 'icon' => '&#128101;'],
];

// Estadisticas de usuarios
$totalUsuariosSie     = 0;
$totalYaTienenGrupo   = 0;
$totalNecesitanGrupo  = 0;
foreach ($resultados as $r) {
    if ($r['users_auth']) {
        $totalUsuariosSie    += count($r['users_auth']['usuarios_sie']);
        $totalYaTienenGrupo  += count($r['users_auth']['ya_tienen_grupo']);
        $totalNecesitanGrupo += count($r['users_auth']['necesitan_grupo']);
    }
}

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

if ($esCLI) {
    echo "================================================================\n";
    echo " CONFIGURADOR DE GRUPO BEZ ADMIN - SUBDOMINIOS SIE\n";
    echo " " . date('Y-m-d H:i:s') . " | Modo: {$modo} | Grupo: {$grupoBez} | Tiempo: {$tiempoFin}s\n";
    echo "================================================================\n\n";

    echo "Total DokuWiki: " . count($resultados) . " | OK: {$totalOK} | Necesitan cambio: {$totalProblema}\n";
    echo "Usuarios SIE: {$totalUsuariosSie} | Ya con grupo: {$totalYaTienenGrupo} | Necesitan grupo: {$totalNecesitanGrupo}\n\n";

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

    if (!empty($afectados)) {
        echo "\n=== SISTEMAS POR CONFIGURAR ===\n";
        foreach ($afectados as $r) {
            echo sprintf("  %-30s [%s]\n", $r['carpeta'], implode(', ', $r['fixes']));
            foreach ($r['detalles'] as $tipo => $det) {
                echo "    -> {$tipo}: {$det}\n";
            }
        }
    }
    exit(0);
}

// =====================================================================
//  SALIDA HTML
// =====================================================================
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Configurador BEZ Admin - 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: 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: 10px; margin-bottom: 20px; }
    .card { background: #fff; border-radius: 10px; padding: 12px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .card .num { font-size: 1.6em; font-weight: 700; }
    .card .label { font-size: 0.75em; color: #64748b; }
    .green { color: #16a34a; } .red { color: #dc2626; } .yellow { color: #d97706; } .blue { color: #2563eb; } .purple { color: #6366f1; } .pink { color: #e94560; }

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

    .explain { background: #eff6ff; border: 1px solid #93c5fd; border-radius: 10px; padding: 16px; margin-bottom: 20px; }
    .explain h2 { color: #1e40af; margin-bottom: 8px; font-size: 1em; }
    .explain p { font-size: 0.84em; color: #334155; margin-bottom: 4px; }
    code { background: #f1f5f9; padding: 1px 4px; border-radius: 3px; font-size: 0.86em; }

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

    .grupo-config { background: #faf5ff; border: 2px solid #6366f1; border-radius: 10px; padding: 16px; margin-bottom: 20px; }
    .grupo-config label { font-weight: 700; font-size: 0.95em; color: #4c1d95; }
    .grupo-config input { padding: 8px 14px; border: 2px solid #6366f1; border-radius: 8px; font-size: 1em; font-weight: 600; color: #4c1d95; width: 200px; margin: 0 12px; }
    .grupo-config .hint { font-size: 0.8em; color: #7c3aed; margin-top: 6px; }

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

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

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

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

<h1>&#128272; Configurador de Grupo BEZ Admin - SIE</h1>
<p class="subtitle">
    <?= date('Y-m-d H:i:s') ?> |
    Modo: <strong><?= $modo === 'corregir' ? '&#9888;&#65039; CORREGIR' : '&#128269; ESCANEAR' ?></strong> |
    Tiempo: <?= $tiempoFin ?>s |
    Subdominios DokuWiki: <?= count($resultados) ?> |
    Grupo: <strong style="color:#6366f1;"><?= htmlspecialchars($grupoBez) ?></strong>
</p>

<!-- Explicacion -->
<div class="explain">
    <h2>&#128161; Que hace este script</h2>
    <p><strong>OP 1 - bez admin_group:</strong> Agrega o actualiza <code>$conf['plugin']['bez']['admin_group'] = '<?= htmlspecialchars($grupoBez) ?>';</code> en <code>conf/local.php</code>.</p>
    <p><strong>OP 2 - Directivas DokuWiki:</strong> Establece en <code>conf/local.php</code>:</p>
    <ul style="margin:2px 0 6px 20px;font-size:0.95em;">
        <li><code>$conf['defaultgroup'] = 'lectura';</code></li>
        <li><code>$conf['superuser'] = '@admin';</code></li>
        <li><code>$conf['manager'] = 'manager';</code></li>
    </ul>
    <p><strong>OP 3 - users.auth.php:</strong> Busca usuarios con grupo <code>sie</code> y les agrega el grupo <code><?= htmlspecialchars($grupoBez) ?></code> (sin quitar ningun grupo existente).</p>
    <p style="margin-top:8px;"><strong>&#128274; Seguridad:</strong> Cada archivo se respalda como <code>archivo.bak_bezadmin_YYYYMMDD_HHMMSS</code> antes de modificar.</p>
</div>

<!-- Configurar nombre del grupo -->
<div class="grupo-config">
    <label for="inputGrupo">&#128272; Nombre del grupo BEZ Admin:</label>
    <input type="text" id="inputGrupo" value="<?= htmlspecialchars($grupoBez) ?>" placeholder="bez_admin" maxlength="30">
    <button onclick="cambiarGrupo()" class="btn btn-purple">Aplicar nombre</button>
    <div class="hint">Solo letras, numeros y guion bajo. Este grupo dara control total del plugin BEZ sin ser superusuario de DokuWiki.</div>
</div>

<!-- Resumen -->
<div class="summary">
    <div class="card"><div class="num blue"><?= count($resultados) ?></div><div class="label">Sistemas DokuWiki</div></div>
    <div class="card"><div class="num green"><?= $totalOK ?></div><div class="label">Ya configurados</div></div>
    <div class="card"><div class="num <?= $totalProblema > 0 ? 'red' : 'green' ?>"><?= $totalProblema ?></div><div class="label">Necesitan cambio</div></div>
    <div class="card"><div class="num purple"><?= $conteoFixes['LOCAL_PHP'] ?? 0 ?></div><div class="label">&#9881; bez admin_group</div></div>
    <div class="card"><div class="num <?= ($conteoFixes['DIRECTIVAS'] ?? 0) > 0 ? 'yellow' : 'green' ?>"><?= $conteoFixes['DIRECTIVAS'] ?? 0 ?></div><div class="label">&#9874; directivas DW</div></div>
    <div class="card"><div class="num pink"><?= $conteoFixes['USERS_AUTH'] ?? 0 ?></div><div class="label">&#128101; users.auth.php</div></div>
    <div class="card"><div class="num blue"><?= $totalUsuariosSie ?></div><div class="label">Usuarios SIE total</div></div>
    <div class="card"><div class="num <?= $totalNecesitanGrupo > 0 ? 'yellow' : 'green' ?>"><?= $totalNecesitanGrupo ?></div><div class="label">Necesitan grupo</div></div>
</div>

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

<!-- Botones principales -->
<div class="actions">
    <?php if (!empty($targetSub)): ?>
        <a href="?grupo=<?= urlencode($grupoBez) ?>" class="btn btn-gray">&#8592; Volver a todos</a>
        <?php if ($totalProblema > 0 && $modo !== 'corregir'): ?>
            <a href="?modo=corregir&sub=<?= urlencode($targetSub) ?>&grupo=<?= urlencode($grupoBez) ?>" class="btn btn-red"
               onclick="return confirm('Configurar BEZ Admin en <?= htmlspecialchars($targetSub, ENT_QUOTES) ?>?\n\nGrupo: <?= htmlspecialchars($grupoBez, ENT_QUOTES) ?>\n\nSe creara backup antes de modificar.')">
                &#128295; Configurar <?= htmlspecialchars($targetSub) ?>
            </a>
        <?php endif; ?>
    <?php else: ?>
        <a href="?modo=escanear&grupo=<?= urlencode($grupoBez) ?>" class="btn btn-blue">&#128269; Escanear todos</a>
        <?php if ($totalProblema > 0 && $modo !== 'corregir'): ?>
            <a href="?modo=corregir&grupo=<?= urlencode($grupoBez) ?>" class="btn btn-red"
               onclick="return confirm('ATENCION: Se van a configurar <?= $totalProblema ?> subdominios.\n\nGrupo BEZ Admin: <?= htmlspecialchars($grupoBez, ENT_QUOTES) ?>\n\nOperaciones:\n- OP 1: bez admin_group en conf/local.php\n- OP 2: defaultgroup=lectura, superuser=@admin, manager=manager\n- OP 3: Agregar grupo a usuarios SIE en users.auth.php\n\nSe creara backup de cada archivo.\n\nContinuar?')">
                &#128295; Configurar TODOS (<?= $totalProblema ?> subdominios)
            </a>
        <?php endif; ?>
    <?php endif; ?>
</div>

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

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

<!-- Tabla completa -->
<div class="section">
    <h2>&#128203; Todos los subdominios DokuWiki (<?= count($resultados) ?>)</h2>
    <div class="filter-bar">
        <input type="text" id="filtro" placeholder="Buscar..." oninput="filtrar()">
        <select id="filtroEstado" onchange="filtrar()">
            <option value="">Todos</option>
            <option value="err">Necesitan cambio</option>
            <option value="ok">Ya configurados</option>
        </select>
    </div>
    <div style="overflow-x:auto;">
    <table id="tabla">
        <thead>
            <tr>
                <th>#</th>
                <th>Subdominio</th>
                <th>bez admin_group</th>
                <th>Valor actual</th>
                <th>defaultgroup</th>
                <th>superuser</th>
                <th>manager</th>
                <th>Usuarios SIE</th>
                <th>Ya con grupo</th>
                <th>Necesitan grupo</th>
                <th>Estado</th>
            </tr>
        </thead>
        <tbody>
        <?php $i = 0; foreach ($resultados as $r): $i++; ?>
            <?php $tieneProblema = !empty($r['fixes']); ?>
            <tr class="<?= $tieneProblema ? 'row-err' : '' ?>"
                data-nombre="<?= strtolower($r['carpeta']) ?>"
                data-estado="<?= $tieneProblema ? 'err' : 'ok' ?>">
                <td><?= $i ?></td>
                <td><strong><?= htmlspecialchars($r['carpeta']) ?></strong></td>
                <td>
                    <?php if (!$r['local_php']['existe']): ?>
                        <span class="badge badge-err">No existe</span>
                    <?php elseif ($r['local_php']['correcto']): ?>
                        <span class="badge badge-ok">OK</span>
                    <?php elseif ($r['local_php']['tiene_conf']): ?>
                        <span class="badge badge-warn">Valor diferente</span>
                    <?php else: ?>
                        <span class="badge badge-purple">Falta agregar</span>
                    <?php endif; ?>
                </td>
                <td>
                    <?php if ($r['local_php']['tiene_conf']): ?>
                        <code><?= htmlspecialchars($r['local_php']['valor_actual']) ?></code>
                    <?php else: ?>
                        <span style="color:#94a3b8;">—</span>
                    <?php endif; ?>
                </td>
                <?php
                $dirKeys = ['defaultgroup', 'superuser', 'manager'];
                foreach ($dirKeys as $dk):
                    $d = $r['directivas'] ? $r['directivas']['directivas'][$dk] : null;
                ?>
                <td style="text-align:center;">
                    <?php if (!$d): ?>
                        <span style="color:#94a3b8;">—</span>
                    <?php elseif ($d['correcto']): ?>
                        <span class="badge badge-ok"><?= htmlspecialchars($d['actual']) ?></span>
                    <?php elseif ($d['actual'] !== null): ?>
                        <span class="badge badge-warn" title="Esperado: <?= htmlspecialchars($d['esperado']) ?>"><?= htmlspecialchars($d['actual']) ?></span>
                    <?php else: ?>
                        <span class="badge badge-err">no definido</span>
                    <?php endif; ?>
                </td>
                <?php endforeach; ?>
                <td style="text-align:center;">
                    <?php if ($r['users_auth'] && $r['users_auth']['existe']): ?>
                        <?= count($r['users_auth']['usuarios_sie']) ?>
                    <?php else: ?>
                        <span style="color:#94a3b8;">—</span>
                    <?php endif; ?>
                </td>
                <td style="text-align:center;">
                    <?php if ($r['users_auth'] && !empty($r['users_auth']['ya_tienen_grupo'])): ?>
                        <span class="badge badge-ok"><?= count($r['users_auth']['ya_tienen_grupo']) ?></span>
                    <?php else: ?>
                        <span style="color:#94a3b8;">0</span>
                    <?php endif; ?>
                </td>
                <td style="text-align:center;">
                    <?php if ($r['users_auth'] && !empty($r['users_auth']['necesitan_grupo'])): ?>
                        <span class="badge badge-err"><?= count($r['users_auth']['necesitan_grupo']) ?></span>
                    <?php else: ?>
                        <span style="color:#94a3b8;">0</span>
                    <?php endif; ?>
                </td>
                <td>
                    <?php if ($tieneProblema): ?>
                        <?php foreach ($r['fixes'] as $f):
                            $badgeClass = 'badge-info';
                            if ($f === 'LOCAL_PHP') $badgeClass = 'badge-purple';
                            elseif ($f === 'DIRECTIVAS') $badgeClass = 'badge-warn';
                            elseif ($f === 'USERS_AUTH') $badgeClass = 'badge-pink';
                        ?>
                            <span class="badge <?= $badgeClass ?>"><?= $f ?></span>
                        <?php endforeach; ?>
                    <?php else: ?>
                        <span class="badge badge-ok">OK</span>
                    <?php endif; ?>
                </td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    </div>
</div>

<!-- Detalle de usuarios SIE por subdominio -->
<?php
$subConUsuariosSie = array_filter($resultados, fn($r) => $r['users_auth'] && !empty($r['users_auth']['usuarios_sie']));
if (!empty($subConUsuariosSie)):
?>
<div class="section">
    <h2>&#128101; Detalle de usuarios SIE (<?= $totalUsuariosSie ?> en <?= count($subConUsuariosSie) ?> sistemas)</h2>
    <div style="columns:2;column-gap:20px;font-size:0.84em;">
    <?php foreach ($subConUsuariosSie as $r): ?>
        <div style="break-inside:avoid;margin-bottom:12px;padding:8px;border:1px solid #e2e8f0;border-radius:6px;">
            <strong style="color:#1e293b;"><?= htmlspecialchars($r['carpeta']) ?></strong>
            <span style="color:#64748b;font-size:0.9em;"> (<?= count($r['users_auth']['usuarios_sie']) ?> usuarios SIE)</span>
            <div style="margin-top:4px;">
            <?php foreach ($r['users_auth']['usuarios_sie'] as $u): ?>
                <div style="margin-left:8px;">
                    <?php if (in_array($u['usuario'], $r['users_auth']['ya_tienen_grupo'])): ?>
                        <span class="badge badge-ok">OK</span>
                    <?php else: ?>
                        <span class="badge badge-warn">+<?= htmlspecialchars($grupoBez) ?></span>
                    <?php endif; ?>
                    <strong><?= htmlspecialchars($u['usuario']) ?></strong>
                    <span style="color:#94a3b8;font-size:0.85em;">[<?= htmlspecialchars($u['grupos']) ?>]</span>
                </div>
            <?php endforeach; ?>
            </div>
        </div>
    <?php endforeach; ?>
    </div>
</div>
<?php endif; ?>

</div><!-- container -->

<script>
function cambiarGrupo() {
    var grupo = document.getElementById('inputGrupo').value.replace(/[^a-zA-Z0-9_]/g, '');
    if (!grupo) { alert('El nombre del grupo no puede estar vacio'); return; }
    window.location.href = '?grupo=' + encodeURIComponent(grupo);
}

function accionIndividual(modo) {
    var sub = document.getElementById('selectSub').value;
    if (!sub) { alert('Selecciona un subdominio primero'); return; }
    var grupo = document.getElementById('inputGrupo').value.replace(/[^a-zA-Z0-9_]/g, '') || '<?= htmlspecialchars($grupoBez) ?>';
    if (modo === 'corregir') {
        if (!confirm('Configurar BEZ Admin en ' + sub + '?\n\nGrupo: ' + grupo + '\nSe creara backup antes de modificar.')) return;
    }
    window.location.href = '?modo=' + modo + '&sub=' + encodeURIComponent(sub) + '&grupo=' + encodeURIComponent(grupo);
}

function filtrar() {
    var texto = document.getElementById('filtro').value.toLowerCase();
    var estado = document.getElementById('filtroEstado').value;
    var filas = document.getElementById('tabla').querySelectorAll('tbody tr');
    filas.forEach(function(tr) {
        var nombre = tr.getAttribute('data-nombre') || '';
        var est = tr.getAttribute('data-estado') || '';
        var show = true;
        if (texto && nombre.indexOf(texto) === -1) show = false;
        if (estado && est !== estado) show = false;
        tr.style.display = show ? '' : 'none';
    });
}

// Enter en input grupo
document.getElementById('inputGrupo').addEventListener('keypress', function(e) {
    if (e.key === 'Enter') cambiarGrupo();
});
</script>
</body>
</html>
