<?php
/**
 * GET /modules/turnero/api/get_consentimientos.php
 * Retorna el estado actualizado de los consentimientos de un turno.
 * Usado por lugar.php (polling cada 5 s) y recepcion.php.
 * No requiere autenticación (las pantallas internas ya están protegidas).
 *
 * Query params:
 *   turno_id          int   requerido
 *   incluir_solicitud int   opcional  1 → también retorna solicitud, paciente y exámenes
 */

require_once __DIR__ . '/_helpers.php';
requireMethod('GET');

$turnoId         = isset($_GET['turno_id'])          ? (int) $_GET['turno_id']          : 0;
$incluirSolicitud = isset($_GET['incluir_solicitud']) ? (bool)(int)$_GET['incluir_solicitud'] : false;

if ($turnoId <= 0) jsonError('turno_id inválido.');

$pdo = db();

// ── Verificar que el turno existe ─────────────────────────────
$stmt = $pdo->prepare("SELECT id, estado, lugar_destino_id FROM turnero_turnos WHERE id = ?");
$stmt->execute([$turnoId]);
$turno = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$turno) jsonError('Turno no encontrado.', 404);

// ── Formularios de lugar ──────────────────────────────────────────────────────
// Solo cuando el turno tiene lugar destino asignado. En recepción (NULL),
// fidsDeLugar queda vacío → todos los consentimientos reciben origen_lugar_id=null
// → pasan el filtro !c.origen_lugar_id de recepcion.php.
$lugarDestinoId = (int)($turno['lugar_destino_id'] ?? 0);
$fidsDeLugar    = [];
if ($lugarDestinoId) {
    $stmtL = $pdo->prepare(
        "SELECT formulario_id FROM turnero_lugar_consentimientos WHERE lugar_id = ?"
    );
    $stmtL->execute([$lugarDestinoId]);
    $fidsDeLugar = array_map('intval', $stmtL->fetchAll(PDO::FETCH_COLUMN));
}

// ── Consentimientos ───────────────────────────────────────────
$stmt = $pdo->prepare(
    "SELECT tc.id,
            tc.turno_id,
            tc.formulario_id,
            tc.token,
            tc.estado,
            tc.enviado_at,
            tc.firmado_at,
            (tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
            tc.firmado_profesional_at,
            tc.siguiente_toma_at,
            tc.toma_inicio_at,
            tc.datos_respuestas,
            f.nombre               AS formulario_nombre,
            f.esquema              AS formulario_esquema,
            f.es_toma_progresiva   AS formulario_es_toma_prog
       FROM turnero_consentimientos tc
       LEFT JOIN lab_formularios f ON f.id = tc.formulario_id
      WHERE tc.turno_id = ?
      ORDER BY tc.id ASC"
);
$stmt->execute([$turnoId]);
$consentimientos = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Compute flags desde el esquema; origen_lugar_id calculado según config actual
foreach ($consentimientos as &$c) {
    $esquema = $c['formulario_esquema'] ?? null;
    $campos  = [];
    if ($esquema) {
        $decoded = json_decode($esquema, true);
        $campos  = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
    }
    $camposFirmaPro = array_values(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
    $tieneFirmaPro  = !empty($camposFirmaPro);
    $tieneFirmaPac  = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));

    // Toma progresiva: override explícito en DB gana; si es NULL, usar heurística (>1 campo firma_profesional)
    $overrideProg = $c['formulario_es_toma_prog'] ?? null;
    $esTomaProg   = $overrideProg !== null ? (bool)(int)$overrideProg : count($camposFirmaPro) > 1;
    $tomasTotal   = count($camposFirmaPro);
    $tomasFirm   = 0;
    if ($esTomaProg && $c['datos_respuestas']) {
        $dr = json_decode($c['datos_respuestas'], true) ?? [];
        foreach ($camposFirmaPro as $fp) {
            if (!empty($dr[$fp['id']]) && strlen($dr[$fp['id']]) > 10) $tomasFirm++;
        }
    }

    $c['requiere_firma_profesional'] = $tieneFirmaPro;
    $c['requiere_firma_paciente']    = !($tieneFirmaPro && !$tieneFirmaPac);
    $c['origen_lugar_id']            = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
                                       ? ($lugarDestinoId ?: -1) : null;
    $c['es_toma_progresiva']         = $esTomaProg;
    $c['tomas_total']                = $tomasTotal;
    $c['tomas_firmadas']             = $tomasFirm;
    // Exponer campos firma_profesional (ids) para el frontend
    $c['campos_firma_pro']           = array_column($camposFirmaPro, 'id');
    unset($c['formulario_esquema'], $c['formulario_es_toma_prog'], $c['datos_respuestas']);
}
unset($c);

$respuesta = [
    'turno_id'        => $turnoId,
    'turno_estado'    => $turno['estado'],
    'consentimientos' => $consentimientos,
];

// ── Datos adicionales si solicita solicitud ───────────────────
if ($incluirSolicitud) {
    $stmt = $pdo->prepare(
        "SELECT s.id, s.turno_id, s.paciente_id, s.lugar_id,
                s.numero_orden,
                s.total_cobrado, s.metodo_pago, s.observaciones, s.embarazada, s.solo_muestras, s.medico_id, s.creado_at,
                l.nombre AS lugar_nombre,
                CONCAT(m.nombres, ' ', m.apellidos) AS medico_nombre,
                m.cod_especialidad AS medico_especialidad,
                m.codigo AS medico_codigo
           FROM turnero_solicitudes s
           LEFT JOIN turnero_lugares l ON l.id = s.lugar_id
           LEFT JOIN medicos m ON m.id = s.medico_id
          WHERE s.turno_id = ?
          LIMIT 1"
    );
    $stmt->execute([$turnoId]);
    $solicitud = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;

    $paciente = null;
    $examenes = [];

    if ($solicitud) {
        // Paciente
        $stmt = $pdo->prepare(
            "SELECT id, nombre_completo, tipo_documento, numero_documento,
                    fecha_nacimiento, telefono
               FROM lab_pacientes
              WHERE id = ?"
        );
        $stmt->execute([$solicitud['paciente_id']]);
        $paciente = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;

        // Exámenes
        $stmt = $pdo->prepare(
            "SELECT et.id, et.codigo, et.nombre, et.categoria
               FROM turnero_examen_items tei
               JOIN exam_tipos et ON et.id = tei.exam_tipo_id
              WHERE tei.solicitud_id = ?
              ORDER BY et.categoria, et.nombre"
        );
        $stmt->execute([$solicitud['id']]);
        $examenes = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // Auto-crear consentimientos requeridos desde DOS fuentes:
        // 1. Por examen  → exam_tipo_consentimientos
        // 2. Por lugar   → turnero_lugar_consentimientos
        $requeridos   = [];
        $vistosFIds   = [];

        // Fuente 1: examen
        if (!empty($examenes)) {
            $examIds = array_column($examenes, 'id');
            $ph = implode(',', array_fill(0, count($examIds), '?'));
            $stmtE = $pdo->prepare(
                "SELECT DISTINCT etc.formulario_id, f.nombre AS formulario_nombre
                   FROM exam_tipo_consentimientos etc
                   JOIN lab_formularios f ON f.id = etc.formulario_id
                  WHERE etc.exam_tipo_id IN ($ph) AND f.is_active = 1"
            );
            $stmtE->execute($examIds);
            foreach ($stmtE->fetchAll(PDO::FETCH_ASSOC) as $r) {
                $fid = (int)$r['formulario_id'];
                if (!in_array($fid, $vistosFIds, true)) {
                    $requeridos[] = $r;
                    $vistosFIds[] = $fid;
                }
            }
        }

        // Fuente 2: lugar destino ($lugarDestinoId y $fidsDeLugar ya calculados arriba)
        if ($lugarDestinoId) {
            $stmtL = $pdo->prepare(
                "SELECT DISTINCT tlc.formulario_id, f.nombre AS formulario_nombre
                   FROM turnero_lugar_consentimientos tlc
                   JOIN lab_formularios f ON f.id = tlc.formulario_id
                  WHERE tlc.lugar_id = ? AND f.is_active = 1"
            );
            $stmtL->execute([$lugarDestinoId]);
            foreach ($stmtL->fetchAll(PDO::FETCH_ASSOC) as $r) {
                $fid = (int)$r['formulario_id'];
                if (!in_array($fid, $vistosFIds, true)) {
                    $requeridos[] = $r;
                    $vistosFIds[] = $fid;
                }
            }
        }

        // Auto-crear los registros que falten
        if (!empty($requeridos)) {
            $existFormIds = array_map('intval', array_column($consentimientos, 'formulario_id'));
            $stmtIns = $pdo->prepare(
                "INSERT IGNORE INTO turnero_consentimientos
                    (turno_id, formulario_id, token, estado)
                 VALUES (?, ?, ?, 'pendiente')"
            );
            $creados = 0;
            foreach ($requeridos as $r) {
                if (!in_array((int)$r['formulario_id'], $existFormIds, true)) {
                    $token = sprintf(
                        '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
                        mt_rand(0,0xffff), mt_rand(0,0xffff),
                        mt_rand(0,0xffff),
                        mt_rand(0,0x0fff)|0x4000,
                        mt_rand(0,0x3fff)|0x8000,
                        mt_rand(0,0xffff), mt_rand(0,0xffff), mt_rand(0,0xffff)
                    );
                    $stmtIns->execute([$turnoId, (int)$r['formulario_id'], $token]);
                    $creados++;
                }
            }

            // Re-leer si se crearon nuevos registros y recalcular flags
            if ($creados > 0) {
                $stmtC = $pdo->prepare(
                    "SELECT tc.id, tc.turno_id, tc.formulario_id, tc.token,
                            tc.estado, tc.enviado_at, tc.firmado_at,
                            (tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
                            tc.firmado_profesional_at,
                            tc.siguiente_toma_at,
                            tc.toma_inicio_at,
                            tc.datos_respuestas,
                            f.nombre               AS formulario_nombre,
                            f.esquema              AS formulario_esquema,
                            f.es_toma_progresiva   AS formulario_es_toma_prog
                       FROM turnero_consentimientos tc
                       LEFT JOIN lab_formularios f ON f.id = tc.formulario_id
                      WHERE tc.turno_id = ?
                      ORDER BY tc.id ASC"
                );
                $stmtC->execute([$turnoId]);
                $consentimientos = $stmtC->fetchAll(PDO::FETCH_ASSOC);
                foreach ($consentimientos as &$c) {
                    $esquema = $c['formulario_esquema'] ?? null;
                    $campos  = [];
                    if ($esquema) {
                        $decoded = json_decode($esquema, true);
                        $campos  = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
                    }
                    $camposFirmaPro = array_values(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
                    $tieneFirmaPro  = !empty($camposFirmaPro);
                    $tieneFirmaPac  = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
                    $overrideProg   = $c['formulario_es_toma_prog'] ?? null;
                    $esTomaProg     = $overrideProg !== null ? (bool)(int)$overrideProg : count($camposFirmaPro) > 1;
                    $tomasFirm      = 0;
                    if ($esTomaProg && $c['datos_respuestas']) {
                        $dr = json_decode($c['datos_respuestas'], true) ?? [];
                        foreach ($camposFirmaPro as $fp) {
                            if (!empty($dr[$fp['id']]) && strlen($dr[$fp['id']]) > 10) $tomasFirm++;
                        }
                    }
                    $c['requiere_firma_profesional'] = $tieneFirmaPro;
                    $c['requiere_firma_paciente']    = !($tieneFirmaPro && !$tieneFirmaPac);
                    $c['origen_lugar_id']            = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
                                                       ? $lugarDestinoId : null;
                    $c['es_toma_progresiva']         = $esTomaProg;
                    $c['tomas_total']                = count($camposFirmaPro);
                    $c['tomas_firmadas']             = $tomasFirm;
                    $c['campos_firma_pro']           = array_column($camposFirmaPro, 'id');
                    unset($c['formulario_esquema'], $c['formulario_es_toma_prog'], $c['datos_respuestas']);
                }
                unset($c);
                $respuesta['consentimientos'] = $consentimientos;
            }
        }
    }

    // Muestras pendientes / recibidas del turno
    $muestras = [];
    if ($solicitud) {
        try {
            $stmtM = $pdo->prepare(
                "SELECT tm.id, tm.tipo_muestra, tm.estado, tm.motivo_rechazo, tm.recibida_at,
                        COALESCE(lt.nombre, tm.tipo_muestra) AS label,
                        0 AS es_pendiente_anterior, NULL AS solicitud_orden_anterior
                   FROM turnero_muestras tm
                   LEFT JOIN lab_tipos_muestra lt ON lt.codigo = tm.tipo_muestra
                  WHERE tm.solicitud_id = ?
                  ORDER BY tm.id ASC"
            );
            $stmtM->execute([$solicitud['id']]);
            $muestras = $stmtM->fetchAll(PDO::FETCH_ASSOC);

            // Si es visita de entrega de muestras, agregar pendientes de solicitudes anteriores
            if (!empty($solicitud['solo_muestras']) && !empty($solicitud['paciente_id'])) {
                $stmtPrev = $pdo->prepare(
                    "SELECT tm.id, tm.tipo_muestra, tm.estado, tm.motivo_rechazo, tm.recibida_at,
                            COALESCE(lt.nombre, tm.tipo_muestra) AS label,
                            1 AS es_pendiente_anterior,
                            ts.numero_orden AS solicitud_orden_anterior
                       FROM turnero_muestras tm
                       JOIN turnero_solicitudes ts ON ts.id = tm.solicitud_id
                       LEFT JOIN lab_tipos_muestra lt ON lt.codigo = tm.tipo_muestra
                      WHERE ts.paciente_id = ?
                        AND tm.solicitud_id != ?
                        AND tm.estado = 'pendiente'
                      ORDER BY tm.id ASC"
                );
                $stmtPrev->execute([$solicitud['paciente_id'], $solicitud['id']]);
                $previas = $stmtPrev->fetchAll(PDO::FETCH_ASSOC);
                $muestras = array_merge($previas, $muestras);
            }
        } catch (\Throwable $_) {
            // Tabla aún no existe
        }
    }

    $respuesta['solicitud'] = $solicitud;
    $respuesta['paciente']  = $paciente;
    $respuesta['examenes']  = $examenes;
    $respuesta['muestras']  = $muestras;
}

jsonOk($respuesta);
