<?php
/**
 * POST /api/lab/ingest_paciente.php
 * Endpoint server-to-server para ingesta de pacientes desde RIPS Manager.
 * Autenticación: header  X-Lab-Key: <LAB_SYNC_KEY>  (sin sesión de usuario).
 *
 * Body JSON (todos opcionales excepto nombre_completo en creación):
 *   { numero_documento, tipo_documento, nombre_completo, telefono, email,
 *     fecha_nacimiento, genero, direccion, ciudad, eps, origen }
 *
 * Respuesta:
 *   { ok, action: "created"|"updated"|"skipped", id, message }
 */

ob_start();
require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../classes/lab/Paciente.php';

error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', '0');
ini_set('html_errors', '0');

register_shutdown_function(function () {
    $err = error_get_last();
    if ($err && in_array($err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        ob_clean();
        http_response_code(500);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok' => false, 'error' => 'Error interno: ' . $err['message']]);
    }
});

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Lab-Key, X-Lab-Sync-Key');
header('Access-Control-Max-Age: 86400');

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'Método no permitido']);
    exit;
}

// ── Autenticación por API key ────────────────────────────────────────────────
$keyHeader = $_SERVER['HTTP_X_LAB_KEY']
    ?? $_SERVER['HTTP_X_LAB_SYNC_KEY']
    ?? '';

if (!$keyHeader || !hash_equals(LAB_SYNC_KEY, $keyHeader)) {
    http_response_code(401);
    ob_clean();
    echo json_encode(['ok' => false, 'error' => 'API key inválida']);
    exit;
}

// ── Leer body ────────────────────────────────────────────────────────────────
$raw  = file_get_contents('php://input');
$data = json_decode($raw, true);

if (!is_array($data)) {
    http_response_code(400);
    ob_clean();
    echo json_encode(['ok' => false, 'error' => 'Body JSON inválido']);
    exit;
}

// ── Normalizar campos ────────────────────────────────────────────────────────
$campos = [];

if (!empty($data['nombre_completo'])) {
    $campos['nombre_completo'] = mb_strtoupper(trim($data['nombre_completo']));
}
if (!empty($data['numero_documento'])) {
    $campos['numero_documento'] = trim($data['numero_documento']);
}
if (!empty($data['tipo_documento'])) {
    $tiposValidos = ['CC', 'CE', 'TI', 'PA', 'NIT', 'RC', 'MS'];
    $t = strtoupper(trim($data['tipo_documento']));
    $campos['tipo_documento'] = in_array($t, $tiposValidos) ? $t : 'CC';
}
if (!empty($data['telefono'])) {
    $tel = preg_replace('/[^0-9+]/', '', $data['telefono']);
    if (strlen($tel) >= 6) {
        $campos['telefono'] = $tel;
    }
}
if (!empty($data['email']) && filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
    $e = strtolower(trim($data['email']));
    // Ignorar emails de relleno generados por RIPS
    if (!str_contains($e, '@sinregistro.co') && !str_contains($e, 'sinregistro')) {
        $campos['email'] = $e;
    }
}
if (!empty($data['fecha_nacimiento'])) {
    $fn = trim($data['fecha_nacimiento']);
    // Acepta dd/mm/yyyy o yyyy-mm-dd
    if (preg_match('/^(\d{2})\/(\d{2})\/(\d{4})$/', $fn, $m)) {
        $campos['fecha_nacimiento'] = "{$m[3]}-{$m[2]}-{$m[1]}";
    } elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/', $fn)) {
        $campos['fecha_nacimiento'] = $fn;
    }
}
if (!empty($data['genero'])) {
    $g = strtoupper(trim($data['genero']));
    if (in_array($g, ['M', 'F', 'O'])) {
        $campos['genero'] = $g;
    }
}
if (!empty($data['direccion'])) {
    $campos['direccion'] = trim($data['direccion']);
}
if (!empty($data['ciudad'])) {
    $campos['ciudad'] = trim($data['ciudad']);
}
if (!empty($data['eps'])) {
    $campos['eps'] = trim($data['eps']);
}
// origen solo se aplica en creación, nunca en update
$origenValidos = ['manual', 'lab', 'whatsapp'];
$campos['origen'] = in_array($data['origen'] ?? '', $origenValidos, true)
    ? $data['origen'] : 'lab';

// ── Modo: "insertar" (solo nuevos) | "upsert" (crea o actualiza) ─────────────
$modo = trim($data['modo'] ?? 'upsert');
if (!in_array($modo, ['insertar', 'upsert'], true)) {
    $modo = 'upsert';
}

// ── Exámenes opcionales (vienen del scheduler de RIPS) ───────────────────────
$examenesRaw = $data['examenes'] ?? null;
$examenesGuardados = 0;

function db(): \PDO {
    return Database::getInstance()->getConnection();
}

function guardarExamenesPendientes(string $doc, array $examenes): int {
    if (!$examenes || !$doc) return 0;
    $pdo = db();

    $stDel = $pdo->prepare(
        "DELETE FROM rips_examenes_pendientes
         WHERE numero_documento = ? AND DATE(created_at) = CURDATE()"
    );
    if (!$stDel) {
        $info = $pdo->errorInfo();
        throw new \RuntimeException("rips_examenes_pendientes no existe o error: {$info[2]}");
    }
    $stDel->execute([$doc]);

    $meta  = $examenes[0] ?? [];
    $stIns = $pdo->prepare(
        "INSERT INTO rips_examenes_pendientes
            (numero_documento, datos, recepcion_id, hora_recepcion)
         VALUES (?, ?, ?, ?)"
    );
    if (!$stIns) {
        $info = $pdo->errorInfo();
        throw new \RuntimeException("INSERT rips_examenes_pendientes falló: {$info[2]}");
    }
    $stIns->execute([
        $doc,
        json_encode($examenes, JSON_UNESCAPED_UNICODE),
        $meta['recepcion_id'] ?? null,
        $meta['hora']         ?? null,
    ]);
    return count($examenes);
}

// ── UPSERT / INSERT-ONLY ─────────────────────────────────────────────────────
try {
    $pac = new Paciente();

    $existente = null;
    if (!empty($campos['numero_documento'])) {
        $existente = $pac->porDocumento($campos['numero_documento']);
    }

    ob_clean();

    if ($existente) {
        if (!empty($examenesRaw) && is_array($examenesRaw)) {
            $examenesGuardados = guardarExamenesPendientes($campos['numero_documento'], $examenesRaw);
        }
        if ($modo === 'insertar') {
            echo json_encode([
                'ok'                => true,
                'action'            => 'skipped',
                'id'                => $existente['id'],
                'message'           => 'Paciente ya existe',
                'examenes_guardados' => $examenesGuardados,
            ]);
        } else {
            // Nunca pisar origen en update — conservar el que ya tiene en BD
            unset($campos['origen']);
            $pac->actualizar($existente['id'], $campos, null);
            echo json_encode([
                'ok'                => true,
                'action'            => 'updated',
                'id'                => $existente['id'],
                'message'           => 'Paciente actualizado',
                'examenes_guardados' => $examenesGuardados,
            ]);
        }
    } elseif (!empty($campos['nombre_completo'])) {
        $id = $pac->crear($campos, null);
        if (!empty($examenesRaw) && is_array($examenesRaw)) {
            $examenesGuardados = guardarExamenesPendientes($campos['numero_documento'], $examenesRaw);
        }
        echo json_encode([
            'ok'                => true,
            'action'            => 'created',
            'id'                => $id,
            'message'           => 'Paciente creado',
            'examenes_guardados' => $examenesGuardados,
        ]);
    } else {
        http_response_code(422);
        echo json_encode([
            'ok'     => false,
            'action' => 'skipped',
            'error'  => 'Sin número de documento ni nombre: registro omitido',
        ]);
    }
} catch (\Throwable $e) {
    ob_clean();
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
}
