<?php
/**
 * MIGRADOR DE CHECKBOXES (PLUGIN DO) - SUBDOMINIOS SIE
 * =====================================================
 * Migra el estado de checkboxes/tareas del plugin "do" desde paginas origen
 * a paginas destino. El plugin "do" almacena tareas en base de datos SQLite.
 *
 * TABLAS AFECTADAS:
 *   tasks          - Definicion de tareas (page, md5, date, text, creator, pos)
 *   task_status    - Estado checked/unchecked (page, md5, status, closedby, msg)
 *   task_assignees - Usuarios asignados (page, md5, user)
 *   task_filename  - Archivos asociados (page, md5, filename, path)
 *
 * MAPEOS CONFIGURADOS:
 *   varios:menu:1  -->  proyectos:administrativos:1:1_responsabilidades
 *   varios:menu:2  -->  proyectos:administrativos:1:2_requisitos_eticos
 *   varios:menu:3  -->  proyectos:administrativos:1:3_recursos_humanos
 *
 * MODOS:
 *   ?modo=escanear   (default) - Solo detectar, no modificar nada
 *   ?modo=corregir              - Migrar tareas en TODOS los afectados
 *   ?sub=nombre                 - Solo un subdominio especifico
 *
 * LOGICA:
 *   - Copia las tareas de la pagina origen a la pagina destino
 *   - Si la tarea (mismo md5) ya existe en destino, la salta (no duplica)
 *   - Crea backup de la BD antes de modificar
 */

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

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

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

// Mapeos: origen => destino (page IDs)
$mapeos = [
    'varios:menu:1' => 'proyectos:administrativos:1:1_responsabilidades',
    'varios:menu:2' => 'proyectos:administrativos:1:2_requisitos_eticos',
    'varios:menu:3' => 'proyectos:administrativos:1:3_recursos_humanos',
];

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

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

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

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

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

// =====================================================================
//  FUNCIONES
// =====================================================================

/**
 * Busca la base de datos SQLite del plugin "do"
 * Ubicaciones posibles: data/meta/do.sqlite3 o meta/do.sqlite3
 */
function encontrarDB($subPath)
{
    $posibles = [
        $subPath . '/data/meta/do.sqlite3',
        $subPath . '/data/meta/do.sqlite',
    ];
    foreach ($posibles as $p) {
        if (file_exists($p)) return $p;
    }
    return null;
}

/**
 * Abre conexion PDO a la base de datos SQLite
 */
function abrirDB($dbPath)
{
    try {
        $pdo = new PDO('sqlite:' . $dbPath);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    } catch (Exception $e) {
        return null;
    }
}

/**
 * Verifica si una tabla existe en la base de datos
 */
function tablaExiste($pdo, $tabla)
{
    try {
        $stmt = $pdo->query("SELECT name FROM sqlite_master WHERE type='table' AND name='" . SQLite3::escapeString($tabla) . "'");
        return $stmt->fetch() !== false;
    } catch (Exception $e) {
        return false;
    }
}

/**
 * Cuenta tareas de una pagina en la BD
 */
function contarTareas($pdo, $pageId)
{
    try {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM tasks WHERE page = ?");
        $stmt->execute([$pageId]);
        return (int)$stmt->fetchColumn();
    } catch (Exception $e) {
        return 0;
    }
}

/**
 * Obtiene todas las tareas de una pagina con su estado
 */
function obtenerTareas($pdo, $pageId)
{
    $tareas = [];
    try {
        $stmt = $pdo->prepare("SELECT * FROM tasks WHERE page = ?");
        $stmt->execute([$pageId]);
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $md5 = $row['md5'];
            $tareas[$md5] = [
                'task'      => $row,
                'status'    => null,
                'assignees' => [],
                'filename'  => null,
            ];
        }
    } catch (Exception $e) { return $tareas; }

    if (empty($tareas)) return $tareas;

    $md5List = array_keys($tareas);
    $placeholders = implode(',', array_fill(0, count($md5List), '?'));

    // Obtener estados
    try {
        $stmt = $pdo->prepare("SELECT * FROM task_status WHERE page = ? AND md5 IN ({$placeholders})");
        $stmt->execute(array_merge([$pageId], $md5List));
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $tareas[$row['md5']]['status'] = $row;
        }
    } catch (Exception $e) {}

    // Obtener assignees
    if (tablaExiste($pdo, 'task_assignees')) {
        try {
            $stmt = $pdo->prepare("SELECT * FROM task_assignees WHERE page = ? AND md5 IN ({$placeholders})");
            $stmt->execute(array_merge([$pageId], $md5List));
            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                $tareas[$row['md5']]['assignees'][] = $row;
            }
        } catch (Exception $e) {}
    }

    // Obtener filenames
    if (tablaExiste($pdo, 'task_filename')) {
        try {
            $stmt = $pdo->prepare("SELECT * FROM task_filename WHERE page = ? AND md5 IN ({$placeholders})");
            $stmt->execute(array_merge([$pageId], $md5List));
            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                $tareas[$row['md5']]['filename'] = $row;
            }
        } catch (Exception $e) {}
    }

    return $tareas;
}

/**
 * Cuenta cuantas tareas del origen necesitan accion en el destino.
 * "Faltante" = la tarea no existe en destino, O la tarea existe pero le falta el STATUS.
 */
function contarFaltantes($pdo, $srcPage, $dstPage)
{
    $srcTareas = contarTareas($pdo, $srcPage);
    if ($srcTareas === 0) return ['src' => 0, 'dst' => 0, 'faltantes' => 0];

    $dstTareas = contarTareas($pdo, $dstPage);

    // Obtener tareas completas del origen (con status)
    $srcData = obtenerTareas($pdo, $srcPage);
    $dstData = obtenerTareas($pdo, $dstPage);

    // Mapear destino por md5 y por texto
    $dstMd5s = array_keys($dstData);
    $dstByText = [];
    foreach ($dstData as $md5 => $d) {
        $dstByText[trim($d['task']['text'] ?? '')] = $md5;
    }

    $faltantes = 0;
    foreach ($srcData as $srcMd5 => $srcInfo) {
        $srcStatus = $srcInfo['status'];
        // Si el origen no tiene status (no esta checkeado), no hay nada que migrar
        if (!$srcStatus) continue;

        // Buscar la tarea en destino (por md5 o por texto)
        $dstMd5Match = null;
        if (in_array($srcMd5, $dstMd5s)) {
            $dstMd5Match = $srcMd5;
        } elseif (isset($dstByText[trim($srcInfo['task']['text'] ?? '')])) {
            $dstMd5Match = $dstByText[trim($srcInfo['task']['text'] ?? '')];
        }

        if ($dstMd5Match !== null) {
            // Tarea existe en destino: verificar si le falta el status o tiene msg incorrecto
            $dstStatus = $dstData[$dstMd5Match]['status'] ?? null;
            if (!$dstStatus) {
                $faltantes++; // Tarea existe pero NO tiene status -> pendiente
            } else {
                // Status existe pero msg no es 'Completado' ni 'No Aplica' -> pendiente
                $dstMsg = $dstStatus['msg'] ?? '';
                if (empty($dstMsg) || !in_array($dstMsg, ['Completado', 'No Aplica'])) {
                    $faltantes++;
                }
            }
        } else {
            $faltantes++; // Tarea no existe en destino -> pendiente
        }
    }

    return ['src' => $srcTareas, 'dst' => $dstTareas, 'faltantes' => $faltantes];
}

/**
 * Analiza un subdominio
 */
function analizarSubdominio($subPath, $carpeta, $mapeos)
{
    $r = [
        'carpeta'    => $carpeta,
        'tiene_doku' => false,
        'tiene_db'   => false,
        'mapeos'     => [],
        'total_src'  => 0,
        'pendientes' => 0,
        'estado'     => 'NO_DOKU',
    ];

    if (!file_exists($subPath . '/doku.php')) return $r;
    $r['tiene_doku'] = true;

    $dbPath = encontrarDB($subPath);
    if (!$dbPath) {
        $r['estado'] = 'SIN_DB';
        return $r;
    }

    $pdo = abrirDB($dbPath);
    if (!$pdo) {
        $r['estado'] = 'DB_ERROR';
        return $r;
    }
    $r['tiene_db'] = true;

    if (!tablaExiste($pdo, 'tasks')) {
        $r['estado'] = 'SIN_TABLA';
        return $r;
    }

    foreach ($mapeos as $srcId => $dstId) {
        $conteo = contarFaltantes($pdo, $srcId, $dstId);

        $m = [
            'src_id'    => $srcId,
            'dst_id'    => $dstId,
            'src_count' => $conteo['src'],
            'dst_count' => $conteo['dst'],
            'faltantes' => $conteo['faltantes'],
            'estado'    => 'SIN_TAREAS',
        ];

        if ($conteo['src'] === 0) {
            $m['estado'] = 'SIN_TAREAS';
        } elseif ($conteo['faltantes'] === 0) {
            $m['estado'] = 'YA_MIGRADO';
        } else {
            $m['estado'] = 'PENDIENTE';
            $r['pendientes']++;
        }

        $r['total_src'] += $conteo['src'];
        $r['mapeos'][] = $m;
    }

    $pdo = null;
    $r['estado'] = $r['pendientes'] > 0 ? 'PENDIENTE' : 'OK';
    return $r;
}

/**
 * Migra las tareas de las paginas origen a destino
 */
function corregirSubdominio($subPath, $carpeta, $mapeos)
{
    $resultados = [];
    $timestamp = date('Ymd_His');

    $dbPath = encontrarDB($subPath);
    if (!$dbPath) {
        return [['mapeo' => 'N/A', 'ok' => false, 'msg' => 'BD no encontrada', 'count' => 0]];
    }

    // Backup de la BD
    $backupPath = $dbPath . ".bak_migchk_{$timestamp}";
    if (!@copy($dbPath, $backupPath)) {
        return [['mapeo' => 'N/A', 'ok' => false, 'msg' => 'No se pudo crear backup de BD', 'count' => 0]];
    }
    $backupName = basename($backupPath);

    $pdo = abrirDB($dbPath);
    if (!$pdo) {
        return [['mapeo' => 'N/A', 'ok' => false, 'msg' => 'No se pudo abrir BD', 'count' => 0]];
    }

    foreach ($mapeos as $srcId => $dstId) {
        $srcTareas = obtenerTareas($pdo, $srcId);
        if (empty($srcTareas)) {
            $resultados[] = [
                'mapeo' => "{$srcId} -> {$dstId}",
                'ok'    => true,
                'msg'   => 'Sin tareas en origen',
                'count' => 0,
            ];
            continue;
        }

        // Obtener tareas existentes en destino (por md5 y por texto)
        $dstTareas = obtenerTareas($pdo, $dstId);
        $dstMd5s = array_keys($dstTareas);
        $dstTexts = [];
        foreach ($dstTareas as $dt) {
            $dstTexts[trim($dt['task']['text'] ?? '')] = true;
        }

        $migrados = 0;
        $saltados = 0;
        $statusSync = 0;

        // Mapear destino por texto para encontrar correspondencias
        $dstByText = [];
        foreach ($dstTareas as $dMd5 => $dt) {
            $dstByText[trim($dt['task']['text'] ?? '')] = $dMd5;
        }

        try {
            $pdo->beginTransaction();

            foreach ($srcTareas as $md5 => $data) {
                $task = $data['task'];
                $srcStatus = $data['status'];

                // Buscar si ya existe en destino (por md5 o por texto)
                $dstMd5Match = null;
                if (in_array($md5, $dstMd5s)) {
                    $dstMd5Match = $md5;
                } elseif (isset($dstByText[trim($task['text'] ?? '')])) {
                    $dstMd5Match = $dstByText[trim($task['text'] ?? '')];
                }

                if ($dstMd5Match !== null) {
                    // Tarea ya existe en destino -> verificar si necesita STATUS o correccion de msg
                    if ($srcStatus) {
                        $dstStatus = $dstTareas[$dstMd5Match]['status'] ?? null;
                        if (!$dstStatus) {
                            // Destino NO tiene status, origen SI -> insertar status
                            $s = $srcStatus;
                            $msgFinal = (!empty($s['msg']) && in_array($s['msg'], ['Completado', 'No Aplica']))
                                ? $s['msg'] : 'Completado';
                            $stmt = $pdo->prepare("INSERT OR IGNORE INTO task_status (page, md5, status, closedby, msg) VALUES (?, ?, ?, ?, ?)");
                            $stmt->execute([$dstId, $dstMd5Match, $s['status'] ?? date('Y-m-d'), $s['closedby'] ?? 'system', $msgFinal]);
                            $statusSync++;
                        } else {
                            // Status existe pero msg puede ser incorrecto -> corregir a 'Completado'
                            $dstMsg = $dstStatus['msg'] ?? '';
                            if (empty($dstMsg) || !in_array($dstMsg, ['Completado', 'No Aplica'])) {
                                $stmt = $pdo->prepare("UPDATE task_status SET msg = 'Completado' WHERE page = ? AND md5 = ?");
                                $stmt->execute([$dstId, $dstMd5Match]);
                                $statusSync++;
                            }
                        }
                    }
                    $saltados++;
                    continue;
                }

                // Tarea NO existe en destino -> insertar completa
                $stmt = $pdo->prepare("INSERT OR IGNORE INTO tasks (page, md5, date, text, creator, pos) VALUES (?, ?, ?, ?, ?, ?)");
                $stmt->execute([$dstId, $md5, $task['date'] ?? '', $task['text'] ?? '', $task['creator'] ?? '', $task['pos'] ?? 0]);

                // Insertar estado si existe
                if ($srcStatus) {
                    $s = $srcStatus;
                    $msgFinal = (!empty($s['msg']) && in_array($s['msg'], ['Completado', 'No Aplica']))
                        ? $s['msg'] : 'Completado';
                    $stmt = $pdo->prepare("INSERT OR IGNORE INTO task_status (page, md5, status, closedby, msg) VALUES (?, ?, ?, ?, ?)");
                    $stmt->execute([$dstId, $md5, $s['status'] ?? date('Y-m-d'), $s['closedby'] ?? 'system', $msgFinal]);
                }

                // Insertar assignees
                if (!empty($data['assignees']) && tablaExiste($pdo, 'task_assignees')) {
                    $stmt = $pdo->prepare("INSERT OR IGNORE INTO task_assignees (page, md5, user) VALUES (?, ?, ?)");
                    foreach ($data['assignees'] as $a) {
                        $stmt->execute([$dstId, $md5, $a['user'] ?? '']);
                    }
                }

                // Insertar filename si existe
                if ($data['filename'] && tablaExiste($pdo, 'task_filename')) {
                    $f = $data['filename'];
                    $stmt = $pdo->prepare("INSERT OR IGNORE INTO task_filename (page, md5, filename, path) VALUES (?, ?, ?, ?)");
                    $stmt->execute([$dstId, $md5, $f['filename'] ?? '', $f['path'] ?? '']);
                }

                $migrados++;
            }

            $pdo->commit();
        } catch (Exception $e) {
            $pdo->rollBack();
            $resultados[] = [
                'mapeo' => "{$srcId} -> {$dstId}",
                'ok'    => false,
                'msg'   => "Error SQL: " . $e->getMessage(),
                'count' => 0,
            ];
            continue;
        }

        $resultados[] = [
            'mapeo' => "{$srcId} -> {$dstId}",
            'ok'    => true,
            'msg'   => "Migradas {$migrados} tareas nuevas, {$statusSync} estados sincronizados, {$saltados} saltadas. Backup: {$backupName}",
            'count' => $migrados + $statusSync,
        ];
    }

    $pdo = null;
    return $resultados;
}

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

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

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

foreach ($carpetas as $carpeta) {
    $subPath = $basePath . '/' . $carpeta;
    $r = analizarSubdominio($subPath, $carpeta, $mapeos);
    if (!$r['tiene_doku']) continue;
    $resultados[] = $r;

    if ($modo === 'corregir' && $r['estado'] === 'PENDIENTE') {
        $fix = corregirSubdominio($subPath, $carpeta, $mapeos);
        $correcciones[$carpeta] = $fix;
    }
}

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

$totalOK       = count(array_filter($resultados, fn($r) => $r['estado'] === 'OK'));
$totalPendiente = count(array_filter($resultados, fn($r) => $r['estado'] === 'PENDIENTE'));
$totalSinDB    = count(array_filter($resultados, fn($r) => $r['estado'] === 'SIN_DB'));

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

if ($esCLI) {
    echo "================================================================\n";
    echo " MIGRADOR DE CHECKBOXES (PLUGIN DO) - SIE\n";
    echo " " . date('Y-m-d H:i:s') . " | Modo: {$modo} | Tiempo: {$tiempoFin}s\n";
    echo "================================================================\n\n";
    echo "Total: " . count($resultados) . " | OK: {$totalOK} | Pendientes: {$totalPendiente} | Sin BD: {$totalSinDB}\n\n";

    $afectados = array_filter($resultados, fn($r) => $r['estado'] === 'PENDIENTE');
    foreach ($afectados as $r) {
        echo "  {$r['carpeta']} ({$r['total_src']} tareas origen)\n";
        if (isset($correcciones[$r['carpeta']])) {
            foreach ($correcciones[$r['carpeta']] as $fix) {
                echo "    " . ($fix['ok'] ? 'OK' : 'ERR') . ": {$fix['msg']}\n";
            }
        }
    }
    exit(0);
}

// =====================================================================
//  SALIDA HTML
// =====================================================================
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Migrador Checkboxes (do) - 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(150px, 1fr)); gap: 12px; margin-bottom: 20px; }
    .card { background: #fff; border-radius: 10px; padding: 14px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .card .num { font-size: 1.8em; font-weight: 700; }
    .card .label { font-size: 0.8em; color: #64748b; }
    .green { color: #16a34a; } .red { color: #dc2626; } .yellow { color: #d97706; } .blue { color: #2563eb; }
    .section { background: #fff; border-radius: 10px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .section h2 { font-size: 1.1em; margin-bottom: 12px; }
    .explain { background: #eff6ff; border: 1px solid #93c5fd; border-radius: 10px; padding: 16px; margin-bottom: 20px; }
    .explain h2 { color: #1e40af; margin-bottom: 8px; font-size: 1em; }
    .explain p { font-size: 0.86em; color: #334155; margin-bottom: 4px; }
    .explain code { background: #dbeafe; color: #1e40af; padding: 1px 4px; border-radius: 3px; font-size: 0.9em; }
    .mapeo-box { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 10px 14px; margin-bottom: 8px; font-size: 0.86em; }
    .mapeo-arrow { color: #2563eb; font-weight: 700; margin: 0 6px; }
    .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-gray { background: #64748b; color: #fff; }
    .result-box { border-radius: 10px; padding: 16px; margin-bottom: 20px; }
    .result-ok { background: #f0fdf4; border: 1px solid #86efac; }
    .result-ok strong { color: #166534; }
    .result-err { background: #fef2f2; border: 1px solid #fecaca; }
    table { width: 100%; border-collapse: collapse; font-size: 0.83em; }
    th { text-align: left; padding: 8px 6px; border-bottom: 2px solid #e2e8f0; color: #475569; font-size: 0.85em; }
    td { padding: 7px 6px; border-bottom: 1px solid #f1f5f9; }
    tr:hover { background: #f8fafc; }
    tr.row-pend { background: #fffbeb; }
    tr.row-pend:hover { background: #fef3c7; }
    .badge { display: inline-block; padding: 2px 7px; border-radius: 4px; font-size: 0.76em; font-weight: 600; }
    .badge-ok { background: #dcfce7; color: #166534; }
    .badge-err { background: #fee2e2; color: #991b1b; }
    .badge-warn { background: #fef3c7; color: #92400e; }
    .badge-gray { background: #f1f5f9; color: #64748b; }
    .badge-fix { background: #dbeafe; color: #1e40af; }
    .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>&#9745; Migrador de Checkboxes (plugin do) - SIE</h1>
<p class="subtitle">
    <?= date('Y-m-d H:i:s') ?> |
    Modo: <strong><?= $modo === 'corregir' ? '&#9888;&#65039; MIGRAR' : '&#128269; ESCANEAR' ?></strong> |
    Tiempo: <?= $tiempoFin ?>s |
    Sistemas: <?= count($resultados) ?>
</p>

<div class="explain">
    <h2>&#128161; Que hace este script</h2>
    <p><strong>Proposito:</strong> Migra el estado de checkboxes/tareas del plugin <code>do</code> desde paginas antiguas a paginas nuevas. El estado se almacena en la base de datos SQLite <code>do.sqlite3</code>.</p>
    <p><strong>Mapeos:</strong></p>
    <?php foreach ($mapeos as $src => $dst): ?>
    <div class="mapeo-box">
        <code><?= htmlspecialchars($src) ?></code>
        <span class="mapeo-arrow">&rarr;</span>
        <code><?= htmlspecialchars($dst) ?></code>
    </div>
    <?php endforeach; ?>
    <p style="margin-top:8px;"><strong>Anti-duplicado:</strong> Verifica por md5 Y por texto del task. Si ya existe, lo salta. Crea backup de la BD antes de modificar.</p>
</div>

<div class="summary">
    <div class="card"><div class="num blue"><?= count($resultados) ?></div><div class="label">Total DokuWiki</div></div>
    <div class="card"><div class="num green"><?= $totalOK ?></div><div class="label">Sin pendientes</div></div>
    <div class="card"><div class="num <?= $totalPendiente > 0 ? 'yellow' : 'green' ?>"><?= $totalPendiente ?></div><div class="label">Con migracion pendiente</div></div>
    <div class="card"><div class="num <?= $totalSinDB > 0 ? 'red' : 'green' ?>"><?= $totalSinDB ?></div><div class="label">Sin BD do.sqlite3</div></div>
</div>

<div class="actions">
    <a href="?modo=escanear" class="btn btn-blue">&#128269; Escanear todos</a>
    <?php if ($totalPendiente > 0 && $modo !== 'corregir'): ?>
        <a href="?modo=corregir" class="btn btn-red"
           onclick="return confirm('ATENCION: Esto va a migrar tareas/checkboxes en <?= $totalPendiente ?> sistemas.\n\nSe creara backup de do.sqlite3 antes de modificar.\nTareas que ya existen en destino se saltan.\n\nContinuar?')">
            &#9745; Migrar en <?= $totalPendiente ?> sistemas
        </a>
    <?php endif; ?>
    <?php if (!empty($targetSub)): ?>
        <a href="?" class="btn btn-gray">Ver todos</a>
    <?php endif; ?>
</div>

<?php if ($modo === 'corregir' && !empty($correcciones)): ?>
<?php
$totalFixOK = 0; $totalFixErr = 0; $totalMig = 0;
foreach ($correcciones as $fixes) {
    foreach ($fixes as $f) {
        if ($f['ok']) { $totalFixOK++; $totalMig += $f['count']; }
        else { $totalFixErr++; }
    }
}
?>
<div class="result-box <?= $totalFixErr > 0 ? 'result-err' : 'result-ok' ?>">
    <strong>&#9989; Resultado: <?= $totalFixOK ?> mapeos procesados, <?= $totalFixErr ?> errores, <?= $totalMig ?> tareas migradas</strong>
    <table style="margin-top:10px;">
        <thead><tr><th>Subdominio</th><th>Mapeo</th><th>Resultado</th><th>Detalle</th></tr></thead>
        <tbody>
        <?php foreach ($correcciones as $carpeta => $fixes): ?>
            <?php foreach ($fixes as $f): ?>
            <tr>
                <td><strong><?= htmlspecialchars($carpeta) ?></strong></td>
                <td><code style="font-size:0.85em;"><?= htmlspecialchars($f['mapeo']) ?></code></td>
                <td><span class="badge <?= $f['ok'] ? 'badge-ok' : 'badge-err' ?>"><?= $f['ok'] ? ($f['count'] > 0 ? 'MIGRADO' : 'SIN CAMBIOS') : 'ERROR' ?></span></td>
                <td style="font-size:0.85em;"><?= htmlspecialchars($f['msg']) ?></td>
            </tr>
            <?php endforeach; ?>
        <?php endforeach; ?>
        </tbody>
    </table>
</div>
<?php endif; ?>

<div class="section">
    <h2>&#128203; Todos los sistemas (<?= 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="pend">Con pendientes</option>
            <option value="OK">Solo OK</option>
        </select>
    </div>
    <table id="tabla">
        <thead>
            <tr>
                <th>#</th>
                <th>Subdominio</th>
                <th>BD</th>
                <th>Estado</th>
                <th>Tareas origen</th>
                <th>Detalle mapeos</th>
            </tr>
        </thead>
        <tbody>
        <?php $i = 0; foreach ($resultados as $r): $i++; ?>
            <?php $rowClass = $r['estado'] === 'PENDIENTE' ? 'row-pend' : ''; ?>
            <tr class="<?= $rowClass ?>" data-name="<?= htmlspecialchars(strtolower($r['carpeta'])) ?>" data-estado="<?= $r['estado'] === 'OK' || $r['estado'] === 'SIN_DB' || $r['estado'] === 'SIN_TABLA' ? 'OK' : 'pend' ?>">
                <td><?= $i ?></td>
                <td><strong><?= htmlspecialchars($r['carpeta']) ?></strong></td>
                <td>
                    <?php if ($r['tiene_db']): ?>
                        <span class="badge badge-ok">SI</span>
                    <?php else: ?>
                        <span class="badge badge-gray"><?= htmlspecialchars($r['estado']) ?></span>
                    <?php endif; ?>
                </td>
                <td>
                    <?php
                    switch ($r['estado']) {
                        case 'OK': echo '<span class="badge badge-ok">OK</span>'; break;
                        case 'PENDIENTE': echo '<span class="badge badge-warn">PENDIENTE (' . $r['pendientes'] . ')</span>'; break;
                        case 'SIN_DB': echo '<span class="badge badge-gray">SIN BD</span>'; break;
                        case 'SIN_TABLA': echo '<span class="badge badge-gray">SIN TABLA</span>'; break;
                        default: echo '<span class="badge badge-err">' . htmlspecialchars($r['estado']) . '</span>';
                    }
                    ?>
                </td>
                <td><?= $r['total_src'] ?></td>
                <td>
                    <?php if (!empty($r['mapeos'])): ?>
                        <?php foreach ($r['mapeos'] as $m): ?>
                            <?php
                            $bc = 'badge-gray'; $lb = $m['estado'];
                            switch ($m['estado']) {
                                case 'PENDIENTE': $bc = 'badge-warn'; $lb = "PEND({$m['faltantes']})"; break;
                                case 'YA_MIGRADO': $bc = 'badge-ok'; $lb = 'OK'; break;
                                case 'SIN_TAREAS': $bc = 'badge-gray'; $lb = 'VACIO'; break;
                            }
                            ?>
                            <span class="badge <?= $bc ?>" title="<?= htmlspecialchars($m['src_id']) ?> -> <?= htmlspecialchars($m['dst_id']) ?> (src:<?= $m['src_count'] ?> dst:<?= $m['dst_count'] ?>)"><?= $lb ?></span>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
</div>

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