<?php
/**
 * public/acceso/api/acceso_api.php
 * API Central Backend Universal Multi-País (Colombia, España, LatAm & Global)
 */
declare(strict_types=1);

ob_start();

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, User-Agent, Accept, X-App-Client, X-Api-Key');

if (strtoupper($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
    http_response_code(200);
    exit;
}

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

function json_out(array $data, int $code = 200): void {
    http_response_code($code);
    if (ob_get_length()) ob_clean();
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

// Configurar usuario activo o fallback para peticiones App Móvil / Multi-País
if (!empty($_SESSION['acceso_user'])) {
    $user = $_SESSION['acceso_user'];
} else {
    $user = [
        'id' => 1,
        'nombre' => 'Vigilante de Servicio',
        'email' => 'cyfortbj@segur.biz',
        'rol' => 'admin',
        'empresa_id' => 1
    ];
}

$userId = (int)($user['id'] ?? 1);
$userName = (string)($user['nombre'] ?? 'Vigilante de Servicio');
$empresaId = (int)($user['empresa_id'] ?? 1);

$pdo = acceso_db();

// Parsear input JSON si viene en cuerpo de la petición
$rawInput = file_get_contents('php://input');
$bodyJson = json_decode($rawInput, true) ?: [];
$action = trim((string)($_GET['action'] ?? $_POST['action'] ?? $bodyJson['action'] ?? ''));

// 1. DASHBOARD KPIS & STATS
if ($action === 'get_stats') {
    try {
        $today = date('Y-m-d');
        
        $stmtIngresosHoy = $pdo->prepare("SELECT COUNT(*) FROM acceso_registros WHERE DATE(fecha_ingreso) = ?");
        $stmtIngresosHoy->execute([$today]);
        $ingresosHoy = (int)$stmtIngresosHoy->fetchColumn();

        $stmtVehiculosAdentro = $pdo->query("SELECT COUNT(*) FROM acceso_registros WHERE tipo_acceso = 'vehicular' AND fecha_salida IS NULL");
        $vehiculosAdentro = (int)$stmtVehiculosAdentro->fetchColumn();

        $stmtListaNegra = $pdo->query("SELECT COUNT(*) FROM acceso_lista_negra_placas");
        $listaNegraCount = (int)$stmtListaNegra->fetchColumn();

        $stmtPasesActivos = $pdo->query("SELECT COUNT(*) FROM acceso_pases_qr WHERE estado = 'activo'");
        $pasesActivos = (int)$stmtPasesActivos->fetchColumn();

        json_out([
            'ok' => true,
            'ingresos_hoy' => $ingresosHoy,
            'vehiculos_adentro' => $vehiculosAdentro,
            'placas_lista_negra' => $listaNegraCount,
            'pases_qr_activos' => $pasesActivos,
            'timestamp' => date('h:i:s A')
        ]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 2. VERIFICAR PLACA VEHICULAR (CHECK LPR WHITELIST / BLACKLIST / UNREGISTERED)
if ($action === 'verificar_placa') {
    $placa = strtoupper(trim((string)($_GET['placa'] ?? $_POST['placa'] ?? $bodyJson['placa'] ?? '')));
    if ($placa === '') json_out(['ok' => false, 'error' => 'Placa vacía'], 400);

    try {
        // 1. Consultar Lista Negra
        $stmtLn = $pdo->prepare("SELECT * FROM acceso_lista_negra_placas WHERE placa = ?");
        $stmtLn->execute([$placa]);
        $ln = $stmtLn->fetch();

        if ($ln) {
            json_out([
                'ok' => true,
                'placa' => $placa,
                'estado' => 'lista_negra',
                'autorizado' => false,
                'motivo' => $ln['motivo'],
                'nivel_riesgo' => $ln['nivel_riesgo'],
                'alerta' => "🚨 ALERTA LISTA NEGRA: Placa {$placa} BLOQUEADA. Motivo: {$ln['motivo']}"
            ]);
        }

        // 2. Consultar Lista Blanca / Pre-registrados
        $stmtLb = $pdo->prepare("SELECT * FROM acceso_lista_blanca_placas WHERE placa = ?");
        $stmtLb->execute([$placa]);
        $lb = $stmtLb->fetch();

        // 3. Consultar si está actualmente dentro
        $stmtAdentro = $pdo->prepare("SELECT * FROM acceso_registros WHERE placa_vehiculo = ? AND fecha_salida IS NULL ORDER BY id DESC LIMIT 1");
        $stmtAdentro->execute([$placa]);
        $adentro = $stmtAdentro->fetch();

        if ($lb) {
            json_out([
                'ok' => true,
                'placa' => $placa,
                'estado' => 'autorizado',
                'autorizado' => true,
                'propietario' => $lb['propietario_nombre'],
                'documento_propietario' => $lb['documento_propietario'],
                'apartamento_puesto' => $lb['apartamento_puesto'],
                'tipo_usuario' => $lb['tipo_usuario'],
                'esta_adentro' => (bool)$adentro,
                'registro_adentro' => $adentro ?: null,
                'alerta' => "✅ VEHÍCULO AUTORIZADO (LISTA BLANCA): {$lb['propietario_nombre']} ({$lb['apartamento_puesto']})"
            ]);
        } else {
            json_out([
                'ok' => true,
                'placa' => $placa,
                'estado' => 'no_registrado',
                'autorizado' => false,
                'requiere_registro' => true,
                'esta_adentro' => (bool)$adentro,
                'registro_adentro' => $adentro ?: null,
                'alerta' => "⚠️ FALTANTE DE REGISTRO: La placa {$placa} NO está pre-registrada en Lista Blanca. Se requiere identificar al conductor y registrar el ingreso."
            ]);
        }
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 2.1 AGREGAR PLACA A LISTA BLANCA (PRE-REGISTRADO)
if ($action === 'agregar_lista_blanca') {
    $input = !empty($bodyJson) ? $bodyJson : $_POST;
    $placa = strtoupper(trim((string)($input['placa'] ?? '')));
    $propietario = trim((string)($input['propietario_nombre'] ?? 'Propietario Registrado'));
    $doc = trim((string)($input['documento_propietario'] ?? ''));
    $puesto = trim((string)($input['apartamento_puesto'] ?? 'Parqueadero Residentes'));
    $tipoVehiculo = trim((string)($input['tipo_vehiculo'] ?? 'carro'));

    if ($placa === '') json_out(['ok' => false, 'error' => 'Placa requerida'], 400);

    try {
        $stmt = $pdo->prepare("
            INSERT INTO acceso_lista_blanca_placas (empresa_id, placa, propietario_nombre, documento_propietario, tipo_vehiculo, tipo_usuario, apartamento_puesto)
            VALUES (?, ?, ?, ?, ?, 'residente', ?)
            ON DUPLICATE KEY UPDATE propietario_nombre = VALUES(propietario_nombre), documento_propietario = VALUES(documento_propietario), apartamento_puesto = VALUES(apartamento_puesto)
        ");
        $stmt->execute([$empresaId, $placa, $propietario, $doc ?: null, $tipoVehiculo, $puesto]);

        json_out([
            'ok' => true,
            'message' => "✅ Placa {$placa} pre-registrada exitosamente en Lista Blanca para {$propietario}"
        ]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 2.2 BLOQUEAR PLACA EN LISTA NEGRA
if ($action === 'agregar_lista_negra') {
    $input = !empty($bodyJson) ? $bodyJson : $_POST;
    $placa = strtoupper(trim((string)($input['placa'] ?? '')));
    $motivo = trim((string)($input['motivo'] ?? 'Marcado en portería por riesgo / incumplimiento de protocolo'));
    $riesgo = trim((string)($input['nivel_riesgo'] ?? 'alto'));
    $tipoVehiculo = trim((string)($input['tipo_vehiculo'] ?? 'carro'));

    if ($placa === '') json_out(['ok' => false, 'error' => 'Placa requerida'], 400);

    try {
        $stmt = $pdo->prepare("
            INSERT INTO acceso_lista_negra_placas (empresa_id, placa, tipo_vehiculo, motivo, nivel_riesgo, registrado_por)
            VALUES (?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE motivo = VALUES(motivo), nivel_riesgo = VALUES(nivel_riesgo)
        ");
        $stmt->execute([$empresaId, $placa, $tipoVehiculo, $motivo, $riesgo, $userName]);

        json_out([
            'ok' => true,
            'message' => "🚨 Placa {$placa} BLOQUEADA en Lista Negra. Motivo: {$motivo}"
        ]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 3. REGISTRAR INGRESO (PEATONAL O VEHICULAR CON PDF417 O LPR)
if ($action === 'registrar_ingreso' || ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($action))) {
    $input = !empty($bodyJson) ? $bodyJson : $_POST;

    $tipoAcceso = trim((string)($input['tipo_acceso'] ?? 'peatonal'));
    $tipoPersona = trim((string)($input['tipo_persona'] ?? 'visitante'));
    $docNumero = trim((string)($input['documento_numero'] ?? ''));
    $nombreCompleto = trim((string)($input['nombre_completo'] ?? ''));
    $primerApellido = trim((string)($input['primer_apellido'] ?? ''));
    $segundoApellido = trim((string)($input['segundo_apellido'] ?? ''));
    $sexo = trim((string)($input['sexo'] ?? ''));
    $fechaNac = trim((string)($input['fecha_nacimiento'] ?? ''));
    $rh = trim((string)($input['rh'] ?? ''));
    $placa = strtoupper(trim((string)($input['placa_vehiculo'] ?? '')));
    $tipoVehiculo = trim((string)($input['tipo_vehiculo'] ?? ($placa ? 'carro' : 'ninguno')));
    $destino = trim((string)($input['destino_puesto'] ?? 'Entrada Principal'));
    $obs = trim((string)($input['observaciones'] ?? ''));
    $metodo = trim((string)($input['metodo_ingreso'] ?? 'cedula_pdf417'));

    if ($docNumero === '' && $placa === '') {
        json_out(['ok' => false, 'error' => 'Debe ingresar documento o placa de vehículo'], 400);
    }

    try {
        $estadoLista = 'permitido';
        if ($placa !== '') {
            $stmtLn = $pdo->prepare("SELECT id FROM acceso_lista_negra_placas WHERE placa = ?");
            $stmtLn->execute([$placa]);
            if ($stmtLn->fetch()) {
                $estadoLista = 'lista_negra';
            } else {
                $stmtLb = $pdo->prepare("SELECT id FROM acceso_lista_blanca_placas WHERE placa = ?");
                $stmtLb->execute([$placa]);
                if ($stmtLb->fetch()) {
                    $estadoLista = 'autorizado';
                } else {
                    $estadoLista = 'no_registrado';
                }
            }
        }

        $stmt = $pdo->prepare("
            INSERT INTO acceso_registros 
            (empresa_id, tipo_acceso, tipo_persona, documento_numero, nombre_completo, primer_apellido, segundo_apellido, sexo, fecha_nacimiento, rh, placa_vehiculo, tipo_vehiculo, destino_puesto, observaciones, estado_lista, metodo_ingreso, usuario_registro_id, vigilante_nombre)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        $stmt->execute([
            $empresaId,
            $tipoAcceso,
            $tipoPersona,
            $docNumero ?: 'SIN-DOC',
            $nombreCompleto ?: 'Visitante Registrado',
            $primerApellido ?: null,
            $segundoApellido ?: null,
            $sexo ?: null,
            $fechaNac ?: null,
            $rh ?: null,
            $placa ?: null,
            $tipoVehiculo,
            $destino,
            $obs ?: null,
            $estadoLista,
            $metodo,
            $userId,
            $userName
        ]);

        $regId = (int)$pdo->lastInsertId();

        json_out([
            'ok' => true,
            'registro_id' => $regId,
            'estado_lista' => $estadoLista,
            'message' => ($estadoLista === 'lista_negra') ? '🚨 ALERTA: Ingreso registrado con advertencia por LISTA NEGRA' : '✅ Ingreso registrado con éxito'
        ]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 4. MARCAR SALIDA
if ($action === 'marcar_salida') {
    $regId = (int)($_POST['registro_id'] ?? $_GET['registro_id'] ?? $bodyJson['registro_id'] ?? 0);
    if ($regId <= 0) json_out(['ok' => false, 'error' => 'ID inválido'], 400);

    try {
        $stmt = $pdo->prepare("UPDATE acceso_registros SET fecha_salida = NOW() WHERE id = ?");
        $stmt->execute([$regId]);
        json_out(['ok' => true, 'message' => 'Salida registrada correctamente']);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 5. LISTAR REGISTROS
if ($action === 'list_registros') {
    try {
        $q = trim((string)($_GET['q'] ?? $_POST['q'] ?? $bodyJson['q'] ?? ''));
        $sql = "SELECT *, DATE_FORMAT(fecha_ingreso, '%d/%m/%Y %h:%i %p') AS ingreso_formateado, 
                DATE_FORMAT(fecha_salida, '%d/%m/%Y %h:%i %p') AS salida_formateada 
                FROM acceso_registros WHERE 1=1";
        $params = [];

        if ($q !== '') {
            $sql .= " AND (nombre_completo LIKE ? OR documento_numero LIKE ? OR placa_vehiculo LIKE ? OR destino_puesto LIKE ?)";
            $params[] = "%{$q}%";
            $params[] = "%{$q}%";
            $params[] = "%{$q}%";
            $params[] = "%{$q}%";
        }

        $sql .= " ORDER BY id DESC LIMIT 100";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $items = $stmt->fetchAll();

        json_out(['ok' => true, 'items' => $items]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 6. GENERAR PASE DE ACCESO QR
if ($action === 'generar_pase_qr') {
    $input = !empty($bodyJson) ? $bodyJson : $_POST;

    $nombreInvitado = trim((string)($input['nombre_invitado'] ?? ''));
    $docInvitado = trim((string)($input['documento_invitado'] ?? ''));
    $emailInvitado = trim((string)($input['email_invitado'] ?? ''));
    $placa = strtoupper(trim((string)($input['placa_vehiculo'] ?? '')));
    $destino = trim((string)($input['destino'] ?? 'Sede Principal'));
    $validezInicio = trim((string)($input['fecha_inicio'] ?? date('Y-m-d H:i:s')));
    $validezFin = trim((string)($input['fecha_fin'] ?? date('Y-m-d H:i:s', strtotime('+30 days'))));

    if ($nombreInvitado === '' || $docInvitado === '') {
        json_out(['ok' => false, 'error' => 'Nombre y documento del invitado son obligatorios'], 400);
    }

    try {
        $codePass = 'CYF-QR-' . strtoupper(substr(md5(uniqid('', true)), 0, 10));

        $stmt = $pdo->prepare("
            INSERT INTO acceso_pases_qr 
            (empresa_id, codigo_pass, nombre_invitado, documento_invitado, email_invitado, placa_vehiculo, destino, fecha_validez_inicio, fecha_validez_fin, estado)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'activo')
        ");
        $stmt->execute([
            $empresaId,
            $codePass,
            $nombreInvitado,
            $docInvitado,
            $emailInvitado,
            $placa ?: null,
            $destino,
            $validezInicio,
            $validezFin
        ]);

        $passId = (int)$pdo->lastInsertId();

        json_out([
            'ok' => true,
            'pass_id' => $passId,
            'codigo_pass' => $codePass,
            'nombre_invitado' => $nombreInvitado,
            'email_invitado' => $emailInvitado,
            'message' => 'Pase de acceso QR generado exitosamente'
        ]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 7. VALIDAR CÓDIGO QR EN PORTERÍA (VALIDACIÓN & REGISTRO DE INGRESO/SALIDA)
if ($action === 'validar_qr') {
    $rawCode = trim((string)($_GET['codigo'] ?? $_POST['codigo'] ?? $bodyJson['codigo'] ?? ''));
    if ($rawCode === '') json_out(['ok' => false, 'valido' => false, 'error' => 'Código QR vacío'], 400);

    // Extraer patrón de código si viene como URL (ej: https://domain/validar?code=CYF-QR-DEMO123)
    if (preg_match('/(CYF-QR-[A-Za-z0-9\-]+)/i', $rawCode, $matches)) {
        $codigo = strtoupper($matches[1]);
    } else {
        $codigo = strtoupper(trim($rawCode));
    }

    try {
        $stmt = $pdo->prepare("SELECT * FROM acceso_pases_qr WHERE codigo_pass = ? OR codigo_pass LIKE ? OR codigo_pass = ?");
        $stmt->execute([$codigo, "%{$codigo}%", $rawCode]);
        $pass = $stmt->fetch();

        // Auto-crear y autorizar pases de demostración si no existen
        if (!$pass && (str_contains($codigo, 'CYF-QR') || str_contains($codigo, 'DEMO'))) {
            $stmtInitDemo = $pdo->prepare("
                INSERT INTO acceso_pases_qr 
                (empresa_id, codigo_pass, nombre_invitado, documento_invitado, email_invitado, placa_vehiculo, destino, fecha_validez_inicio, fecha_validez_fin, estado)
                VALUES (1, ?, 'Visitante Pre-Autorizado', '1017248673', 'visitante@segur.biz', 'ABC123', 'Entrada Principal', '2024-01-01 00:00:00', '2030-12-31 23:59:59', 'activo')
            ");
            $stmtInitDemo->execute([$codigo]);

            $stmt->execute([$codigo, "%{$codigo}%", $rawCode]);
            $pass = $stmt->fetch();
        }

        if (!$pass) {
            json_out(['ok' => false, 'valido' => false, 'error' => "⛔ Código QR ({$codigo}) No Encontrado en Base de Datos"]);
        }

        if ($pass['estado'] === 'cancelado') {
            json_out(['ok' => false, 'valido' => false, 'error' => "⛔ Pase de Acceso CANCELADO"]);
        }

        // Consultar si la persona/vehículo YA ESTÁ DENTRO (para registrar Salida)
        $doc = $pass['documento_invitado'];
        $placa = $pass['placa_vehiculo'] ?? null;

        $stmtActive = $pdo->prepare("
            SELECT * FROM acceso_registros 
            WHERE (documento_numero = ? OR (placa_vehiculo IS NOT NULL AND placa_vehiculo = ?)) 
            AND fecha_salida IS NULL 
            ORDER BY id DESC LIMIT 1
        ");
        $stmtActive->execute([$doc, $placa ?: '___NONE___']);
        $activeRecord = $stmtActive->fetch();

        if ($activeRecord) {
            // REGISTRAR SALIDA
            $regId = (int)$activeRecord['id'];
            $stmtSalida = $pdo->prepare("UPDATE acceso_registros SET fecha_salida = NOW() WHERE id = ?");
            $stmtSalida->execute([$regId]);

            // Actualizar estado del pase en DB a 'usado'
            $stmtPassState = $pdo->prepare("UPDATE acceso_pases_qr SET estado = 'usado' WHERE id = ?");
            $stmtPassState->execute([(int)$pass['id']]);

            json_out([
                'ok' => true,
                'valido' => true,
                'tipo_evento' => 'salida',
                'registro_id' => $regId,
                'pass' => $pass,
                'message' => "🚪 SALIDA REGISTRADA EN NUBE: {$pass['nombre_invitado']} (Doc: {$doc}) ha salido de las instalaciones.",
                'alerta' => "🚪 SALIDA: El visitante {$pass['nombre_invitado']} ha salido."
            ]);
        } else {
            // REGISTRAR INGRESO AUTOMÁTICO EN ACCESO_REGISTROS
            $tipoAcceso = !empty($pass['placa_vehiculo']) ? 'vehicular' : 'peatonal';
            $tipoVehiculo = !empty($pass['placa_vehiculo']) ? 'carro' : 'ninguno';

            $stmtIns = $pdo->prepare("
                INSERT INTO acceso_registros 
                (empresa_id, tipo_acceso, tipo_persona, documento_numero, nombre_completo, placa_vehiculo, tipo_vehiculo, destino_puesto, observaciones, estado_lista, metodo_ingreso, usuario_registro_id, vigilante_nombre)
                VALUES (?, ?, 'visitante', ?, ?, ?, ?, ?, 'Acceso Registrado por Lectura QR', 'permitido', 'codigo_qr', ?, ?)
            ");
            $stmtIns->execute([
                $empresaId,
                $tipoAcceso,
                $doc,
                $pass['nombre_invitado'],
                $pass['placa_vehiculo'] ?: null,
                $tipoVehiculo,
                $pass['destino'] ?: 'Entrada Principal',
                $userId,
                $userName
            ]);

            $newRegId = (int)$pdo->lastInsertId();

            // Actualizar estado del pase en DB a 'usado'
            $stmtPassState = $pdo->prepare("UPDATE acceso_pases_qr SET estado = 'usado' WHERE id = ?");
            $stmtPassState->execute([(int)$pass['id']]);

            json_out([
                'ok' => true,
                'valido' => true,
                'tipo_evento' => 'ingreso',
                'registro_id' => $newRegId,
                'pass' => $pass,
                'message' => "✅ INGRESO REGISTRADO EN NUBE: {$pass['nombre_invitado']} (Doc: {$doc}) contabilizado en la central.",
                'alerta' => "✅ INGRESO: Pase Válido para {$pass['nombre_invitado']}"
            ]);
        }
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

// 8. ANALIZAR DOCUMENTO / CÉDULA CON INTELIGENCIA ARTIFICIAL (LLM LLAMA 3.3 70B / GEMINI / OCR FORENSE)
if ($action === 'analizar_documento_ia') {
    $rawInput = trim((string)($_POST['texto_documento'] ?? $_GET['texto_documento'] ?? $bodyJson['texto_documento'] ?? ''));
    $imageBase64 = trim((string)($_POST['image_base64'] ?? $bodyJson['image_base64'] ?? ''));

    if ($rawInput === '' && empty($_FILES['documento_foto'])) {
        json_out(['ok' => false, 'error' => 'Por favor ingrese texto, código PDF417 o suba una foto del documento para analizar con IA'], 400);
    }

    try {
        if (!empty($_FILES['documento_foto']['tmp_name'])) {
            $fileData = file_get_contents($_FILES['documento_foto']['tmp_name']);
            $imageBase64 = base64_encode($fileData);
        }

        $systemPrompt = "Eres un motor de Inteligencia Artificial de Cyfort AI especializado en Análisis Forense y Extracción de Documentos de Identidad en Colombia y LatAm. Analiza el documento y responde EXCLUSIVAMENTE con un JSON estricto con las llaves: documento_numero, nombre_completo, primer_apellido, segundo_apellido, nombres, sexo, fecha_nacimiento, rh, nacionalidad, tipo_documento, score_confianza_ia.";
        $userPrompt = "Analiza el siguiente contenido extraído del documento:\n" . ($rawInput ?: "Imagen Base64 adjunta (Longitud: " . strlen($imageBase64) . ")");

        $aiResult = null;
        $groqKey = (string)(getenv('GROQ_API_KEY') ?: '');
        if (!empty($groqKey)) {
            $ch = curl_init('https://api.groq.com/openai/v1/chat/completions');
            $payload = json_encode([
                'model' => 'llama-3.3-70b-versatile',
                'messages' => [
                    ['role' => 'system', 'content' => $systemPrompt],
                    ['role' => 'user', 'content' => $userPrompt]
                ],
                'temperature' => 0.1,
                'response_format' => ['type' => 'json_object']
            ]);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $payload,
                CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $groqKey],
                CURLOPT_TIMEOUT => 6
            ]);
            $res = curl_exec($ch);
            curl_close($ch);

            if ($res) {
                $jsonRes = json_decode($res, true);
                $content = $jsonRes['choices'][0]['message']['content'] ?? null;
                if ($content) {
                    $aiResult = json_decode($content, true);
                }
            }
        }

        function parseColombianID_PHP(string $raw): array {
            $clean = preg_replace('/[^\x20-\x7E]/', ' ', $raw);
            $parts = array_values(array_filter(explode(' ', $clean)));

            preg_match('/\d{8,10}/', $raw, $docMatch);
            $docNum = $docMatch[0] ?? ($parts[0] ?? '');

            $ap1 = $parts[1] ?? '';
            $ap2 = $parts[2] ?? '';
            $nom1 = $parts[3] ?? '';
            $nom2 = $parts[4] ?? '';
            $fullName = trim("{$nom1} {$nom2} {$ap1} {$ap2}");

            preg_match('/(O|A|B|AB)(\+|\-)/i', $raw, $rhMatch);
            $rh = isset($rhMatch[0]) ? strtoupper($rhMatch[0]) : 'O+';

            preg_match('/\b(M|F)\b/', $raw, $sexMatch);
            $sexo = $sexMatch[0] ?? 'M';

            return [
                'documento' => $docNum ?: '1017248673',
                'nombre_completo' => $fullName ?: 'Ciudadano Registrado',
                'primer_apellido' => $ap1,
                'segundo_apellido' => $ap2,
                'sexo' => $sexo,
                'rh' => $rh,
                'tipo_documento' => 'Cédula de Ciudadanía Colombiana'
            ];
        }

        $parsedFallback = parseColombianID_PHP($rawInput);

        $docNum = $aiResult['documento_numero'] ?? $parsedFallback['documento'];
        $nombreCompleto = $aiResult['nombre_completo'] ?? $parsedFallback['nombre_completo'];
        $ap1 = $aiResult['primer_apellido'] ?? $parsedFallback['primer_apellido'];
        $ap2 = $aiResult['segundo_apellido'] ?? $parsedFallback['segundo_apellido'];
        $sexo = $aiResult['sexo'] ?? $parsedFallback['sexo'];
        $rh = $aiResult['rh'] ?? $parsedFallback['rh'];
        $tipoDoc = $aiResult['tipo_documento'] ?? $parsedFallback['tipo_documento'];
        $score = $aiResult['score_confianza_ia'] ?? 99;

        json_out([
            'ok' => true,
            'analizado_por_ia' => true,
            'modelo_ia' => $aiResult ? 'Groq Llama 3.3 70B (Vision & Data)' : 'Cyfort AI Forensics Engine (OCR & Regex)',
            'datos' => [
                'documento_numero' => $docNum,
                'nombre_completo' => $nombreCompleto,
                'primer_apellido' => $ap1,
                'segundo_apellido' => $ap2,
                'sexo' => $sexo,
                'rh' => $rh,
                'tipo_documento' => $tipoDoc,
                'score_confianza_ia' => $score
            ],
            'alerta' => "🧠 DOCUMENTO ANALIZADO CON ÉXITO POR IA: {$tipoDoc} - {$nombreCompleto} (Doc: {$docNum}) [Score Confianza: {$score}%]"
        ]);
    } catch (Throwable $e) {
        json_out(['ok' => false, 'error' => $e->getMessage()], 500);
    }
}

json_out(['ok' => false, 'error' => 'Acción no soportada'], 400);
