<?php
/**
 * ETL: Firebird staging → MySQL producción
 *
 * PASO PREVIO (una sola vez):
 *   php scripts/etl_examenes.php --load   # carga staging y ejecuta ETL
 *   php scripts/etl_examenes.php          # solo ETL (staging ya cargado)
 *   php scripts/etl_examenes.php --clean  # elimina tablas staging
 */

require_once __DIR__ . '/../config/config.php';

$pdo = Database::getInstance()->getConnection();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// MariaDB defaultea utf8mb4 a uca1400_ai_ci; forzamos unicode_ci para que
// los literales de string en queries no colisionen con columnas de producción
$pdo->exec("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");

$doLoad  = in_array('--load',  $argv);
$doClean = in_array('--clean', $argv);

// ── helpers ──────────────────────────────────────────────────
function run(PDO $pdo, string $sql, string $label): void {
    $t = microtime(true);
    $rows = $pdo->exec($sql);
    printf("  %-45s %6d filas  %.2fs\n", $label, $rows, microtime(true) - $t);
}

function step(string $msg): void {
    echo "\n── $msg\n";
}

// ── limpiar staging si se pide ────────────────────────────────
if ($doClean) {
    $staging = ['SECCION','PROTOCOLO','MUESTRA','EXAMEN','ITEM',
                'PERFIL','PERFIL_EXA','TARIFAID','TARIFA','LAB_REFER',
                'stg_empresa','stg_examen_emp'];
    $pdo->exec('SET FOREIGN_KEY_CHECKS=0');
    foreach ($staging as $t) {
        $pdo->exec("DROP TABLE IF EXISTS `$t`");
        echo "  DROP $t\n";
    }
    $pdo->exec('SET FOREIGN_KEY_CHECKS=1');
    echo "Staging eliminado.\n";
    exit(0);
}

// ── cargar staging desde examenes_completo.sql ────────────────
if ($doLoad) {
    $sqlFile = realpath(__DIR__ . '/../database/examenes_completo.sql');
    if (!$sqlFile) { echo "ERROR: No se encuentra examenes_completo.sql\n"; exit(1); }

    $tmpFile = sys_get_temp_dir() . '/examenes_staging_' . getmypid() . '.sql';
    echo "Preparando staging SQL...\n";

    $sql = file_get_contents($sqlFile);
    $sql = preg_replace('/\blab_examenes_empresa\b/', 'stg_examen_emp', $sql);
    $sql = preg_replace('/\blab_empresas\b/',         'stg_empresa',    $sql);
    $sql = preg_replace('/\bINSERT INTO\b/',          'INSERT IGNORE INTO', $sql);
    file_put_contents($tmpFile, $sql);
    unset($sql);

    $host = DB_HOST; $port = DB_PORT; $user = DB_USER; $pass = DB_PASS; $db = DB_NAME;
    echo "Cargando staging vía mysql CLI (puede tardar 2-3 min)...\n";
    $cmd = "mysql -h " . escapeshellarg($host)
         . " -P " . escapeshellarg($port)
         . " -u " . escapeshellarg($user)
         . " -p" . escapeshellarg($pass)
         . " --default-character-set=utf8mb4"
         . " " . escapeshellarg($db)
         . " < " . escapeshellarg($tmpFile)
         . " 2>&1";
    passthru($cmd, $ret);
    unlink($tmpFile);
    if ($ret !== 0) { echo "ERROR cargando staging.\n"; exit(1); }
    echo "Staging cargado.\n";
}

// ── verificar staging ─────────────────────────────────────────
try {
    $pdo->query("SELECT 1 FROM EXAMEN LIMIT 1");
} catch (\Throwable $e) {
    echo "ERROR: Tablas staging no encontradas. Ejecuta: php etl_examenes.php --load\n";
    exit(1);
}

echo "ETL Firebird → MySQL\n";
echo str_repeat('─', 60) . "\n";

// convertir staging a misma collation que producción (MariaDB usa uca1400 por defecto)
$pdo->exec('SET FOREIGN_KEY_CHECKS = 0');
foreach (['SECCION','PROTOCOLO','MUESTRA','EXAMEN','ITEM',
          'PERFIL','PERFIL_EXA','TARIFAID','TARIFA','LAB_REFER',
          'stg_empresa','stg_examen_emp'] as $_t) {
    try {
        $pdo->exec("ALTER TABLE `$_t` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
    } catch (\Throwable $_e) { /* tabla no existe aún, ok */ }
}
$pdo->exec('SET UNIQUE_CHECKS = 0');

// ── 1. SECCION → lab_secciones ───────────────────────────────
step('1. SECCION → lab_secciones');
run($pdo, "
    INSERT IGNORE INTO lab_secciones (codigo, nombre)
    SELECT CODIGO, NOMBRE FROM SECCION
", 'lab_secciones');

// ── 2. PROTOCOLO → lab_protocolos ────────────────────────────
step('2. PROTOCOLO → lab_protocolos');
run($pdo, "
    INSERT IGNORE INTO lab_protocolos (codigo, nombre, cod_seccion)
    SELECT CODIGO, NOMBRE, COD_SECCION FROM PROTOCOLO
", 'lab_protocolos');

// ── 3. MUESTRA → lab_tipos_muestra ───────────────────────────
step('3. MUESTRA → lab_tipos_muestra');
run($pdo, "
    INSERT IGNORE INTO lab_tipos_muestra (codigo, nombre)
    SELECT CODIGO, NOMBRE FROM MUESTRA
", 'lab_tipos_muestra');

// ── 4. EXAMEN → exam_tipos ───────────────────────────────────
step('4. EXAMEN → exam_tipos');
// codigo = EXAMEN.CODIGO (unique en Firebird, usamos como código interno también)
// categoria = nombre de la sección del protocolo
run($pdo, "
    INSERT IGNORE INTO exam_tipos
        (codigo, nombre, categoria, activo,
         codigo_legacy, cups, cod_protocolo, tipo_muestra,
         nivel, abreviatura, seremite, serecibe)
    SELECT
        e.CODIGO,
        e.NOMBRE,
        s.NOMBRE,
        1,
        e.CODIGO,
        NULLIF(e.CUPS, ''),
        NULLIF(e.COD_PROTOCOLO, ''),
        NULLIF(e.TIPOMUESTRA, ''),
        e.NIVEL,
        NULLIF(e.ABREVIATURA, ''),
        IF(e.SEREMITE = 'T', 1, 0),
        NULLIF(e.SERECIBE, '')
    FROM EXAMEN e
    LEFT JOIN PROTOCOLO p ON p.CODIGO = e.COD_PROTOCOLO
    LEFT JOIN SECCION   s ON s.CODIGO = p.COD_SECCION
", 'exam_tipos');

// ── 5. ITEM → lab_items_resultado ────────────────────────────
step('5. ITEM → lab_items_resultado');
// ponytail: truncate antes de insertar — ITEM no tiene UK en MySQL
$pdo->exec('DELETE FROM lab_items_resultado');
run($pdo, "
    INSERT INTO lab_items_resultado
        (cod_protocolo, nombre, tipo_sexo, tipo,
         medida, abreviatura, vmin_ref, vmax_ref,
         orden, formula, cups_detalle)
    SELECT
        i.COD_PROTOCOLO,
        i.NOM_ITEM,
        CASE i.TIPO_SEXO WHEN 'M' THEN 'M' WHEN 'F' THEN 'F' ELSE NULL END,
        CASE WHEN i.TIPO = '2' THEN 'N' ELSE 'T' END,
        NULLIF(i.MEDIDA, ''),
        NULLIF(i.ABREVIATURA, ''),
        NULLIF(i.VMINREF, 0),
        NULLIF(i.VMAXREF, 0),
        COALESCE(i.ORDEN, 0),
        NULLIF(i.FORMULA, ''),
        NULLIF(i.CUPS_DETALLE, '')
    FROM ITEM i
    WHERE EXISTS (SELECT 1 FROM lab_protocolos p WHERE p.codigo = i.COD_PROTOCOLO)
", 'lab_items_resultado');

// ── 6. PERFIL → lab_perfiles ─────────────────────────────────
step('6. PERFIL → lab_perfiles');
run($pdo, "
    INSERT IGNORE INTO lab_perfiles (id, nombre, activo)
    SELECT COD_PERFIL, NOM_PERFIL, 1 FROM PERFIL
", 'lab_perfiles');

// ── 7. PERFIL_EXA → lab_perfil_examenes ──────────────────────
step('7. PERFIL_EXA → lab_perfil_examenes');
run($pdo, "
    INSERT IGNORE INTO lab_perfil_examenes (perfil_id, exam_tipo_id)
    SELECT pe.COD_PERFIL, et.id
    FROM PERFIL_EXA pe
    JOIN exam_tipos et ON et.codigo_legacy = pe.COD_EXA
", 'lab_perfil_examenes');

// ── 8. TARIFAID → lab_tarifas_id ─────────────────────────────
step('8. TARIFAID → lab_tarifas_id');
run($pdo, "
    INSERT IGNORE INTO lab_tarifas_id (id, nombre, tarifa_origen, porcentaje)
    SELECT
        COD_TARIFA,
        NOMBRE,
        NULLIF(TARIFAORIGEN, 0),
        PORCENTAJE
    FROM TARIFAID
", 'lab_tarifas_id');

// ── 9. TARIFA → lab_tarifas (104 788 filas) ──────────────────
step('9. TARIFA → lab_tarifas  [puede tardar ~30s]');
run($pdo, "
    INSERT IGNORE INTO lab_tarifas
        (cod_examen_legacy, exam_tipo_id, tarifa_id,
         valor, recargo_urg, recargo_fes, recargo_esp)
    SELECT
        t.COD_EXAMEN,
        et.id,
        t.TARIFA,
        COALESCE(t.VALOR, 0),
        COALESCE(t.RECARGO_URG, 0),
        COALESCE(t.RECARGO_FES, 0),
        COALESCE(t.RECARGO_ESP, 0)
    FROM TARIFA t
    LEFT JOIN exam_tipos et ON et.codigo_legacy = t.COD_EXAMEN
", 'lab_tarifas');

// ── 10. LAB_REFER → lab_laboratorios_externos ────────────────
step('10. LAB_REFER → lab_laboratorios_externos');
$pdo->exec("
    CREATE TABLE IF NOT EXISTS lab_laboratorios_externos (
        codigo      VARCHAR(20)  NOT NULL,
        nombre      VARCHAR(100),
        nit_lab     VARCHAR(30),
        direccion   VARCHAR(200),
        telefonos   VARCHAR(50),
        email       VARCHAR(100),
        activo      TINYINT(1)   NOT NULL DEFAULT 1,
        PRIMARY KEY (codigo)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
      COMMENT='Laboratorios externos de referencia — replica LAB_REFER Firebird'
");
run($pdo, "
    INSERT IGNORE INTO lab_laboratorios_externos
        (codigo, nombre, nit_lab, direccion, telefonos, email, activo)
    SELECT
        CODIGO, NOMBRE, NIT_LAB, DIRECCION, TELEFONOS, EMAIL,
        IF(ACTIVADO = 'T', 1, 0)
    FROM LAB_REFER
", 'lab_laboratorios_externos');

// ── 11. EMPRESA (staging) → lab_empresas ─────────────────────
step('11. EMPRESA → lab_empresas');
// ponytail: staging usa columnas Firebird, producción tiene columnas en snake_case
run($pdo, "
    INSERT IGNORE INTO lab_empresas
        (nit, nombre, razon_social, tarifa_id, descuento_pct,
         codigo_eps, tipo_usuario, tipo_usuario_sispro,
         cod_contrato, cod_tercero, centro_costo,
         req_autoriza, activa)
    SELECT
        NIT,
        NOMBRE,
        NULLIF(RAZONSOCIAL, ''),
        NULLIF(TARIFA, 0),
        COALESCE(DSCTO, 0),
        NULLIF(CODIGOEPS, ''),
        NULLIF(TIPOUSUARIO, ''),
        NULLIF(TIPOUSUARIOSISPRO, ''),
        NULLIF(CODCONTRATO, ''),
        NULLIF(CODTERCERO, ''),
        NULLIF(CENTROCOSTO, ''),
        IF(REQAUTORIZA = 'T', 1, 0),
        IF(ACTIVADA    = 'T', 1, 0)
    FROM stg_empresa
", 'lab_empresas');

// ── 12. EXAMEN_EMP (staging) → lab_examenes_empresa ──────────
step('12. EXAMEN_EMP → lab_examenes_empresa');
run($pdo, "
    INSERT IGNORE INTO lab_examenes_empresa
        (nit_empresa, cod_examen_legacy, exam_tipo_id, codigo_empresa)
    SELECT
        ee.NIT_EMP,
        ee.COD_EXA,
        et.id,
        NULLIF(ee.EXA_EMP, '')
    FROM stg_examen_emp ee
    LEFT JOIN exam_tipos et ON et.codigo_legacy = ee.COD_EXA
", 'lab_examenes_empresa');

// ── fin ───────────────────────────────────────────────────────
$pdo->exec('SET FOREIGN_KEY_CHECKS = 1');
$pdo->exec('SET UNIQUE_CHECKS = 1');

echo "\n" . str_repeat('─', 60) . "\n";
echo "ETL completado.\n\n";

// resumen rápido
$tablas = [
    'lab_secciones', 'lab_protocolos', 'lab_tipos_muestra', 'exam_tipos',
    'lab_items_resultado', 'lab_perfiles', 'lab_perfil_examenes',
    'lab_tarifas_id', 'lab_tarifas', 'lab_laboratorios_externos',
    'lab_empresas', 'lab_examenes_empresa',
];
echo "Totales en producción:\n";
foreach ($tablas as $t) {
    $n = $pdo->query("SELECT COUNT(*) FROM `$t`")->fetchColumn();
    printf("  %-35s %7d\n", $t, $n);
}
echo "\nListo.\n";
