<?php
/**
 * modules/turnero/api/get_dashboard.php
 * GET ?fecha=YYYY-MM-DD   (por defecto = hoy)
 *
 * Devuelve métricas del día para el dashboard del turnero:
 *   - resumen global (total, atendidos, pendientes, ausentes, tiempo promedio)
 *   - desglose por prioridad
 *   - desglose por lugar
 *   - desglose por recepcionista y por bacteriólogo (quién atendió a cuántos)
 *   - lista de turnos del día (para tabla detalle)
 */
require_once __DIR__ . '/_helpers.php';

requireTurnero();
requireMethod('GET');

$fecha = trim($_GET['fecha'] ?? '');
if ($fecha === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) {
    $fecha = date('Y-m-d');
}

$pdo = db();

// ── 1. Sesión del día ─────────────────────────────────────────
$stmtSesion = $pdo->prepare(
    'SELECT id, inicio_at, fin_at FROM turnero_sesiones WHERE fecha = ? LIMIT 1'
);
$stmtSesion->execute([$fecha]);
$sesion = $stmtSesion->fetch(PDO::FETCH_ASSOC);

if (!$sesion) {
    jsonOk([
        'fecha'   => $fecha,
        'sesion'  => null,
        'resumen' => [
            'total'                        => 0,
            'atendidos'                    => 0,
            'en_espera'                    => 0,
            'ausentes'                     => 0,
            'cancelados'                   => 0,
            'tiempo_espera_promedio_min'   => null,
            'tiempo_servicio_promedio_min' => null,
        ],
        'por_prioridad'     => [],
        'por_lugar'         => [],
        'por_recepcionista' => [],
        'por_bacteriologo'  => [],
        'consent_stats'     => [],
        'turnos'            => [],
    ]);
}

$sesionId = (int)$sesion['id'];

// ── 2. Resumen global ─────────────────────────────────────────
$stmtRes = $pdo->prepare(
    "SELECT
        COUNT(*) AS total,
        SUM(t.estado IN ('finalizado','en_servicio')) AS atendidos,
        SUM(t.estado IN ('espera','en_recepcion','en_espera_lugar')) AS en_espera,
        SUM(t.estado = 'ausente')    AS ausentes,
        SUM(t.estado = 'cancelado')  AS cancelados,
        ROUND(
            AVG(
                CASE
                    WHEN t.inicio_recepcion_at IS NOT NULL AND t.creado_at IS NOT NULL
                    THEN TIMESTAMPDIFF(SECOND, t.creado_at, t.inicio_recepcion_at) / 60.0
                END
            ), 1
        ) AS tiempo_espera_promedio_min,
        -- En los protocolos prolongados la atención se corta en la PRIMERA toma:
        -- lo que sigue son horas de espera del examen (una curva de glucosa son
        -- 2 horas), no tiempo de trabajo. Contarlas triplicaba el promedio —21,9
        -- min contra 7,4— y hacía ver los puestos mucho más lentos de lo que son.
        ROUND(
            AVG(
                CASE
                    WHEN t.inicio_lugar_at IS NOT NULL
                     AND COALESCE(prot.toma_inicio_at, t.fin_lugar_at) IS NOT NULL
                    THEN TIMESTAMPDIFF(SECOND, t.inicio_lugar_at,
                                       COALESCE(prot.toma_inicio_at, t.fin_lugar_at)) / 60.0
                END
            ), 1
        ) AS tiempo_servicio_promedio_min,
        ROUND(
            AVG(
                CASE
                    WHEN t.creado_at IS NOT NULL
                     AND COALESCE(prot.toma_inicio_at, t.fin_lugar_at) IS NOT NULL
                    THEN TIMESTAMPDIFF(SECOND, t.creado_at,
                                       COALESCE(prot.toma_inicio_at, t.fin_lugar_at)) / 60.0
                END
            ), 1
        ) AS tiempo_total_promedio_min
     FROM turnero_turnos t
     -- Un turno tiene a lo sumo un protocolo prolongado, así que el join no duplica
     LEFT JOIN (
        SELECT tc.turno_id, MIN(tc.toma_inicio_at) AS toma_inicio_at
          FROM turnero_consentimientos tc
          JOIN lab_formularios f ON f.id = tc.formulario_id AND f.es_toma_progresiva = 1
         GROUP BY tc.turno_id
     ) prot ON prot.turno_id = t.id
     WHERE t.sesion_id = ?"
);
$stmtRes->execute([$sesionId]);
$resumen = $stmtRes->fetch(PDO::FETCH_ASSOC);

// ── 3. Desglose por prioridad ─────────────────────────────────
$stmtPri = $pdo->prepare(
    "SELECT p.codigo, p.nombre, p.color,
            COUNT(t.id) AS total,
            SUM(t.estado IN ('finalizado','en_servicio')) AS atendidos,
            SUM(t.estado IN ('espera','en_recepcion','en_espera_lugar')) AS pendientes,
            SUM(t.estado = 'ausente') AS ausentes
     FROM   turnero_turnos t
     JOIN   turnero_prioridades p ON p.id = t.prioridad_id
     WHERE  t.sesion_id = ?
     GROUP  BY p.id
     ORDER  BY p.orden_peso ASC"
);
$stmtPri->execute([$sesionId]);
$porPrioridad = $stmtPri->fetchAll(PDO::FETCH_ASSOC);

// ── 4. Desglose por lugar ─────────────────────────────────────
$stmtLug = $pdo->prepare(
    "SELECT l.nombre AS lugar,
            COUNT(t.id) AS total,
            SUM(t.estado IN ('finalizado','en_servicio')) AS atendidos,
            SUM(t.estado IN ('en_espera_lugar')) AS en_espera,
            ROUND(AVG(
                CASE
                    WHEN t.inicio_lugar_at IS NOT NULL
                     AND COALESCE(prot.toma_inicio_at, t.fin_lugar_at) IS NOT NULL
                    THEN TIMESTAMPDIFF(SECOND, t.inicio_lugar_at,
                                       COALESCE(prot.toma_inicio_at, t.fin_lugar_at)) / 60.0
                END
            ), 1) AS tiempo_servicio_promedio_min
     FROM   turnero_turnos t
     JOIN   turnero_lugares l ON l.id = t.lugar_destino_id
     LEFT JOIN (
        SELECT tc.turno_id, MIN(tc.toma_inicio_at) AS toma_inicio_at
          FROM turnero_consentimientos tc
          JOIN lab_formularios f ON f.id = tc.formulario_id AND f.es_toma_progresiva = 1
         GROUP BY tc.turno_id
     ) prot ON prot.turno_id = t.id
     WHERE  t.sesion_id = ?
     GROUP  BY l.id
     ORDER  BY l.sort_order ASC, l.nombre ASC"
);
$stmtLug->execute([$sesionId]);
$porLugar = $stmtLug->fetchAll(PDO::FETCH_ASSOC);

// ── 4b. Desglose por recepcionista ────────────────────────────
//      Mismo molde que el ranking de enfermeras de lab_domicilios
//      (api/lab/get_metricas.php). atendido_recepcion_por guarda al PRIMER
//      recepcionista que tomó el turno (COALESCE en cambiar_estado.php).
$stmtRec = $pdo->prepare(
    "SELECT u.id,
            COALESCE(NULLIF(u.full_name, ''), u.username) AS nombre,
            COUNT(t.id) AS total,
            SUM(t.estado IN ('finalizado','en_servicio','en_espera_lugar')) AS atendidos,
            SUM(t.estado = 'ausente')   AS ausentes,
            SUM(t.estado = 'cancelado') AS cancelados,
            ROUND(AVG(
                CASE
                    WHEN t.fin_recepcion_at IS NOT NULL AND t.inicio_recepcion_at IS NOT NULL
                    THEN TIMESTAMPDIFF(SECOND, t.inicio_recepcion_at, t.fin_recepcion_at) / 60.0
                END
            ), 1) AS tiempo_promedio_min
     FROM   turnero_turnos t
     JOIN   admin_users u ON u.id = t.atendido_recepcion_por
     WHERE  t.sesion_id = ?
     GROUP  BY u.id, u.full_name, u.username
     ORDER  BY atendidos DESC, total DESC"
);
$stmtRec->execute([$sesionId]);
$porRecepcionista = $stmtRec->fetchAll(PDO::FETCH_ASSOC);

// ── 4c. Desglose por bacteriólogo (quien atendió en el lugar) ──
$stmtBac = $pdo->prepare(
    "SELECT u.id,
            COALESCE(NULLIF(u.full_name, ''), u.username) AS nombre,
            COUNT(t.id) AS total,
            SUM(t.estado = 'finalizado')  AS finalizados,
            SUM(t.estado = 'en_servicio') AS en_servicio,
            SUM(t.estado = 'ausente')     AS ausentes,
            ROUND(AVG(
                CASE
                    WHEN t.inicio_lugar_at IS NOT NULL
                     AND COALESCE(prot.toma_inicio_at, t.fin_lugar_at) IS NOT NULL
                    THEN TIMESTAMPDIFF(SECOND, t.inicio_lugar_at,
                                       COALESCE(prot.toma_inicio_at, t.fin_lugar_at)) / 60.0
                END
            ), 1) AS tiempo_promedio_min
     FROM   turnero_turnos t
     JOIN   admin_users u ON u.id = t.atendido_lugar_por
     LEFT JOIN (
        SELECT tc.turno_id, MIN(tc.toma_inicio_at) AS toma_inicio_at
          FROM turnero_consentimientos tc
          JOIN lab_formularios f ON f.id = tc.formulario_id AND f.es_toma_progresiva = 1
         GROUP BY tc.turno_id
     ) prot ON prot.turno_id = t.id
     WHERE  t.sesion_id = ?
     GROUP  BY u.id, u.full_name, u.username
     ORDER  BY finalizados DESC, total DESC"
);
$stmtBac->execute([$sesionId]);
$porBacteriologo = $stmtBac->fetchAll(PDO::FETCH_ASSOC);

// ── 5. Lista de turnos del día ────────────────────────────────
$stmtTurnos = $pdo->prepare(
    "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,
            p.codigo AS prioridad_codigo, p.nombre AS prioridad_nombre, p.color AS prioridad_color,
            l.nombre  AS lugar_nombre,
            s.nombre_completo AS paciente_bd,
            s.numero_documento AS paciente_doc,
            s.tipo_documento   AS paciente_tipo_doc,
            rd.nombre         AS recepcion_desk_nombre,
            ur.full_name      AS atendido_recepcion_nombre,
            ul.full_name      AS atendido_lugar_nombre,
            ts.observaciones  AS notas,
            ROUND(TIMESTAMPDIFF(SECOND, t.creado_at, COALESCE(t.inicio_recepcion_at, NOW())) / 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,
            ROUND(TIMESTAMPDIFF(SECOND, t.creado_at, t.fin_lugar_at) / 60.0, 1) AS total_min
     FROM   turnero_turnos t
     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 ts ON ts.turno_id = t.id
     LEFT   JOIN lab_pacientes s ON s.id = ts.paciente_id
     WHERE  t.sesion_id = ?
     ORDER  BY t.numero ASC"
);
$stmtTurnos->execute([$sesionId]);
$turnos = $stmtTurnos->fetchAll(PDO::FETCH_ASSOC);

// Enriquecer con exámenes y comentarios — en lote.
// Antes eran 2 consultas por turno dentro del foreach (N+1): con 80 turnos en
// el día eran 160 consultas evitables. Mismo patrón que get_historial.php.
$turnoIds            = array_column($turnos, 'id');
$examenesPorTurno    = [];
$comentariosPorTurno = [];

if ($turnoIds) {
    $ph = implode(',', array_fill(0, count($turnoIds), '?'));

    $stmtEx = $pdo->prepare(
        "SELECT DISTINCT ts.turno_id, et.nombre
           FROM turnero_solicitudes ts
           JOIN turnero_examen_items tei ON tei.solicitud_id = ts.id
           JOIN exam_tipos et            ON et.id = tei.exam_tipo_id
          WHERE ts.turno_id IN ($ph)
          ORDER BY et.nombre ASC"
    );
    $stmtEx->execute($turnoIds);
    foreach ($stmtEx->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $examenesPorTurno[(int)$row['turno_id']][] = ['nombre' => $row['nombre']];
    }

    $stmtCom = $pdo->prepare(
        "SELECT turno_id, usuario_nombre, comentario, tipo, creado_at
           FROM turnero_comentarios
          WHERE turno_id IN ($ph)
          ORDER BY turno_id, creado_at ASC"
    );
    $stmtCom->execute($turnoIds);
    foreach ($stmtCom->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $tid = (int)$row['turno_id'];
        unset($row['turno_id']);
        $comentariosPorTurno[$tid][] = $row;
    }
}

foreach ($turnos as &$turno) {
    $tid = (int)$turno['id'];
    $turno['examenes']    = $examenesPorTurno[$tid]    ?? [];
    $turno['comentarios'] = $comentariosPorTurno[$tid] ?? [];
}
unset($turno);

// ── 6. Consentimientos del día ────────────────────────────────
$stmtcons = $pdo->prepare(
    "SELECT tc.estado, COUNT(*) AS cnt
     FROM   turnero_consentimientos tc
     JOIN   turnero_turnos t ON t.id = tc.turno_id
     WHERE  t.sesion_id = ?
     GROUP  BY tc.estado"
);
$stmtcons->execute([$sesionId]);
$consentStats = [];
foreach ($stmtcons->fetchAll(PDO::FETCH_ASSOC) as $r) {
    $consentStats[$r['estado']] = (int)$r['cnt'];
}

jsonOk([
    'fecha'   => $fecha,
    'sesion'  => [
        'id'       => $sesionId,
        'inicio'   => $sesion['inicio_at'] ? date('H:i', strtotime($sesion['inicio_at'])) : null,
        'fin'      => $sesion['fin_at']    ? date('H:i', strtotime($sesion['fin_at']))    : null,
        'abierta'  => $sesion['fin_at'] === null,
    ],
    'resumen'           => $resumen,
    'por_prioridad'     => $porPrioridad,
    'por_lugar'         => $porLugar,
    'por_recepcionista' => $porRecepcionista,
    'por_bacteriologo'  => $porBacteriologo,
    'consent_stats'     => $consentStats,
    'turnos'            => $turnos,
]);
