<?php
/**
 * relinear_productos_hosting.php
 * UTILERÍA PREMIUM DE ALINEACIÓN Y RECONCILIACIÓN DE BASE DE DATOS DUAL
 * 
 * Este script alinea los identificadores de productos desfasados entre la base de datos
 * principal y la secundaria para asegurar que la replicación con DualPDO funcione sin conflictos.
 */

// Desactivar el límite de tiempo de ejecución
ini_set('max_execution_time', 600);
set_time_limit(600);

// Configuración por defecto (Hosting de Producción)
$host = 'localhost';
$user = 'farmacia_onlydi2025';
$pass = '1corintios13';
$db_principal = 'farmacia_nadiecomoel2026';
$db_secundaria = 'farmacia_nadiecomoel';

// Autodetectar si estamos en entorno local
$is_local = (php_sapi_name() === 'cli' || strpos($_SERVER['HTTP_HOST'] ?? '', 'localhost') !== false || strpos($_SERVER['HTTP_HOST'] ?? '', '127.0.0.1') !== false);
if ($is_local) {
    $user = 'root';
    $pass = '';
    $db_principal = 'host_nadiecomoel2026';
    $db_secundaria = 'host_nadiecomoel';
} else {
    // Autodetectar configuración desde los archivos de los sub-sistemas
    if (file_exists(__DIR__ . '/SISTEMA1WEB/db_config.php')) {
        $conf1 = include(__DIR__ . '/SISTEMA1WEB/db_config.php');
        if (is_array($conf1)) {
            $host = $conf1['host'] ?? $host;
            $db_principal = $conf1['dbname'] ?? $db_principal;
            $user = $conf1['user'] ?? $user;
            $pass = $conf1['pass'] ?? $pass;
        }
    }
    if (file_exists(__DIR__ . '/SISTEMA2WEB/config/db_connection.php')) {
        $content = file_get_contents(__DIR__ . '/SISTEMA2WEB/config/db_connection.php');
        if (preg_match('/\$db\s*=\s*[\'"]([^\'"]+)[\'"]/', $content, $matches)) {
            $db_secundaria = $matches[1];
        }
        if (preg_match('/\$user\s*=\s*[\'"]([^\'"]+)[\'"]/', $content, $matches)) {
            $user = $matches[1];
        }
        if (preg_match('/\$password\s*=\s*[\'"]([^\'"]+)[\'"]/', $content, $matches)) {
            $pass = $matches[1];
        }
    }
}

// Procesar la solicitud AJAX de alineación o ejecución CLI
if ((isset($_GET['action']) && $_GET['action'] === 'run') || php_sapi_name() === 'cli') {
    header('Content-Type: text/plain; charset=utf-8');
    header('Cache-Control: no-cache');
    
    // Función auxiliar para imprimir logs en tiempo real
    function logMsg($msg) {
        echo $msg . "\n";
        if (ob_get_level() > 0) {
            ob_flush();
        }
        flush();
    }
    
    try {
        logMsg("Iniciando conexión a bases de datos...");
        $pdo1 = new PDO("mysql:host=$host;dbname=$db_principal;charset=utf8mb4", $user, $pass, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
            PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
        ]);
        $pdo2 = new PDO("mysql:host=$host;dbname=$db_secundaria;charset=utf8mb4", $user, $pass, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
            PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
        ]);
        logMsg("Conexión exitosa a ambas bases de datos.");
        
        // Tablas que contienen producto_id
        $refTables = [
            'ajustes_inventario',
            'compras_detalle',
            'detalle_pedidos',
            'detalle_traslados',
            'detalle_ventas',
            'fel_producto_mapping',
            'ingresos_sucursal',
            'inventario_movimientos',
            'inventario_sucursal',
            'lote',
            'movimientos_inventario',
            'ordenes_compra_detalle',
            'producto_lugares_compra',
            'producto_presentaciones',
            'productos_costo_promedio',
            'promocion_productos',
            'sistema_eventos',
            'ventas_recetas'
        ];

        // 0. Verificar y restaurar índices en la base secundaria si faltaran
        logMsg("\n--- Paso 0: Verificando y restaurando índices en la base secundaria ---");
        
        // Ejecutar REPAIR TABLE en todas las tablas para evitar corrupción de índices de MyISAM
        logMsg("  Reparando índices de MyISAM en la base secundaria...");
        $stmtT = $pdo2->prepare("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?");
        $stmtT->execute([$db_secundaria]);
        $allTables = $stmtT->fetchAll(PDO::FETCH_COLUMN);
        $stmtT->closeCursor();
        
        foreach ($allTables as $tName) {
            $stmtR = $pdo2->query("REPAIR TABLE `$db_secundaria`.`$tName`");
            $stmtR->fetchAll();
            $stmtR->closeCursor();
        }
        logMsg("  ✓ Reparación de tablas MyISAM completada.");

        $tablesWithoutKeys = [];
        $res = $pdo2->query("
            SELECT t.TABLE_NAME 
            FROM information_schema.TABLES t 
            LEFT JOIN information_schema.TABLE_CONSTRAINTS tc 
                ON t.TABLE_SCHEMA = tc.TABLE_SCHEMA 
                AND t.TABLE_NAME = tc.TABLE_NAME 
                AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
            WHERE t.TABLE_SCHEMA = '$db_secundaria' 
            AND tc.CONSTRAINT_NAME IS NULL
        ")->fetchAll(PDO::FETCH_COLUMN);
        
        if (count($res) > 0) {
            logMsg("  Se detectaron " . count($res) . " tablas sin llave primaria. Buscando índices en el archivo SQL dump...");
            $dumpPaths = [
                __DIR__ . '/farmacia_nadiecomoel.sql',
                __DIR__ . '/SISTEMA2WEB/farmacia_nadiecomoel.sql',
                __DIR__ . '/WEBHOSTING7/SISTEMA2WEB/farmacia_nadiecomoel.sql'
            ];
            $dumpFile = null;
            foreach ($dumpPaths as $path) {
                if (file_exists($path)) {
                    $dumpFile = $path;
                    break;
                }
            }
            
            if ($dumpFile) {
                logMsg("  Archivo SQL dump encontrado en: " . basename($dumpFile) . ". Aplicando índices faltantes...");
                $handle = fopen($dumpFile, 'r');
                $lineNum = 0;
                $query = '';
                $appliedCount = 0;
                $errorCount = 0;
                
                while (($line = fgets($handle)) !== false) {
                    $lineNum++;
                    if ($lineNum < 380000) {
                        continue;
                    }
                    
                    $trimmed = trim($line);
                    if ($trimmed === '' || strpos($trimmed, '--') === 0 || strpos($trimmed, '/*') === 0) {
                        continue;
                    }
                    
                    if ($query === '') {
                        $queryStartLine = $lineNum;
                    }
                    $query .= $line;
                    
                    if (substr(rtrim($trimmed), -1) === ';') {
                        if (stripos($query, 'ALTER TABLE') !== false && (stripos($query, 'ADD PRIMARY KEY') !== false || stripos($query, 'ADD KEY') !== false || stripos($query, 'ADD UNIQUE KEY') !== false)) {
                            try {
                                $pdo2->exec($query);
                                $appliedCount++;
                            } catch (Exception $e) {
                                if (strpos($e->getMessage(), 'Multiple primary key defined') === false && strpos($e->getMessage(), 'Duplicate key name') === false) {
                                    $errorCount++;
                                }
                            }
                        }
                        $query = '';
                    }
                }
                fclose($handle);
                logMsg("  ✓ Se aplicaron $appliedCount consultas de índices con éxito (errores no-duplicados: $errorCount).");
            } else {
                logMsg("  [ADVERTENCIA]: No se encontró el archivo 'farmacia_nadiecomoel.sql' para restaurar los índices.");
            }
        } else {
            logMsg("  Todas las tablas de la base secundaria ya cuentan con llaves primarias.");
        }

        // 1. Corregir AUTO_INCREMENT y estructura de columnas primero en la secundaria
        logMsg("\n--- Paso 1: Asegurando AUTO_INCREMENT en la base secundaria ---");
        $tablesToVerify = $pdo1->query("
            SELECT c.TABLE_NAME, c.COLUMN_NAME, c.COLUMN_TYPE
            FROM information_schema.COLUMNS c
            JOIN information_schema.TABLES t ON c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME
            WHERE c.TABLE_SCHEMA = '$db_principal' 
            AND c.EXTRA LIKE '%auto_increment%'
            ORDER BY c.TABLE_NAME
        ")->fetchAll(PDO::FETCH_ASSOC);

        foreach ($tablesToVerify as $t) {
            $tableName = $t['TABLE_NAME'];
            $colName = $t['COLUMN_NAME'];
            $colType = $t['COLUMN_TYPE'];
            
            $col2 = $pdo2->query("
                SELECT EXTRA FROM information_schema.COLUMNS 
                WHERE TABLE_SCHEMA = '$db_secundaria' 
                AND TABLE_NAME = '$tableName' 
                AND COLUMN_NAME = '$colName'
            ")->fetch(PDO::FETCH_ASSOC);
            
            if ($col2 && strpos($col2['EXTRA'], 'auto_increment') === false) {
                $pdo2->exec("ALTER TABLE `$db_secundaria`.`$tableName` MODIFY `$colName` $colType NOT NULL AUTO_INCREMENT");
                logMsg("  ✓ AUTO_INCREMENT habilitado en `$db_secundaria`.`$tableName`.`$colName`");
            }
        }

        // 2. Procesar productos que SOLO existen en la base secundaria (moverlos a un rango alto temporal)
        logMsg("\n--- Paso 2: Buscando productos exclusivos de la base secundaria ---");
        $onlySec = $pdo2->query("
            SELECT p2.id as id_secundario, p2.CodigoInterno, p2.NombreComercial 
            FROM `$db_secundaria`.`productos` p2
            LEFT JOIN `$db_principal`.`productos` p1 ON p1.CodigoInterno = p2.CodigoInterno
            WHERE p1.CodigoInterno IS NULL AND p2.CodigoInterno IS NOT NULL AND p2.CodigoInterno != ''
        ")->fetchAll(PDO::FETCH_ASSOC);

        $tempIdBase = 1000000;
        $tempMappingOnlySec = [];

        logMsg("  Encontrados " . count($onlySec) . " productos exclusivos en secundaria.");
        foreach ($onlySec as $p) {
            $oldId = $p['id_secundario'];
            $tempId = $tempIdBase + $oldId;
            $tempMappingOnlySec[] = ['old' => $oldId, 'temp' => $tempId, 'p' => $p];
            
            logMsg("  Moviendo temporalmente exclusivo '{$p['NombreComercial']}' ({$p['CodigoInterno']}): ID $oldId → $tempId");
            
            foreach ($refTables as $table) {
                if ($table === 'productos') continue;
                try {
                    $pdo2->prepare("UPDATE `$table` SET producto_id = ? WHERE producto_id = ?")->execute([$tempId, $oldId]);
                } catch (Exception $e) {
                    $pdo2->prepare("DELETE FROM `$table` WHERE producto_id = ?")->execute([$oldId]);
                }
            }
            $pdo2->prepare("UPDATE `productos` SET id = ? WHERE id = ?")->execute([$tempId, $oldId]);
        }

        // 3. FASE 1 DE DISCREPANCIAS: Mover productos desalineados a IDs temporales altos
        logMsg("\n--- Paso 3: Resolviendo discrepancias (Fase 1: Mapeo a IDs temporales) ---");
        $mismatched = $pdo1->query("
            SELECT p1.CodigoInterno, p1.id as id_principal, p2.id as id_secundario, p1.NombreComercial
            FROM `$db_principal`.`productos` p1
            JOIN `$db_secundaria`.`productos` p2 ON p1.CodigoInterno = p2.CodigoInterno
            WHERE p1.id != p2.id
        ")->fetchAll(PDO::FETCH_ASSOC);

        logMsg("  Encontrados " . count($mismatched) . " productos desalineados.");
        
        $mismatchedMapping = [];
        foreach ($mismatched as $p) {
            $id1 = $p['id_principal'];
            $id2 = $p['id_secundario'];
            $tempId = $tempIdBase + $id2;
            $mismatchedMapping[] = ['id_principal' => $id1, 'id_secundario' => $id2, 'temp_id' => $tempId, 'p' => $p];
            
            logMsg("  [Fase 1] Desplazando '{$p['NombreComercial']}' ({$p['CodigoInterno']}): ID $id2 → $tempId");
            
            foreach ($refTables as $table) {
                if ($table === 'productos') continue;
                
                if ($table === 'inventario_sucursal') {
                    $stocks = $pdo2->prepare("SELECT id, sucursal_id, stock_total FROM `inventario_sucursal` WHERE producto_id = ?");
                    $stocks->execute([$id2]);
                    foreach ($stocks->fetchAll() as $s) {
                        $check = $pdo2->prepare("SELECT id, stock_total FROM `inventario_sucursal` WHERE producto_id = ? AND sucursal_id = ?");
                        $check->execute([$tempId, $s['sucursal_id']]);
                        $exists = $check->fetch();
                        if ($exists) {
                            $newStock = $exists['stock_total'] + $s['stock_total'];
                            $pdo2->prepare("UPDATE `inventario_sucursal` SET stock_total = ? WHERE id = ?")->execute([newStock, $exists['id']]);
                            $pdo2->prepare("DELETE FROM `inventario_sucursal` WHERE id = ?")->execute([$s['id']]);
                        } else {
                            $pdo2->prepare("UPDATE `inventario_sucursal` SET producto_id = ? WHERE id = ?")->execute([$tempId, $s['id']]);
                        }
                    }
                } else {
                    try {
                        $pdo2->prepare("UPDATE `$table` SET producto_id = ? WHERE producto_id = ?")->execute([$tempId, $id2]);
                    } catch (Exception $e) {
                        $pdo2->prepare("DELETE FROM `$table` WHERE producto_id = ?")->execute([$id2]);
                    }
                }
            }
            $pdo2->prepare("UPDATE `productos` SET id = ? WHERE id = ?")->execute([$tempId, $id2]);
        }

        // 4. FASE 2 DE DISCREPANCIAS: Eliminar temporal e insertar correctos desde la principal
        logMsg("\n--- Paso 4: Resolviendo discrepancias (Fase 2: Asignación de ID principal definitivo) ---");
        foreach ($mismatchedMapping as $map) {
            $id1 = $map['id_principal'];
            $tempId = $map['temp_id'];
            $p = $map['p'];
            
            logMsg("  [Fase 2] Alineando '{$p['NombreComercial']}' a su ID real: $id1");
            
            // Eliminar temporal de tabla productos
            $pdo2->prepare("DELETE FROM `productos` WHERE id = ?")->execute([$tempId]);
            
            // Asegurar limpieza de colisiones previas
            $pdo2->prepare("DELETE FROM `productos` WHERE id = ?")->execute([$id1]);
            
            // Copiar desde la principal
            $cols = $pdo1->query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '$db_principal' AND TABLE_NAME = 'productos' ORDER BY ORDINAL_POSITION")->fetchAll(PDO::FETCH_COLUMN);
            $colList = implode(', ', array_map(fn($c) => "`$c`", $cols));
            $placeholders = implode(', ', array_fill(0, count($cols), '?'));
            
            $selectStmt = $pdo1->prepare("SELECT $colList FROM `productos` WHERE id = ?");
            $selectStmt->execute([$id1]);
            $row = $selectStmt->fetch(PDO::FETCH_NUM);
            
            if ($row) {
                $insertStmt = $pdo2->prepare("INSERT INTO `productos` ($colList) VALUES ($placeholders)");
                $insertStmt->execute($row);
            }
            
            // Actualizar referencias al ID definitivo
            foreach ($refTables as $table) {
                if ($table === 'productos') continue;
                
                if ($table === 'inventario_sucursal') {
                    $stocks = $pdo2->prepare("SELECT id, sucursal_id, stock_total FROM `inventario_sucursal` WHERE producto_id = ?");
                    $stocks->execute([$tempId]);
                    foreach ($stocks->fetchAll() as $s) {
                        $check = $pdo2->prepare("SELECT id, stock_total FROM `inventario_sucursal` WHERE producto_id = ? AND sucursal_id = ?");
                        $check->execute([$id1, $s['sucursal_id']]);
                        $exists = $check->fetch();
                        if ($exists) {
                            $newStock = $exists['stock_total'] + $s['stock_total'];
                            $pdo2->prepare("UPDATE `inventario_sucursal` SET stock_total = ? WHERE id = ?")->execute([$newStock, $exists['id']]);
                            $pdo2->prepare("DELETE FROM `inventario_sucursal` WHERE id = ?")->execute([$s['id']]);
                        } else {
                            $pdo2->prepare("UPDATE `inventario_sucursal` SET producto_id = ? WHERE id = ?")->execute([$id1, $s['id']]);
                        }
                    }
                } else {
                    try {
                        $pdo2->prepare("UPDATE `$table` SET producto_id = ? WHERE producto_id = ?")->execute([$id1, $tempId]);
                    } catch (Exception $e) {
                        $pdo2->prepare("DELETE FROM `$table` WHERE producto_id = ?")->execute([$tempId]);
                    }
                }
            }
        }

        // 5. Mover los productos exclusivos de la secundaria a su ID definitivo (creándolos en la principal)
        logMsg("\n--- Paso 5: Sincronizando productos exclusivos de secundaria a la principal ---");
        foreach ($tempMappingOnlySec as $map) {
            $tempId = $map['temp'];
            $p = $map['p'];
            
            $maxId1 = $pdo1->query("SELECT COALESCE(MAX(id), 0) FROM `$db_principal`.`productos`")->fetchColumn();
            $maxId2 = $pdo2->query("SELECT COALESCE(MAX(id), 0) FROM `$db_secundaria`.`productos` WHERE id < $tempIdBase")->fetchColumn();
            $newId = max($maxId1, $maxId2) + 1;
            
            logMsg("  Insertando '{$p['NombreComercial']}' en principal con nuevo ID: $newId");
            
            $cols = $pdo1->query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '$db_principal' AND TABLE_NAME = 'productos' ORDER BY ORDINAL_POSITION")->fetchAll(PDO::FETCH_COLUMN);
            $colList = implode(', ', array_map(fn($c) => "`$c`", $cols));
            
            $valQuery = $pdo2->prepare("SELECT $colList FROM `productos` WHERE id = ?");
            $valQuery->execute([$tempId]);
            $row = $valQuery->fetch(PDO::FETCH_ASSOC);
            if ($row) {
                $row['id'] = $newId;
                $placeholders = implode(', ', array_fill(0, count($cols), '?'));
                $insStmt = $pdo1->prepare("INSERT INTO `productos` ($colList) VALUES ($placeholders)");
                $insStmt->execute(array_values($row));
            }
            
            $pdo2->prepare("UPDATE `productos` SET id = ? WHERE id = ?")->execute([$newId, $tempId]);
            
            foreach ($refTables as $table) {
                if ($table === 'productos') continue;
                
                if ($table === 'inventario_sucursal') {
                    $stocks = $pdo2->prepare("SELECT id, sucursal_id, stock_total FROM `inventario_sucursal` WHERE producto_id = ?");
                    $stocks->execute([$tempId]);
                    foreach ($stocks->fetchAll() as $s) {
                        $check = $pdo2->prepare("SELECT id, stock_total FROM `inventario_sucursal` WHERE producto_id = ? AND sucursal_id = ?");
                        $check->execute([$newId, $s['sucursal_id']]);
                        $exists = $check->fetch();
                        if ($exists) {
                            $newStock = $exists['stock_total'] + $s['stock_total'];
                            $pdo2->prepare("UPDATE `inventario_sucursal` SET stock_total = ? WHERE id = ?")->execute([newStock, $exists['id']]);
                            $pdo2->prepare("DELETE FROM `inventario_sucursal` WHERE id = ?")->execute([$s['id']]);
                        } else {
                            $pdo2->prepare("UPDATE `inventario_sucursal` SET producto_id = ? WHERE id = ?")->execute([$newId, $s['id']]);
                        }
                    }
                } else {
                    try {
                        $pdo2->prepare("UPDATE `$table` SET producto_id = ? WHERE producto_id = ?")->execute([$newId, $tempId]);
                    } catch (Exception $e) {
                        $pdo2->prepare("DELETE FROM `$table` WHERE producto_id = ?")->execute([$tempId]);
                    }
                }
            }
        }

        // 6. Copiar productos que solo existen en la principal
        logMsg("\n--- Paso 6: Copiando productos faltantes de principal a secundaria ---");
        $onlyPri = $pdo1->query("
            SELECT p1.id, p1.CodigoInterno, p1.NombreComercial
            FROM `$db_principal`.`productos` p1
            LEFT JOIN `$db_secundaria`.`productos` p2 ON p1.CodigoInterno = p2.CodigoInterno
            WHERE p2.CodigoInterno IS NULL
        ")->fetchAll(PDO::FETCH_ASSOC);

        logMsg("  Encontrados " . count($onlyPri) . " productos faltantes en secundaria.");
        foreach ($onlyPri as $p) {
            $id1 = $p['id'];
            
            $pdo2->prepare("DELETE FROM `productos` WHERE id = ?")->execute([$id1]);
            
            $cols = $pdo1->query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '$db_principal' AND TABLE_NAME = 'productos' ORDER BY ORDINAL_POSITION")->fetchAll(PDO::FETCH_COLUMN);
            $colList = implode(', ', array_map(fn($c) => "`$c`", $cols));
            $placeholders = implode(', ', array_fill(0, count($cols), '?'));
            
            $selectStmt = $pdo1->prepare("SELECT $colList FROM `productos` WHERE id = ?");
            $selectStmt->execute([$id1]);
            $row = $selectStmt->fetch(PDO::FETCH_NUM);
            
            if ($row) {
                $insertStmt = $pdo2->prepare("INSERT INTO `productos` ($colList) VALUES ($placeholders)");
                $insertStmt->execute($row);
                logMsg("    ✓ Copiado: {$p['NombreComercial']} (ID: $id1)");
            }
        }

        // 7. Re-sincronizar por completo tablas de definición de productos
        logMsg("\n--- Paso 7: Sincronizando por completo tablas secundarias de definición ---");
        $tablesToReSync = [
            'producto_presentaciones',
            'producto_lugares_compra',
            'productos_costo_promedio',
            'fel_producto_mapping'
        ];

        foreach ($tablesToReSync as $table) {
            logMsg("  Sincronizando tabla `$table`...");
            $pdo2->exec("TRUNCATE TABLE `$table`");
            
            $cols = $pdo1->query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '$db_principal' AND TABLE_NAME = '$table' ORDER BY ORDINAL_POSITION")->fetchAll(PDO::FETCH_COLUMN);
            $colList = implode(', ', array_map(fn($c) => "`$c`", $cols));
            $placeholders = implode(', ', array_fill(0, count($cols), '?'));
            
            $selectStmt = $pdo1->query("SELECT $colList FROM `$table`");
            $insertStmt = $pdo2->prepare("INSERT INTO `$table` ($colList) VALUES ($placeholders)");
            
            $copiedCount = 0;
            while ($row = $selectStmt->fetch(PDO::FETCH_NUM)) {
                $insertStmt->execute($row);
                $copiedCount++;
            }
            logMsg("    ✓ Copiados $copiedCount registros.");
            
            $maxId = $pdo1->query("SELECT COALESCE(MAX(id), 0) FROM `$db_principal`.`$table`")->fetchColumn();
            $newAI = $maxId + 1;
            $pdo2->exec("ALTER TABLE `$table` AUTO_INCREMENT = $newAI");
        }

        // 8. Corregir contadores AUTO_INCREMENT de todas las tablas de productos en la secundaria
        logMsg("\n--- Paso 8: Ajustando AUTO_INCREMENT finales en secundaria ---");
        $tablesToFixAI = [
            'productos' => 'productos',
            'productos_costo_promedio' => 'productos_costo_promedio',
            'producto_presentaciones' => 'producto_presentaciones',
            'producto_lugares_compra' => 'producto_lugares_compra',
            'ventas' => 'ventas',
            'detalle_ventas' => 'detalle_ventas',
            'compras' => 'compras',
            'compras_detalle' => 'compras_detalle'
        ];

        foreach ($tablesToFixAI as $table) {
            $maxId1 = $pdo1->query("SELECT COALESCE(MAX(id), 0) FROM `$db_principal`.`$table`")->fetchColumn();
            $maxId2 = $pdo2->query("SELECT COALESCE(MAX(id), 0) FROM `$db_secundaria`.`$table` WHERE id < $tempIdBase")->fetchColumn();
            $newAI = max($maxId1, $maxId2) + 1;
            $pdo2->exec("ALTER TABLE `$table` AUTO_INCREMENT = $newAI");
            logMsg("  ✓ `$table` AUTO_INCREMENT alineado a: $newAI");
        }

        logMsg("\n========================================================");
        logMsg("¡PROCESO DE ALINEACIÓN COMPLETADO CON ÉXITO!");
        logMsg("========================================================");

    } catch (Exception $e) {
        logMsg("\n[ERROR CRÍTICO]: " . $e->getMessage());
    }
    exit;
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Alineación de Bases de Datos - SufarmaERP</title>
    <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&family=JetBrains+Mono&display=swap" rel="stylesheet">
    <style>
        :root {
            --bg-color: #0d0f12;
            --card-bg: #14181f;
            --accent-color: #00f2fe;
            --accent-gradient: linear-gradient(135deg, #00f2fe 0%, #4facfe 100%);
            --text-primary: #f5f6f8;
            --text-secondary: #90a0b7;
            --border-color: #202635;
            --success-color: #00e676;
            --danger-color: #ff1744;
        }

        body {
            font-family: 'Outfit', sans-serif;
            background-color: var(--bg-color);
            color: var(--text-primary);
            margin: 0;
            padding: 40px 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            box-sizing: border-box;
        }

        .container {
            width: 100%;
            max-width: 850px;
            background-color: var(--card-bg);
            border: 1px solid var(--border-color);
            border-radius: 20px;
            padding: 40px;
            box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
            position: relative;
            overflow: hidden;
        }

        .container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 4px;
            background: var(--accent-gradient);
        }

        h1 {
            font-size: 2.2rem;
            font-weight: 800;
            margin-top: 0;
            margin-bottom: 10px;
            background: var(--accent-gradient);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }

        .subtitle {
            color: var(--text-secondary);
            font-size: 1.1rem;
            margin-bottom: 30px;
        }

        .info-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-bottom: 30px;
        }

        .info-card {
            background-color: rgba(255, 255, 255, 0.02);
            border: 1px solid var(--border-color);
            border-radius: 12px;
            padding: 20px;
        }

        .info-card h3 {
            margin-top: 0;
            margin-bottom: 12px;
            font-size: 1.1rem;
            color: var(--accent-color);
        }

        .info-item {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
            font-size: 0.95rem;
        }

        .info-item span:first-child {
            color: var(--text-secondary);
        }

        .info-item span:last-child {
            font-weight: 600;
        }

        .warning-box {
            background-color: rgba(255, 23, 68, 0.05);
            border: 1px solid rgba(255, 23, 68, 0.2);
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 35px;
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .warning-icon {
            font-size: 2rem;
            color: var(--danger-color);
        }

        .warning-text {
            font-size: 0.95rem;
            color: #ff8a80;
        }

        .warning-text strong {
            color: #ff5252;
        }

        .btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            background: var(--accent-gradient);
            color: #000;
            font-family: 'Outfit', sans-serif;
            font-size: 1.1rem;
            font-weight: 600;
            border: none;
            border-radius: 10px;
            padding: 16px 32px;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(0, 242, 254, 0.2);
            width: 100%;
            box-sizing: border-box;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(0, 242, 254, 0.4);
        }

        .btn:disabled {
            background: #202635;
            color: var(--text-secondary);
            cursor: not-allowed;
            box-shadow: none;
            transform: none;
        }

        .console-container {
            margin-top: 30px;
            display: none;
        }

        .console-header {
            background-color: #1a1e27;
            border: 1px solid var(--border-color);
            border-bottom: none;
            border-top-left-radius: 12px;
            border-top-right-radius: 12px;
            padding: 12px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .console-title {
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.9rem;
            color: var(--text-secondary);
        }

        .console-dots {
            display: flex;
            gap: 6px;
        }

        .dot {
            width: 10px;
            height: 10px;
            border-radius: 50%;
        }

        .dot-red { background-color: #ff5f56; }
        .dot-yellow { background-color: #ffbd2e; }
        .dot-green { background-color: #27c93f; }

        .console-body {
            background-color: #07090c;
            border: 1px solid var(--border-color);
            border-bottom-left-radius: 12px;
            border-bottom-right-radius: 12px;
            padding: 20px;
            height: 350px;
            overflow-y: auto;
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.9rem;
            line-height: 1.5;
            color: #d1d5db;
            white-space: pre-wrap;
        }

        /* Barra de progreso */
        .progress-bar-container {
            margin-top: 20px;
            height: 6px;
            background-color: #1a1e27;
            border-radius: 3px;
            overflow: hidden;
            display: none;
        }

        .progress-bar {
            height: 100%;
            width: 0%;
            background: var(--accent-gradient);
            transition: width 0.3s ease;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Alineación de Bases de Datos</h1>
        <div class="subtitle">Herramienta para alinear códigos secuenciales de productos (SufarmaERP)</div>

        <div class="info-grid">
            <div class="info-card">
                <h3>Base de Datos Principal</h3>
                <div class="info-item">
                    <span>Servidor:</span>
                    <span><?php echo htmlspecialchars($host); ?></span>
                </div>
                <div class="info-item">
                    <span>Nombre BD:</span>
                    <span><?php echo htmlspecialchars($db_principal); ?></span>
                </div>
                <div class="info-item">
                    <span>Usuario:</span>
                    <span><?php echo htmlspecialchars($user); ?></span>
                </div>
            </div>

            <div class="info-card">
                <h3>Base de Datos Secundaria</h3>
                <div class="info-item">
                    <span>Servidor:</span>
                    <span><?php echo htmlspecialchars($host); ?></span>
                </div>
                <div class="info-item">
                    <span>Nombre BD:</span>
                    <span><?php echo htmlspecialchars($db_secundaria); ?></span>
                </div>
                <div class="info-item">
                    <span>Usuario:</span>
                    <span><?php echo htmlspecialchars($user); ?></span>
                </div>
            </div>
        </div>

        <div class="warning-box">
            <div class="warning-icon">⚠</div>
            <div class="warning-text">
                <strong>ATENCIÓN:</strong> Este script modificará llaves primarias y stock consolidado en la base de datos secundaria para alinearlos con la principal. <strong>Es obligatorio realizar un respaldo completo de ambas bases de datos antes de continuar.</strong>
            </div>
        </div>

        <button id="btnRun" class="btn" onclick="startAlignment()">Iniciar Reconciliación y Sincronización</button>

        <div class="progress-bar-container" id="progressBarContainer">
            <div class="progress-bar" id="progressBar"></div>
        </div>

        <div class="console-container" id="consoleContainer">
            <div class="console-header">
                <div class="console-title">ejecucion_alineacion.log</div>
                <div class="console-dots">
                    <div class="dot dot-red"></div>
                    <div class="dot dot-yellow"></div>
                    <div class="dot dot-green"></div>
                </div>
            </div>
            <div class="console-body" id="consoleBody"></div>
        </div>
    </div>

    <script>
        function startAlignment() {
            if (!confirm("¿Confirmas que has realizado copias de seguridad de las bases de datos y deseas proceder?")) {
                return;
            }

            const btn = document.getElementById('btnRun');
            const consoleContainer = document.getElementById('consoleContainer');
            const consoleBody = document.getElementById('consoleBody');
            const progressContainer = document.getElementById('progressBarContainer');
            const progressBar = document.getElementById('progressBar');

            btn.disabled = true;
            btn.innerText = "Ejecutando proceso...";
            consoleContainer.style.display = 'block';
            progressContainer.style.display = 'block';
            consoleBody.innerHTML = "Iniciando comunicación con el servidor...\n";
            progressBar.style.width = "5%";

            // Conectar mediante Fetch API leyendo la respuesta en stream (tiempo real)
            fetch('?action=run')
                .then(response => {
                    const reader = response.body.getReader();
                    const decoder = new TextDecoder('utf-8');
                    
                    function read() {
                        return reader.read().then(({ done, value }) => {
                            if (done) {
                                btn.innerText = "Proceso Terminado";
                                progressBar.style.width = "100%";
                                return;
                            }
                            
                            const text = decoder.decode(value, { stream: true });
                            consoleBody.innerHTML += text;
                            consoleBody.scrollTop = consoleBody.scrollHeight;
                            
                            // Ajustar barra de progreso según los pasos
                            if (text.includes("Paso 1")) progressBar.style.width = "15%";
                            if (text.includes("Paso 2")) progressBar.style.width = "30%";
                            if (text.includes("Paso 3")) progressBar.style.width = "45%";
                            if (text.includes("Paso 4")) progressBar.style.width = "60%";
                            if (text.includes("Paso 5")) progressBar.style.width = "75%";
                            if (text.includes("Paso 6")) progressBar.style.width = "85%";
                            if (text.includes("Paso 7")) progressBar.style.width = "95%";
                            if (text.includes("COMPLETADO CON ÉXITO")) {
                                progressBar.style.width = "100%";
                                btn.innerText = "Sincronización Completada";
                                btn.style.background = "linear-gradient(135deg, #00e676 0%, #00b0ff 100%)";
                            }
                            if (text.includes("ERROR")) {
                                btn.innerText = "Error en el Proceso";
                                btn.style.background = "#ff1744";
                                progressBar.style.backgroundColor = "#ff1744";
                            }
                            
                            return read();
                        });
                    }
                    return read();
                })
                .catch(error => {
                    consoleBody.innerHTML += "\n[ERROR CONEXIÓN]: " + error;
                    btn.innerText = "Fallo de Red";
                    btn.style.background = "#ff1744";
                });
        }
    </script>
</body>
</html>
