<?php
/**
 * Script para sincronizar datos de números económicos desde un endpoint externo
 * Este script obtiene los datos y actualiza la base de datos local
 */

// Cargar archivo de configuración
require_once __DIR__ . '/config.php';

// Extraer configuración de base de datos
$db_host = $db_config['host'];
$db_name = $db_config['name'];
$db_user = $db_config['user'];
$db_pass = $db_config['pass'];
$charset = $db_config['charset'];

echo "Usando configuración de base de datos:\n";
echo "Host: $db_host\n";
echo "Base de datos: $db_name\n";
echo "Usuario: $db_user\n";

// Función para escribir en el log
function escribirLog($mensaje) {
    global $log_directorio;
    $fecha = date('Y-m-d H:i:s');
    $mensaje = "[$fecha] $mensaje\n";
    file_put_contents($log_directorio . '/sincronizacion_' . date('Y-m-d') . '.log', $mensaje, FILE_APPEND);
    echo $mensaje;
}

// Conectar a la base de datos
try {
    $db = new PDO("mysql:host=$db_host;dbname=$db_name;charset=$charset", $db_user, $db_pass);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Conexión establecida con éxito.\n";
} catch (PDOException $e) {
    $error = "Error de conexión: " . $e->getMessage();
    escribirLog($error);
    die($error . "\n");
}

// Obtener los datos del endpoint usando el método de file_get_contents y stream context
function obtenerDatosDelEndpoint($endpoint_url) {
    escribirLog("Obteniendo datos del endpoint...");
    
    $url_base = 'http://74.208.26.126/caronte_test/';
    $usuario = 'soporte';
    $contra_nueva = '40bd001563085fc35165329ea1ff5c5ecbdbbeef';
    $cookie_de_sesion = '';
    
    // Obtener sesión inicial
    $respuesta_sesion_activa = @file_get_contents($url_base . 'public_html/index.php/api/auth/session_activa');
    
    if ($respuesta_sesion_activa === false) {
        throw new Exception("No se pudo obtener la sesión inicial");
    }
    
    // Obtener cookie de la respuesta
    $encabezado_respuesta = $http_response_header;
    if (is_array($encabezado_respuesta) && count($encabezado_respuesta) > 0) {
        foreach ($encabezado_respuesta as $elemento) {
            if (substr($elemento, 0, 10) == 'Set-Cookie') {
                $cookie_de_sesion = substr($elemento, 4, 44);
                escribirLog("Cookie de sesión obtenida");
            }
        }
    }
    
    if (empty($cookie_de_sesion)) {
        throw new Exception("No se pudo obtener la cookie de sesión");
    }
    
    // Datos para login
    $postdata = http_build_query(
        array(
            'username' => $usuario,
            'password' => $contra_nueva,
            'new_password' => $contra_nueva,
            'intentos_captcha' => '1'
        )
    );
    
    // Opciones para login
    $optsLogin = array('http' =>
        array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
                        "$cookie_de_sesion\r\n",
            'content' => $postdata,
            'timeout' => 60
        )
    );
    
    // Opciones para peticiones GET
    $optsGets = array('http' =>
        array(
            'method' => 'GET',
            'header' => "$cookie_de_sesion\r\n",
            'timeout' => 120
        )
    );
    
    // Hacer login
    $context = stream_context_create($optsLogin);
    $respuesta_login = @file_get_contents($url_base . 'public_html/index.php/api/auth/acceso?v=0.60933668797657031', false, $context);
    
    if ($respuesta_login === false) {
        throw new Exception("Error al iniciar sesión");
    }
    
    escribirLog("Inicio de sesión realizado");
    
    // Verificar sesión activa
    $respuesta_sesion_activa = @file_get_contents($url_base . 'public_html/index.php/api/auth/session_activa', false, stream_context_create($optsGets));
    
    if ($respuesta_sesion_activa === false) {
        throw new Exception("Error al verificar sesión activa");
    }
    
    escribirLog("Sesión activa confirmada");
    
    // Obtener los datos del endpoint
    $respuesta_endpoint = @file_get_contents($endpoint_url, false, stream_context_create($optsGets));
    
    if ($respuesta_endpoint === false) {
        throw new Exception("Error al obtener datos del endpoint");
    }
    
    $data = json_decode($respuesta_endpoint, true);
    if (!$data) {
        throw new Exception("Error al decodificar la respuesta JSON del endpoint");
    }
    
    escribirLog("Datos obtenidos correctamente del endpoint");
    return $data;
}

// Iniciar el proceso de sincronización
try {
    // Obtener datos del API
    $data = obtenerDatosDelEndpoint($endpoint_url);

    if (!isset($data['numeros_economicos']) || !is_array($data['numeros_economicos'])) {
        throw new Exception("Formato de respuesta inválido o sin datos");
    }

    $numeros_economicos = $data['numeros_economicos'];
    escribirLog("Se encontraron " . count($numeros_economicos) . " registros en el endpoint.");

    // Iniciar transacción
    $db->beginTransaction();

    try {
        // 1. Verificar y actualizar las modalidades
        $stmt_check_modalidad = $db->prepare("SELECT id FROM numeros_economicos_modalidades WHERE id = ?");
        $stmt_insert_modalidad = $db->prepare("INSERT INTO numeros_economicos_modalidades 
                                          (id, modalidad_nombre, codigo, status, created_at) 
                                          VALUES (?, ?, ?, 1, NOW())");
        
        // Contadores para estadísticas
        $modalidades_nuevas = 0;
        $registros_actualizados = 0;
        $registros_insertados = 0;
        $modalidades_procesadas = [];
        
        escribirLog("Procesando modalidades...");
        
        // Procesar cada número económico
        foreach ($numeros_economicos as $registro) {
            // Verificar que los campos existan
            $modalidad_id = isset($registro['numero_economico_modalidad_id']) ? $registro['numero_economico_modalidad_id'] : null;
            
            // Solo procesamos modalidades que no hayamos visto antes
            if ($modalidad_id && !isset($modalidades_procesadas[$modalidad_id])) {
                $stmt_check_modalidad->execute([$modalidad_id]);
                $existe_modalidad = $stmt_check_modalidad->fetch();
                
                if (!$existe_modalidad && 
                    isset($registro['modalidad_nombre']) && !empty($registro['modalidad_nombre']) && 
                    isset($registro['codigo']) && !empty($registro['codigo'])) {
                    
                    $stmt_insert_modalidad->execute([
                        $modalidad_id,
                        $registro['modalidad_nombre'],
                        $registro['codigo']
                    ]);
                    $modalidades_nuevas++;
                    escribirLog("Nueva modalidad agregada: ID $modalidad_id - {$registro['modalidad_nombre']} ({$registro['codigo']})");
                }
                
                $modalidades_procesadas[$modalidad_id] = true;
            }
        }
        
        escribirLog("Se agregaron $modalidades_nuevas nuevas modalidades.");
        
        // 2. Sincronizar los números económicos
        escribirLog("Sincronizando números económicos...");
        
        $stmt_check_numero = $db->prepare("SELECT id FROM numeros_economicos WHERE id = ?");
        
        $stmt_update_numero = $db->prepare("UPDATE numeros_economicos SET 
                                       numero_economico_modalidad_id = ?, 
                                       numero_economico = ?,
                                       codigo = ?,
                                       status = ?,
                                       unidad_id = ?,
                                       numero_serie_niv = ?,
                                       modelo = ?,
                                       numero_motor = ?,
                                       marca_nombre = ?,
                                       submarca_nombre = ?,
                                       modalidad_nombre = ?,
                                       updated_at = NOW()
                                       WHERE id = ?");
        
        $stmt_insert_numero = $db->prepare("INSERT INTO numeros_economicos 
                                       (id, numero_economico_modalidad_id, numero_economico, 
                                       codigo, status, unidad_id, numero_serie_niv, modelo, 
                                       numero_motor, marca_nombre, submarca_nombre, modalidad_nombre, 
                                       created_at, updated_at) 
                                       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())");
        
        $contador = 0;
        $total = count($numeros_economicos);
        
        foreach ($numeros_economicos as $registro) {
            $contador++;
            if ($contador % 100 == 0 || $contador == $total) {
                escribirLog("Procesando registro $contador de $total...");
            }
            
            // Verificar que el ID exista
            if (!isset($registro['id'])) {
                escribirLog("Error: Registro sin ID encontrado. Saltando...");
                continue;
            }
            
            $stmt_check_numero->execute([$registro['id']]);
            $existe_numero = $stmt_check_numero->fetch();
            
            // Preparar datos seguros
            $datosRegistro = [
                'id' => $registro['id'],
                'numero_economico_modalidad_id' => isset($registro['numero_economico_modalidad_id']) ? $registro['numero_economico_modalidad_id'] : null,
                'numero_economico' => isset($registro['numero_economico']) ? $registro['numero_economico'] : '',
                'codigo' => isset($registro['codigo']) ? $registro['codigo'] : null,
                'status' => isset($registro['status']) ? $registro['status'] : 0,
                'unidad_id' => isset($registro['unidad_id']) ? $registro['unidad_id'] : null,
                'numero_serie_niv' => isset($registro['numero_serie_niv']) ? $registro['numero_serie_niv'] : null,
                'modelo' => isset($registro['modelo']) ? $registro['modelo'] : null,
                'numero_motor' => isset($registro['numero_motor']) ? $registro['numero_motor'] : null,
                'marca_nombre' => isset($registro['marca_nombre']) ? $registro['marca_nombre'] : null,
                'submarca_nombre' => isset($registro['submarca_nombre']) ? $registro['submarca_nombre'] : null,
                'modalidad_nombre' => isset($registro['modalidad_nombre']) ? $registro['modalidad_nombre'] : ''
            ];
            
            if ($existe_numero) {
                // Actualizar registro existente
                $stmt_update_numero->execute([
                    $datosRegistro['numero_economico_modalidad_id'],
                    $datosRegistro['numero_economico'],
                    $datosRegistro['codigo'],
                    $datosRegistro['status'],
                    $datosRegistro['unidad_id'],
                    $datosRegistro['numero_serie_niv'],
                    $datosRegistro['modelo'],
                    $datosRegistro['numero_motor'],
                    $datosRegistro['marca_nombre'],
                    $datosRegistro['submarca_nombre'],
                    $datosRegistro['modalidad_nombre'],
                    $datosRegistro['id']
                ]);
                $registros_actualizados++;
            } else {
                // Insertar nuevo registro
                $stmt_insert_numero->execute([
                    $datosRegistro['id'],
                    $datosRegistro['numero_economico_modalidad_id'],
                    $datosRegistro['numero_economico'],
                    $datosRegistro['codigo'],
                    $datosRegistro['status'],
                    $datosRegistro['unidad_id'],
                    $datosRegistro['numero_serie_niv'],
                    $datosRegistro['modelo'],
                    $datosRegistro['numero_motor'],
                    $datosRegistro['marca_nombre'],
                    $datosRegistro['submarca_nombre'],
                    $datosRegistro['modalidad_nombre']
                ]);
                $registros_insertados++;
            }
        }
        
        // Confirmar la transacción
        $db->commit();
        
        escribirLog("Sincronización completada: $registros_actualizados actualizados, $registros_insertados nuevos.");
        
    } catch (Exception $e) {
        // Revertir en caso de error
        $db->rollBack();
        escribirLog("Error durante la sincronización: " . $e->getMessage());
        throw $e;
    }
    
} catch (Exception $e) {
    escribirLog("Error general: " . $e->getMessage());
    exit(1);
}