<?php
// concurso_nobel/includes/importar_participantes_servicio.php
// Servicio transaccional de importación de participantes NOBEX.
// Respeta exactamente los nombres escritos en el Excel: tildes, ñ, mayúsculas, minúsculas y caracteres válidos.

declare(strict_types=1);

require_once __DIR__ . '/importar_participantes_excel.php';
require_once __DIR__ . '/importar_participantes_repo.php';

function ip_procesar_importacion_participantes(
    mysqli $conn,
    array $archivo,
    int $idConcurso,
    ?int $idGrupo,
    int $idAcceso,
    int $anioConcurso,
    string $observacionBase
): array {
    $filas = ip_leer_archivo_importado($archivo);
    $registros = ip_convertir_filas_a_registros($filas);

    if (empty($registros)) {
        throw new RuntimeException('No hay participantes para importar.');
    }

    $resumen = ip_resumen_inicial();
    $observacionBase = trim($observacionBase);
    $transaccionIniciada = false;

    try {
        if (!mysqli_begin_transaction($conn)) {
            throw new RuntimeException('No se pudo iniciar la transacción de importación.');
        }

        $transaccionIniciada = true;

        foreach ($registros as $registro) {
            $resumen['procesados']++;

            $fila = (int)$registro['fila'];

            $codigoModular = ip_limpia_codigo_modular((string)$registro['codigo_modular']);
            $dni = ip_limpia_dni((string)$registro['dni']);

            $apellidoPaterno = ip_texto_excel((string)$registro['apellido_paterno'], 120);
            $apellidoMaterno = ip_texto_excel((string)$registro['apellido_materno'], 120);
            $nombres = ip_texto_excel((string)$registro['nombres'], 180);

            if ($codigoModular === '') {
                ip_agregar_error($resumen, 'Fila ' . $fila . ': falta CODIGO_MODULAR.');
                continue;
            }

            if ($dni === '' || !preg_match('/^\d{8}$/', $dni)) {
                ip_agregar_error($resumen, 'Fila ' . $fila . ': DNI inválido. Debe tener 8 dígitos.');
                continue;
            }

            if ($apellidoPaterno === '' || $apellidoMaterno === '' || $nombres === '') {
                ip_agregar_error($resumen, 'Fila ' . $fila . ': apellido paterno, apellido materno y nombres son obligatorios.');
                continue;
            }

            $modular = ip_buscar_modular($conn, $codigoModular);

            if (!$modular) {
                ip_agregar_error($resumen, 'Fila ' . $fila . ': código modular no encontrado en catálogo: ' . $codigoModular . '.');
                continue;
            }

            $duplicado = ip_documento_existe($conn, $idConcurso, $dni);

            if ($duplicado) {
                $resumen['duplicados']++;

                if (count($resumen['errores']) < IP_MAX_ERRORES_MOSTRAR) {
                    $resumen['errores'][] = 'Fila ' . $fila . ': DNI ya registrado: ' . $dni . ' | ' . $duplicado['apellidos_nombres'] . '.';
                }

                continue;
            }

            $apellidosNombres = trim($apellidoPaterno . ' ' . $apellidoMaterno . ' ' . $nombres);
            $observacion = $observacionBase !== '' ? $observacionBase : 'Importado por Excel con código modular. Grado y salón pendientes.';

            ip_insertar_participante(
                $conn,
                $idConcurso,
                $idGrupo,
                $idAcceso,
                $anioConcurso,
                $apellidosNombres,
                $dni,
                $modular,
                $observacion
            );

            $resumen['insertados']++;
        }

        cn_auditar(
            $conn,
            $idConcurso,
            $idGrupo,
            $idAcceso,
            null,
            'IMPORTACION_PARTICIPANTES',
            'Importación por código modular. Procesados: ' . $resumen['procesados'] . ', insertados: ' . $resumen['insertados'] . ', duplicados: ' . $resumen['duplicados'] . ', saltados: ' . $resumen['saltados']
        );

        if (!mysqli_commit($conn)) {
            throw new RuntimeException('No se pudo confirmar la importación.');
        }

        return $resumen;
    } catch (Throwable $e) {
        if ($transaccionIniciada) {
            mysqli_rollback($conn);
        }

        throw new RuntimeException('No se completó la importación. No se guardaron registros parciales. Detalle: ' . $e->getMessage());
    }
}