<?php
/**
 * Sistema de migraciones automáticas
 * Se ejecuta al iniciar el contenedor Docker
 * Fecha: 3 de febrero de 2026
 */

// No mostrar errores en pantalla
error_reporting(E_ALL);
ini_set('display_errors', '0');

echo "🔍 Iniciando sistema de migraciones...\n";

// Cargar configuración
if (!file_exists(__DIR__ . '/../config/config.php')) {
    echo "❌ Error: config.php no encontrado\n";
    exit(1);
}

require_once __DIR__ . '/../config/config.php';

try {
    $db = Database::getInstance();
    echo "✅ Conexión a base de datos establecida\n";
    
    // Crear tabla de control de migraciones si no existe
    $db->execute("
        CREATE TABLE IF NOT EXISTS migrations (
            id INT AUTO_INCREMENT PRIMARY KEY,
            filename VARCHAR(255) NOT NULL UNIQUE,
            executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            KEY idx_filename (filename)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    ");
    
    echo "✅ Tabla de control de migraciones verificada\n";
    
    // Obtener lista de migraciones ejecutadas
    $executed = $db->fetchAll("SELECT filename FROM migrations");
    $executedFiles = array_column($executed, 'filename');
    
    // Buscar archivos .sql en database/ Y en migrations/ (carpeta raíz del proyecto)
    $dbFiles         = glob(__DIR__ . '/*.sql') ?: [];
    $migrationsFiles = glob(__DIR__ . '/../migrations/*.sql') ?: [];

    // Unir y ordenar por nombre de archivo (orden cronológico por prefijo)
    $allFiles = array_unique(array_merge($dbFiles, $migrationsFiles));
    usort($allFiles, fn($a, $b) => strcmp(basename($a), basename($b)));
    $migrationFiles = $allFiles;

    if (empty($migrationFiles)) {
        echo "ℹ️  No se encontraron archivos de migración\n";
        exit(0);
    }

    echo "📋 Encontrados " . count($migrationFiles) . " archivos de migración\n";
    echo "   (database/: " . count($dbFiles) . ", migrations/: " . count($migrationsFiles) . ")\n\n";
    
    $executed_count = 0;
    $skipped_count = 0;
    
    foreach ($migrationFiles as $file) {
        $filename = basename($file);
        
        // Saltar archivo de backup completo
        if (strpos($filename, 'backup') !== false) {
            continue;
        }
        
        // Verificar si ya fue ejecutada
        if (in_array($filename, $executedFiles)) {
            // Verificación extra: si el SQL crea tablas, comprobar que realmente existan.
            // Si alguna tabla del archivo no existe, re-ejecutar la migración.
            $sqlRaw = file_get_contents($file);
            preg_match_all(
                '/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?`?(\w+)`?/i',
                $sqlRaw,
                $tableMatches
            );
            $missingTable = false;
            foreach ($tableMatches[1] as $tableName) {
                $rows = $db->fetchAll(
                    "SELECT COUNT(*) as cnt FROM information_schema.tables
                     WHERE table_schema = DATABASE() AND table_name = ?",
                    [$tableName]
                );
                if (empty($rows) || ($rows[0]['cnt'] ?? 0) == 0) {
                    $missingTable = $tableName;
                    break;
                }
            }
            if ($missingTable) {
                echo "⚠️  $filename registrada pero tabla '$missingTable' no existe — re-ejecutando\n";
                // Quitar del registro para re-ejecutar
                $db->execute("DELETE FROM migrations WHERE filename = ?", [$filename]);
                $executedFiles = array_diff($executedFiles, [$filename]);
                // Continúa a la ejecución abajo
            } else {
                echo "⏭️  Saltando $filename (ya ejecutada)\n";
                $skipped_count++;
                continue;
            }
        }
        
        echo "🔄 Ejecutando migración: $filename\n";
        
        try {
            $sql = file_get_contents($file);

            // Eliminar comentarios de bloque /* ... */
            $sql = preg_replace('/\/\*.*?\*\//s', '', $sql);

            // Dividir en sentencias por ; y limpiar
            $rawStatements = explode(';', $sql);
            $statements = [];
            foreach ($rawStatements as $stmt) {
                // Eliminar líneas de comentario -- y líneas vacías
                $lines = explode("\n", $stmt);
                $cleaned = [];
                foreach ($lines as $line) {
                    $trimmed = trim($line);
                    if ($trimmed !== '' && strpos($trimmed, '--') !== 0) {
                        $cleaned[] = $line;
                    }
                }
                $stmt = trim(implode("\n", $cleaned));
                if ($stmt !== '') {
                    $statements[] = $stmt;
                }
            }

            $stmt_count = 0;
            $had_error = false;
            foreach ($statements as $stmt) {
                try {
                    $db->execute($stmt);
                    $stmt_count++;
                } catch (Exception $e) {
                    $msg = $e->getMessage();
                    // Ignorar errores de "ya existe" — son idempotentes
                    $ignorable = [
                        'Duplicate column',
                        'already exists',
                        'Duplicate key name',
                        'Multiple primary key defined',
                    ];
                    $ignore = false;
                    foreach ($ignorable as $pattern) {
                        if (strpos($msg, $pattern) !== false) {
                            $ignore = true;
                            break;
                        }
                    }
                    if ($ignore) {
                        echo "   ⚠ Ya existe (ignorado): " . substr($msg, 0, 80) . "\n";
                        continue;
                    }
                    echo "   ✗ Error en sentencia: $msg\n";
                    $had_error = true;
                    // Continuar con las demás sentencias del archivo
                }
            }

            if (!$had_error) {
                // Registrar migración como ejecutada solo si no hubo errores reales
                $db->execute(
                    "INSERT INTO migrations (filename) VALUES (?)",
                    [$filename]
                );
                echo "   ✓ Ejecutadas $stmt_count sentencias SQL — registrada\n";
            } else {
                echo "   ⚠ Migración con errores — NO registrada (se reintentará en el próximo deploy)\n";
            }
            $executed_count++;
            
        } catch (Exception $e) {
            echo "   ✗ Error fatal en $filename: " . $e->getMessage() . "\n";
            // Continuar con la siguiente migración
        }
    }
    
    echo "\n";
    echo "═══════════════════════════════════════════\n";
    echo "✅ Migraciones completadas\n";
    echo "   - Ejecutadas: $executed_count\n";
    echo "   - Saltadas: $skipped_count\n";
    echo "═══════════════════════════════════════════\n";
    
} catch (Exception $e) {
    echo "❌ Error fatal en sistema de migraciones: " . $e->getMessage() . "\n";
    exit(1);
}

exit(0);
