-- ============================================================
-- Migración 003 – Módulo Turnero (Oleada 1)
-- Sistema de Turnero Inteligente con consentimientos informados
-- FASE 3.1 del plan ERP multi-módulo.
-- Segura para re-ejecutar (IF NOT EXISTS / INSERT IGNORE).
-- ============================================================

-- ── 1. Catálogo maestro de tipos de examen ──────────────────
--      Compartido con Oleada 2 (registro_exams).
--      En Migración 005 se agregan precio_base, requiere_ayunas, instrucciones.
CREATE TABLE IF NOT EXISTS exam_tipos (
    id          INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    codigo      VARCHAR(20)     NOT NULL COMMENT 'Ej: HEM, GLU, URIN',
    nombre      VARCHAR(150)    NOT NULL COMMENT 'Ej: Hemograma completo',
    categoria   VARCHAR(80)     DEFAULT NULL COMMENT 'Ej: Hematología, Química',
    activo      TINYINT(1)      NOT NULL DEFAULT 1,
    creado_at   TIMESTAMP       NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uq_codigo (codigo),
    INDEX idx_activo (activo),
    INDEX idx_categoria (categoria)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Catálogo maestro de tipos de examen del laboratorio';

-- ── 2. Relación M:N examen ↔ consentimiento (formulario) ────
--      Si un examen no tiene registro aquí, no se exige consentimiento.
--      Varios exámenes del mismo turno que apunten al mismo formulario_id
--      generan UN SOLO consentimiento (deduplicado en la lógica PHP).
CREATE TABLE IF NOT EXISTS exam_tipo_consentimientos (
    id              INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    exam_tipo_id    INT UNSIGNED    NOT NULL,
    formulario_id   INT             NOT NULL COMMENT 'FK lab_formularios.id (tipo=consentimiento)',
    PRIMARY KEY (id),
    UNIQUE KEY uq_examen_form (exam_tipo_id, formulario_id),
    INDEX idx_formulario (formulario_id),
    CONSTRAINT fk_etc_exam  FOREIGN KEY (exam_tipo_id)  REFERENCES exam_tipos (id)    ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='M:N entre tipos de examen y formularios de consentimiento';

-- ── 3. Lugares / estaciones de servicio configurables ───────
--      Recepción NO es un lugar; es el paso implícito del flujo.
--      Cada lugar tiene su propia cola y su propia pantalla TV.
CREATE TABLE IF NOT EXISTS turnero_lugares (
    id          INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    nombre      VARCHAR(100)    NOT NULL COMMENT 'Ej: Toma de Muestras 1, Rayos X',
    descripcion TEXT            DEFAULT NULL,
    activo      TINYINT(1)      NOT NULL DEFAULT 1,
    sort_order  INT             NOT NULL DEFAULT 99 COMMENT 'Orden en pantalla TV general',
    creado_at   TIMESTAMP       NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_activo (activo),
    INDEX idx_sort   (sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Estaciones de servicio configurables del turnero';

-- Lugares de ejemplo (ajustar según el laboratorio real)
INSERT IGNORE INTO turnero_lugares (id, nombre, descripcion, activo, sort_order) VALUES
(1, 'Toma de Muestras 1', 'Primera estación de toma de muestras', 1, 1),
(2, 'Toma de Muestras 2', 'Segunda estación de toma de muestras', 1, 2);

-- ── 4. Catálogo de prioridades (códigos A-F) ─────────────────
--      Editable desde el panel admin. orden_peso menor = mayor prioridad.
CREATE TABLE IF NOT EXISTS turnero_prioridades (
    id          INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    codigo      CHAR(1)         NOT NULL COMMENT 'A, B, C, D, E, F',
    nombre      VARCHAR(100)    NOT NULL,
    orden_peso  INT             NOT NULL COMMENT 'Menor número = mayor prioridad',
    color       VARCHAR(7)      NOT NULL DEFAULT '#6b7280' COMMENT 'Hex color para UI',
    activo      TINYINT(1)      NOT NULL DEFAULT 1,
    PRIMARY KEY (id),
    UNIQUE KEY uq_codigo (codigo),
    INDEX idx_orden (orden_peso)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Catálogo configurable de prioridades de atención';

-- Prioridades por defecto A-F
INSERT IGNORE INTO turnero_prioridades (codigo, nombre, orden_peso, color, activo) VALUES
('A', 'Niños',              1, '#ef4444', 1),
('B', 'Embarazadas',        2, '#f97316', 1),
('C', 'Adulto mayor',       3, '#eab308', 1),
('D', 'Discapacidad',       4, '#8b5cf6', 1),
('E', 'Paciente general',   5, '#3b82f6', 1),
('F', 'Muestra pendiente',  6, '#6b7280', 1);

-- ── 5. Sesiones diarias de atención ─────────────────────────
CREATE TABLE IF NOT EXISTS turnero_sesiones (
    id              INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    fecha           DATE            NOT NULL,
    abierto_por     INT             DEFAULT NULL COMMENT 'FK admin_users.id',
    cerrado_por     INT             DEFAULT NULL COMMENT 'FK admin_users.id',
    inicio_at       DATETIME        DEFAULT NULL,
    fin_at          DATETIME        DEFAULT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY uq_fecha (fecha),
    INDEX idx_fecha (fecha)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Sesión de atención del día (una por fecha)';

-- ── 6. Turnos ────────────────────────────────────────────────
--      Motor principal del módulo. Un turno = un paciente en una visita.
CREATE TABLE IF NOT EXISTS turnero_turnos (
    id                      INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    sesion_id               INT UNSIGNED    NOT NULL,
    numero                  INT             NOT NULL COMMENT 'Correlativo dentro de la sesión',
    codigo                  VARCHAR(10)     NOT NULL COMMENT 'Ej: A001, E042',
    prioridad_id            INT UNSIGNED    NOT NULL,
    paciente_nombre         VARCHAR(150)    DEFAULT NULL COMMENT 'Capturado en kiosko (opcional)',
    paciente_cel            VARCHAR(20)     DEFAULT NULL,
    estado                  ENUM(
                                'espera',
                                'en_recepcion',
                                'en_espera_lugar',
                                'en_servicio',
                                'finalizado',
                                'ausente',
                                'cancelado'
                            ) NOT NULL DEFAULT 'espera',
    lugar_destino_id        INT UNSIGNED    DEFAULT NULL COMMENT 'Asignado por recepción',
    -- Timestamps por etapa
    creado_at               DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
    llamado_recepcion_at    DATETIME        DEFAULT NULL,
    inicio_recepcion_at     DATETIME        DEFAULT NULL,
    fin_recepcion_at        DATETIME        DEFAULT NULL,
    llamado_lugar_at        DATETIME        DEFAULT NULL,
    inicio_lugar_at         DATETIME        DEFAULT NULL,
    fin_lugar_at            DATETIME        DEFAULT NULL,
    -- Responsable de atención
    atendido_recepcion_por  INT             DEFAULT NULL COMMENT 'FK admin_users.id',
    atendido_lugar_por      INT             DEFAULT NULL COMMENT 'FK admin_users.id',
    PRIMARY KEY (id),
    UNIQUE KEY uq_sesion_numero  (sesion_id, numero),
    INDEX idx_sesion_estado      (sesion_id, estado),
    INDEX idx_lugar_estado       (lugar_destino_id, estado),
    INDEX idx_prioridad          (prioridad_id),
    INDEX idx_creado             (creado_at),
    CONSTRAINT fk_tt_sesion     FOREIGN KEY (sesion_id)        REFERENCES turnero_sesiones    (id) ON DELETE RESTRICT ON UPDATE CASCADE,
    CONSTRAINT fk_tt_prioridad  FOREIGN KEY (prioridad_id)     REFERENCES turnero_prioridades (id) ON DELETE RESTRICT ON UPDATE CASCADE,
    CONSTRAINT fk_tt_lugar      FOREIGN KEY (lugar_destino_id) REFERENCES turnero_lugares      (id) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Turnos del sistema de atención';

-- ── 7. Solicitud interna (crea recepción) ────────────────────
--      Registra paciente, exámenes, pago y lugar destino.
--      Una solicitud por turno (UNIQUE turno_id).
CREATE TABLE IF NOT EXISTS turnero_solicitudes (
    id              INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    turno_id        INT UNSIGNED    NOT NULL,
    paciente_id     INT             NOT NULL COMMENT 'FK lab_pacientes.id',
    lugar_id        INT UNSIGNED    NOT NULL COMMENT 'FK turnero_lugares.id',
    total_cobrado   DECIMAL(10,2)   DEFAULT NULL,
    metodo_pago     ENUM(
                        'efectivo',
                        'transferencia',
                        'tarjeta',
                        'eps',
                        'cortesia'
                    ) DEFAULT NULL,
    observaciones   TEXT            DEFAULT NULL,
    creado_por      INT             NOT NULL COMMENT 'FK admin_users.id',
    creado_at       DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uq_turno (turno_id),
    INDEX idx_paciente   (paciente_id),
    INDEX idx_lugar      (lugar_id),
    INDEX idx_creado     (creado_at),
    CONSTRAINT fk_ts_turno  FOREIGN KEY (turno_id) REFERENCES turnero_turnos   (id) ON DELETE CASCADE  ON UPDATE CASCADE,
    CONSTRAINT fk_ts_lugar  FOREIGN KEY (lugar_id) REFERENCES turnero_lugares   (id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Solicitud interna de agendamiento creada en recepción';

-- ── 8. Exámenes de la solicitud ──────────────────────────────
CREATE TABLE IF NOT EXISTS turnero_examen_items (
    id              INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    solicitud_id    INT UNSIGNED    NOT NULL,
    exam_tipo_id    INT UNSIGNED    NOT NULL,
    creado_at       DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_solicitud  (solicitud_id),
    INDEX idx_exam_tipo  (exam_tipo_id),
    CONSTRAINT fk_tei_solicitud FOREIGN KEY (solicitud_id) REFERENCES turnero_solicitudes (id) ON DELETE CASCADE  ON UPDATE CASCADE,
    CONSTRAINT fk_tei_exam      FOREIGN KEY (exam_tipo_id) REFERENCES exam_tipos           (id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Exámenes individuales de cada solicitud de turno';

-- ── 9. Consentimientos por turno (deduplicados) ──────────────
--      Un registro por formulario distinto requerido en el turno.
--      token = enlace único de firma (UUID).
CREATE TABLE IF NOT EXISTS turnero_consentimientos (
    id                  INT UNSIGNED    NOT NULL AUTO_INCREMENT,
    turno_id            INT UNSIGNED    NOT NULL,
    formulario_id       INT             NOT NULL COMMENT 'FK lab_formularios.id',
    token               VARCHAR(64)     NOT NULL COMMENT 'UUID único para enlace de firma',
    estado              ENUM(
                            'pendiente',
                            'enviado',
                            'visto',
                            'firmado',
                            'rechazado'
                        ) NOT NULL DEFAULT 'pendiente',
    enviado_at          DATETIME        DEFAULT NULL,
    firmado_at          DATETIME        DEFAULT NULL,
    ip_firma            VARCHAR(45)     DEFAULT NULL COMMENT 'IPv4 o IPv6 del firmante',
    ua_firma            VARCHAR(500)    DEFAULT NULL COMMENT 'User-Agent del dispositivo',
    version_formulario  INT             DEFAULT NULL COMMENT 'Snapshot de versión al firmar',
    PRIMARY KEY (id),
    UNIQUE KEY uq_token     (token),
    UNIQUE KEY uq_turno_form (turno_id, formulario_id),
    INDEX idx_turno         (turno_id),
    INDEX idx_estado        (estado),
    CONSTRAINT fk_tc_turno FOREIGN KEY (turno_id) REFERENCES turnero_turnos (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Consentimientos informados vinculados a un turno (uno por formulario distinto)';

-- ── 10. Columna tipo en lab_formularios ──────────────────────
--       Permite marcar un formulario como consentimiento informado.
ALTER TABLE lab_formularios
    ADD COLUMN IF NOT EXISTS tipo
        ENUM('formulario', 'consentimiento') NOT NULL DEFAULT 'formulario'
        COMMENT 'Tipo de formulario: genérico o consentimiento informado';

-- Índice para filtrar rápido en las consultas del turnero
ALTER TABLE lab_formularios
    ADD INDEX IF NOT EXISTS idx_tipo (tipo);

-- ── 11. Asignar módulo turnero a roles ───────────────────────
--       Activar en system_modules si estaba inactivo
UPDATE system_modules
    SET is_active = 1
    WHERE slug = 'turnero';

-- Permisos del recepcionista sobre el módulo turnero
INSERT IGNORE INTO role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
SELECT r.id, 'turnero', 1, 1, 1, 0, 0
FROM roles r WHERE r.slug = 'recepcionista';

-- Permisos del bacteriólogo sobre el módulo turnero (solo lectura + edición de servicio)
INSERT IGNORE INTO role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
SELECT r.id, 'turnero', 1, 0, 1, 0, 0
FROM roles r WHERE r.slug = 'bacteriologo';

-- ── 12. Datos de ejemplo de tipos de examen ──────────────────
--       Solo si la tabla está vacía (evita duplicar en re-ejecución)
INSERT IGNORE INTO exam_tipos (codigo, nombre, categoria) VALUES
('HEM',   'Hemograma completo',          'Hematología'),
('GLU',   'Glucosa en ayunas',            'Química'),
('URIN',  'Uroanálisis completo',         'Urología'),
('UROCUL','Urocultivo',                   'Microbiología'),
('COLEST','Perfil lipídico (colesterol)', 'Química'),
('TSH',   'TSH (Función tiroidea)',       'Endocrinología'),
('HIV',   'Prueba VIH',                   'Serología'),
('HEPB',  'Hepatitis B (HBsAg)',          'Serología'),
('RXP',   'Rayos X de pecho',             'Radiología'),
('ECG',   'Electrocardiograma',           'Cardiología');

-- ── 13. Columna firma_svg en turnero_consentimientos ─────────
--       Almacena el dibujo de firma del paciente (data URL PNG).
--       MEDIUMTEXT soporta firmas de alta resolución (hasta 16 MB).
ALTER TABLE turnero_consentimientos
    ADD COLUMN IF NOT EXISTS firma_svg MEDIUMTEXT DEFAULT NULL
    COMMENT 'Dibujo de firma del paciente (data URL PNG base64)';
