<?php
/**
 * modules/turnero/api/get_historial.php
 * GET  Historial paginado de turnos con filtros multi-día.
 *
 * Parámetros (todos opcionales):
 *   fecha_desde  YYYY-MM-DD  (default: hace 7 días)
 *   fecha_hasta  YYYY-MM-DD  (default: hoy)
 *   estado       string      ("finalizado","ausente","cancelado","en_servicio",... o vacío = todos)
 *   lugar_id     int         (0 = todos)
 *   prioridad_id int         (0 = todos)
 *   q            string      búsqueda libre por nombre/código
 *   page         int         (default 1)
 *   per_page     int         (default 50, max 200)
 */
require_once __DIR__ . '/_helpers.php';

requireTurnero();
requireMethod('GET');

$pdo = db();

// ── Parámetros ────────────────────────────────────────────────
$hoy          = date('Y-m-d');
$hace7        = date('Y-m-d', strtotime('-6 days'));

$fechaDesde  = trim($_GET['fecha_desde'] ?? '');
$fechaHasta  = trim($_GET['fecha_hasta'] ?? '');
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fechaDesde)) $fechaDesde = $hace7;
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fechaHasta)) $fechaHasta = $hoy;
if ($fechaDesde > $fechaHasta)                          $fechaDesde = $fechaHasta;

$estadoFiltro  = trim($_GET['estado']       ?? '');
$lugarId       = (int)($_GET['lugar_id']    ?? 0);
$prioridadId   = (int)($_GET['prioridad_id'] ?? 0);
$pacienteId    = (int)($_GET['paciente_id'] ?? 0);
$q             = trim($_GET['q']            ?? '');

$perPage = min(200, max(10, (int)($_GET['per_page'] ?? 50)));
$page    = max(1, (int)($_GET['page'] ?? 1));
$offset  = ($page - 1) * $perPage;

// ── Base WHERE ───────────────────────────────────────────────
//   Unimos turnos con sesiones para filtrar por fecha de sesión
$where  = ['DATE(s.fecha) BETWEEN ? AND ?'];
$binds  = [$fechaDesde, $fechaHasta];

$estadosValidos = ['espera','en_recepcion','en_espera_lugar','en_servicio','finalizado','ausente','cancelado'];
if ($estadoFiltro && in_array($estadoFiltro, $estadosValidos, true)) {
    $where[] = 't.estado = ?';
    $binds[] = $estadoFiltro;
}
if ($lugarId > 0) {
    $where[] = 't.lugar_destino_id = ?';
    $binds[] = $lugarId;
}
if ($prioridadId > 0) {
    $where[] = 't.prioridad_id = ?';
    $binds[] = $prioridadId;
}
if ($pacienteId > 0) {
    $where[] = 'ts2.paciente_id = ?';
    $binds[] = $pacienteId;
}
if ($q !== '') {
    $where[] = '(t.codigo LIKE ? OR t.paciente_nombre LIKE ? OR s2.nombre_completo LIKE ?)';
    $like     = '%' . $q . '%';
    $binds[]  = $like;
    $binds[]  = $like;
    $binds[]  = $like;
}

$whereStr = 'WHERE ' . implode(' AND ', $where);

// ── Conteo total ──────────────────────────────────────────────
$sqlCount = "
    SELECT COUNT(*) AS total
    FROM   turnero_turnos t
    JOIN   turnero_sesiones s    ON s.id  = t.sesion_id
    LEFT   JOIN turnero_solicitudes ts2 ON ts2.turno_id = t.id
    LEFT   JOIN lab_pacientes s2        ON s2.id = ts2.paciente_id
    $whereStr";

$stmtCount = $pdo->prepare($sqlCount);
$stmtCount->execute($binds);
$totalRows = (int)$stmtCount->fetchColumn();
$totalPages = max(1, (int)ceil($totalRows / $perPage));
if ($page > $totalPages) $page = $totalPages;
$offset = ($page - 1) * $perPage;

// ── Lista paginada ────────────────────────────────────────────
$sqlTurnos = "
    SELECT
        t.id,
        t.codigo,
        t.numero,
        t.estado,
        t.paciente_nombre,
        t.paciente_cel,
        t.creado_at,
        t.inicio_recepcion_at,
        t.fin_recepcion_at,
        t.inicio_lugar_at,
        t.fin_lugar_at,
        s.fecha                           AS fecha_sesion,
        p.codigo  AS prioridad_codigo,
        p.nombre  AS prioridad_nombre,
        p.color   AS prioridad_color,
        l.nombre  AS lugar_nombre,
        s2.nombre_completo                AS paciente_bd,
        rd.nombre                         AS recepcion_desk_nombre,
        ur.full_name                      AS atendido_recepcion_nombre,
        ul.full_name                      AS atendido_lugar_nombre,
        ts2.observaciones                 AS notas,
        ROUND(TIMESTAMPDIFF(SECOND, t.creado_at,
              COALESCE(t.inicio_recepcion_at, t.fin_recepcion_at)) / 60.0, 1)
                                          AS espera_min,
        ROUND(TIMESTAMPDIFF(SECOND, t.inicio_lugar_at,
              COALESCE(t.fin_lugar_at, NOW())) / 60.0, 1)
                                          AS servicio_min
    FROM   turnero_turnos t
    JOIN   turnero_sesiones s    ON s.id  = t.sesion_id
    JOIN   turnero_prioridades p ON p.id  = t.prioridad_id
    LEFT   JOIN turnero_lugares l         ON l.id  = t.lugar_destino_id
    LEFT   JOIN turnero_lugares rd        ON rd.id = t.recepcion_desk_id
    LEFT   JOIN admin_users ur            ON ur.id = t.atendido_recepcion_por
    LEFT   JOIN admin_users ul            ON ul.id = t.atendido_lugar_por
    LEFT   JOIN turnero_solicitudes ts2   ON ts2.turno_id = t.id
    LEFT   JOIN lab_pacientes s2          ON s2.id = ts2.paciente_id
    $whereStr
    ORDER  BY t.creado_at DESC
    LIMIT  ? OFFSET ?";

$bindsPage   = array_merge($binds, [$perPage, $offset]);
$stmtTurnos  = $pdo->prepare($sqlTurnos);
$stmtTurnos->execute($bindsPage);
$turnos = $stmtTurnos->fetchAll(PDO::FETCH_ASSOC);

// ── Enriquecer con exámenes y consentimientos ──────────────────
foreach ($turnos as &$turno) {
    // Exámenes
    $stmtExam = $pdo->prepare(
        "SELECT DISTINCT et.nombre, et.codigo
           FROM turnero_examen_items tei
           JOIN exam_tipos et ON et.id = tei.exam_tipo_id
          WHERE tei.solicitud_id = (
              SELECT id FROM turnero_solicitudes WHERE turno_id = ? LIMIT 1
          )
          ORDER BY et.nombre ASC"
    );
    $stmtExam->execute([(int)$turno['id']]);
    $turno['examenes'] = $stmtExam->fetchAll(PDO::FETCH_ASSOC);

    // Consentimientos
    $stmtCons = $pdo->prepare(
        "SELECT tc.id, f.nombre, tc.estado, tc.firmado_at
           FROM turnero_consentimientos tc
           LEFT JOIN lab_formularios f ON f.id = tc.formulario_id
          WHERE tc.turno_id = ?
          ORDER BY tc.estado DESC, tc.firmado_at DESC"
    );
    $stmtCons->execute([(int)$turno['id']]);
    $turno['consentimientos'] = $stmtCons->fetchAll(PDO::FETCH_ASSOC);

    // Comentarios
    $stmtCom = $pdo->prepare(
        "SELECT usuario_nombre, comentario, tipo, creado_at
           FROM turnero_comentarios
          WHERE turno_id = ?
          ORDER BY creado_at DESC
          LIMIT 3"
    );
    $stmtCom->execute([(int)$turno['id']]);
    $turno['comentarios'] = $stmtCom->fetchAll(PDO::FETCH_ASSOC);
}

// ── Resumen por estado (del rango filtrado) ───────────────────
$sqlRes = "
    SELECT t.estado, COUNT(*) AS cnt
    FROM   turnero_turnos t
    JOIN   turnero_sesiones s    ON s.id  = t.sesion_id
    LEFT   JOIN turnero_solicitudes ts2 ON ts2.turno_id = t.id
    LEFT   JOIN lab_pacientes s2        ON s2.id = ts2.paciente_id
    $whereStr
    GROUP  BY t.estado";
$stmtRes = $pdo->prepare($sqlRes);
$stmtRes->execute($binds);
$resumenEstados = [];
foreach ($stmtRes->fetchAll(PDO::FETCH_ASSOC) as $r) {
    $resumenEstados[$r['estado']] = (int)$r['cnt'];
}

// ── Catálogos para los selectores (si pide con ?meta=1) ──────
$meta = [];
if (!empty($_GET['meta'])) {
    $meta['lugares'] = $pdo->query(
        "SELECT id, nombre FROM turnero_lugares WHERE activo=1 ORDER BY sort_order ASC, nombre ASC"
    )->fetchAll(PDO::FETCH_ASSOC);

    $meta['prioridades'] = $pdo->query(
        "SELECT id, nombre, codigo, color FROM turnero_prioridades ORDER BY orden_peso ASC"
    )->fetchAll(PDO::FETCH_ASSOC);
}

jsonOk([
    'fecha_desde'    => $fechaDesde,
    'fecha_hasta'    => $fechaHasta,
    'total'          => $totalRows,
    'page'           => $page,
    'per_page'       => $perPage,
    'total_pages'    => $totalPages,
    'resumen_estados'=> $resumenEstados,
    'turnos'         => $turnos,
    'meta'           => $meta,
]);
