<?php
session_start();
require_once __DIR__ . '/../config/db_auto.php';
require_once __DIR__ . '/db_utils.php';
require_once __DIR__ . '/enhanced_validation.php';
require_once __DIR__ . '/import_result_manager.php';
require_once __DIR__ . '/csv_pre_validator.php';
require_once __DIR__ . '/system_logger.php';

use function App\DB\upsert;
use App\Utils\ImportValidator;
use App\Utils\ImportResultManager;
use App\Utils\CSVPreValidator;

$logger = SystemLogger::getInstance();

// Verificar autenticación
if (!isset($_SESSION['user_id'])) {
    $logger->warning('Intento de importación de info adicional sin autenticación', 'IP: ' . ($_SERVER['REMOTE_ADDR'] ?? 'N/A'));
    header('Location: ../views/login.php');
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['csv_file'])) {
    header('Location: ../views/importacion.php?tab=adicional');
    exit;
}

$tipo_importacion = $_POST['tipo_importacion'] ?? '';

if ($tipo_importacion === 'salud') {
    $expected_header = [
        'run_alumno',
        'sistema_salud',
        'alergias',
        'enfermedad_cuidado',
        'medicamento_contraindicado',
        'medicamento_uso_diario',
        'observaciones'
    ];
    $tabla_destino = 'salud_alumno';
} elseif ($tipo_importacion === 'social') {
    $expected_header = [
        'run_alumno',
        'edad',
        'repitente',
        'grado_repitencia',
        'colegio_procedencia',
        'alumno_pie',
        'hermanos_escuela',
        'grado_hermanos',
        'nacionalidad',
        'integrantes_familia',
        'orden_alejamiento',
        'programa_social',
        'etnia',
        'internet_hogar',
        'smartphone',
        'computador_hogar',
        'opta_religion',
        'religion',
        'transporte',
        'sector',
        'junaeb',
        'uso_imagen',
        'vive_con',
        'domicilio',
        'observacion_alejamiento'
    ];
    $tabla_destino = 'social_alumno';
} else {
    $_SESSION['import_message'] = 'Tipo de importación no válido.';
    $_SESSION['import_status'] = 'error';
    header('Location: ../views/importacion.php?tab=adicional');
    exit;
}

$result_manager = new ImportResultManager();
$filename = $_FILES['csv_file']['tmp_name'];

// Pre-validación del archivo
$pre_validator = new CSVPreValidator();
$pre_validation = $pre_validator->validateFile($filename, $expected_header);

if (!empty($pre_validation['errors'])) {
    $error_html = '<h4>Errores en el archivo CSV:</h4><ul>';
    foreach ($pre_validation['errors'] as $error) {
        $error_html .= '<li>' . htmlspecialchars($error) . '</li>';
    }
    $error_html .= '</ul>';

    $_SESSION['import_message'] = $error_html;
    $_SESSION['import_status'] = 'error';
    $logger->error('Error en pre-validación de info adicional', 'Archivo rechazado: ' . implode(', ', $pre_validation['errors']));
    header('Location: ../views/importacion.php?tab=adicional');
    exit;
}

if (($handle = fopen($filename, "r")) !== FALSE) {
    $header = array_map('trim', fgetcsv($handle, 2000, ","));
    $result_manager->setTotalRows($pre_validation['stats']['total_rows']);

    // Configurar PDO para que no lance excepciones por advertencias (como 'Data truncated')
    // pero sí por errores reales. Esto permite que el script continúe y reporte el problema.
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $pdo->beginTransaction();
    try {
        $row_number = 1;
        while (($data = fgetcsv($handle, 2000, ",")) !== FALSE) {
            $row_number++;

            if (empty(array_filter($data))) {
                $result_manager->incrementSkipped();
                continue;
            }

            $row = array_combine($expected_header, $data);

            // 1. Validar RUN y encontrar alumno_id
            $run_alumno_raw = $row['run_alumno'] ?? '';
            $run_alumno_cleaned = preg_replace('/[^0-9kK]/', '', strtoupper($run_alumno_raw));

            $stmt = $pdo->prepare("SELECT id FROM alumnos WHERE REPLACE(run, '-', '') = ?");
            $stmt->execute([$run_alumno_cleaned]);
            $alumno = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$alumno) {
                $result_manager->addError("Alumno con RUN " . htmlspecialchars($run_alumno_raw) . " no encontrado.", $row_number);
                continue;
            }
            $alumno_id = $alumno['id'];

            // --- NUEVO: Normalización de datos booleanos (SI/NO a 1/0) ---
            // Esto es crucial para los campos que en la BD son TINYINT(1).
            if ($tipo_importacion === 'social') {
                $boolean_fields = [
                    'repitente',
                    'alumno_pie',
                    'hermanos_escuela',
                    'orden_alejamiento',
                    'internet_hogar',
                    'smartphone',
                    'computador_hogar',
                    'opta_religion',
                    'transporte',
                    'junaeb',
                    'uso_imagen'
                ];

                foreach ($boolean_fields as $field) {
                    if (isset($row[$field])) {
                        $value = strtoupper(trim($row[$field]));
                        // Aceptar 'SI', 'S', '1', 'VERDADERO' como afirmativo.
                        if (in_array($value, ['SI', 'S', '1', 'VERDADERO'])) {
                            $row[$field] = 1;
                        }
                        // Aceptar 'NO', 'N', '0', 'FALSO' como negativo.
                        elseif (in_array($value, ['NO', 'N', '0', 'FALSO'])) {
                            $row[$field] = 0;
                        }
                        // Si es otro valor (o está vacío), se limpiará más adelante
                        // para que no se intente guardar.
                        else {
                            $row[$field] = '';
                        }
                    }
                }
            }

            // 2. Preparar datos para actualizar, ignorando los vacíos
            $datos_para_actualizar = array_filter(
                array_intersect_key($row, array_flip($expected_header)),
                fn($v) => $v !== null && $v !== ''
            );
            unset($datos_para_actualizar['run_alumno']); // No necesitamos el RUN en los datos a guardar

            // 3. Si hay datos para actualizar, intentar ejecutar el upsert
            try {
                if (!empty($datos_para_actualizar)) {
                    upsert($pdo, $tabla_destino, $datos_para_actualizar, 'alumno_id', $alumno_id);
                }
                $result_manager->incrementProcessed();
            } catch (PDOException $e) {
                // Capturar específicamente errores de datos truncados y reportarlos sin detener el proceso
                if ($e->getCode() == '22001' || str_contains($e->getMessage(), 'Data truncated')) {
                    $result_manager->addError("Dato demasiado largo para una columna en el RUN " . htmlspecialchars($run_alumno_raw), $row_number);
                } else {
                    throw $e; // Relanzar otros errores de BD para que sean capturados por el catch principal
                }
            }
        }

        $pdo->commit();
        $stats = $result_manager->getStats();
        $logger->data(
            'Importación de info adicional completada',
            "Tipo: $tipo_importacion, Procesados: {$stats['processed']}, Errores: {$stats['errors']}"
        );
    } catch (Throwable $e) {
        $pdo->rollBack();
        $result_manager->addError("Error crítico durante la importación: " . $e->getMessage());
        $logger->error('Error crítico en importación de info adicional', $e->getMessage());
    }

    fclose($handle);

    // Generar reporte de resultados
    $report_html = $result_manager->generateReport();
    $stats = $result_manager->getStats();

    $_SESSION['import_status'] = ($stats['errors'] > 0) ? 'error' : 'success';
    $_SESSION['import_message'] = $report_html;
}

header('Location: ../views/importacion.php?tab=adicional');
exit;
