<?php
// ============================================================
//  lib/parse_intervencion.php
//
//  Auditoría de CUMPLIMIENTO DE FRECUENCIA DE INTERVENCIONES
//  según el contrato de la EPS del paciente.
//
//  Independiente de lib/parser.php (que audita turno/fecha/hora
//  de cada nota individual). Aquí lo que importa es identificar
//  QUÉ actividad es cada nota (su título) para luego cruzarla
//  contra el catálogo de terapias contratadas y su frecuencia
//  esperada.
// ============================================================

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

class ParserIntervencion {

    /**
     * Punto de entrada: recibe el texto completo extraído del PDF
     * (mismo texto que ya extrae PDF.js en el cliente) y devuelve
     * la lista de notas con su título identificado.
     */
    public static function parsearTexto(string $texto): array {
        if (strlen(trim($texto)) < 50) {
            throw new RuntimeException('Texto insuficiente para analizar.');
        }

        $bloques = self::dividirBloques($texto);

        $notas = [];
        foreach ($bloques as $bloque) {
            $nota = self::parsearBloque($bloque);
            if (!$nota) continue;
            $notas[] = $nota;
        }

        if (empty($notas)) {
            throw new RuntimeException(
                'No se encontraron notas de enfermería en el PDF. ' .
                'Verifique que sea un archivo R-FAST válido.'
            );
        }

        return [
            'total' => count($notas),
            'notas' => $notas,
        ];
    }

    /**
     * Divide el texto en bloques cortando ANTES del encabezado en
     * negrita de cada nota (ej. "**TERAPIA FISICA: 21 Años"), para
     * que el título quede DENTRO del mismo bloque que su Id y sus
     * fechas. Esto es distinto a parser.php, que corta antes de
     * "Id:" y por eso pierde el título en el bloque anterior.
     */
    private static function dividirBloques(string $texto): array {
        $partes = preg_split(
            '/(?=\*{1,2}\s*[A-ZÁÉÍÓÚÑ0-9][A-ZÁÉÍÓÚÑ0-9\s\.\(\)\/,:-]*?:\s*\d+\s*A[ñn]os)/u',
            $texto
        );

        if (count($partes) > 1) {
            $r = array_values(array_filter($partes, fn($p) => strlen(trim($p)) > 20));
            if (!empty($r)) return $r;
        }

        // Fallback: si no se detectaron encabezados en negrita, se
        // corta por "Id:" como en parser.php (el título quedará null
        // para esos casos, pero al menos no se pierde la nota).
        $partes = preg_split('/(?=\bId:\s{1,6}\d{5,9}\b)/iu', $texto);
        if (count($partes) > 1) {
            array_shift($partes);
            return array_values(array_filter($partes, fn($p) => strlen(trim($p)) > 20));
        }

        return [];
    }

    private static function parsearBloque(string $bloque): ?array {

        if (!preg_match('/\bId:\s{1,6}(\d{5,9})\b/iu', $bloque, $m_id)) return null;

        // Título de la nota: texto entre '**' y ': N Años'
        $titulo = null;
        if (preg_match('/\*{1,2}\s*(.+?):\s*\d+\s*A[ñn]os/isu', $bloque, $m_tit)) {
            $titulo = trim(preg_replace('/\s+/u', ' ', $m_tit[1]));
        }

        if (!preg_match(
            '/Fecha\s+de\s+grabaci[oó]n\s*:\s*(\d{1,2}-\w{3,4}-\d{4})\s+(\d{1,2}:\d{2})\s*(am|pm)/iu',
            $bloque, $m_grab
        )) return null;

        $fecha_grab = self::normalizarFecha($m_grab[1]);
        $ampm_grab  = strtolower($m_grab[3]);
        $hora_grab  = self::horaA24h($m_grab[2], $ampm_grab);

        $fecha_aten = null; $hora_aten = null; $ampm_aten = null;
        if (preg_match(
            '/Fecha\s+y\s+Hora\s+de\s+Atencion\s*:+\s*(\d{1,2}-\w{3,4}-\d{4})\s+(\d{1,2}:\d{2})\s*(am|pm)/iu',
            $bloque, $m_aten
        )) {
            $fecha_aten = self::normalizarFecha($m_aten[1]);
            $ampm_aten  = strtolower($m_aten[3]);
            $hora_aten  = self::horaA24h($m_aten[2], $ampm_aten);
        }

        $profesional = 'No especificado';
        if (preg_match(
            '/PROFESIONAL\s*:\s*\[\d+\]\s*([\wÁÉÍÓÚáéíóúÑñ\s\.]+?)\s*-\s*Identificaci[oó]n/isu',
            $bloque, $m_prof
        )) {
            $profesional = trim($m_prof[1]);
        }

        // Especialidad del profesional: aparece tras "Registro: X - Especialidad: Y"
        // (a veces sin "Registro:", directo "Identificación: CC N - Especialidad: Y").
        // Se usa como desempate para actividades cuyo título no distingue
        // el profesional (ej. "PSICOTERAPIA DE PAREJA" puede ser por
        // psiquiatría o por psicología según el contrato).
        $especialidad = null;
        if (preg_match('/Especialidad\s*:\s*([A-ZÁÉÍÓÚÑ\s]+?)\s*(?:\r?\n|\[)/isu', $bloque, $m_esp)) {
            $especialidad = trim($m_esp[1]);
        }

        return [
            'id_nota'      => $m_id[1],
            'titulo_nota'  => $titulo,      // clave para el mapeo contra actividades_rfast
            'profesional'  => $profesional,
            'especialidad' => $especialidad,
            'fecha_grab'   => $fecha_grab,
            'hora_grab'    => $hora_grab,
            'ampm_grab'    => $ampm_grab,
            'fecha_aten'   => $fecha_aten,
            'hora_aten'    => $hora_aten,
            'ampm_aten'    => $ampm_aten,
        ];
    }

    private static function normalizarFecha(string $f): string {
        static $meses = [
            'ene'=>'01','feb'=>'02','mar'=>'03','abr'=>'04',
            'may'=>'05','jun'=>'06','jul'=>'07','ago'=>'08',
            'sep'=>'09','oct'=>'10','nov'=>'11','dic'=>'12',
        ];
        if (preg_match('/(\d{1,2})-(\w{3,4})-(\d{4})/u', $f, $m)) {
            $mes = $meses[strtolower(substr($m[2], 0, 3))] ?? '00';
            return sprintf('%s-%s-%02d', $m[3], $mes, (int)$m[1]);
        }
        return $f;
    }

    // Convierte "08:31" + "am"/"pm" a "08:31:00" formato MySQL TIME
    private static function horaA24h(string $hora, string $ampm): string {
        [$h, $m] = explode(':', $hora);
        $h = (int)$h;
        $m = (int)$m;
        if ($ampm === 'pm' && $h !== 12) $h += 12;
        if ($ampm === 'am' && $h === 12) $h = 0;
        return sprintf('%02d:%02d:00', $h, $m);
    }
}
