<?php 

require_once "conexion.php";

class ModeloConsulta{

        static public function mdlMostrarListaEspera($tabla,$idAreaUsuario){

            $stmt = Conexion::conectar()->prepare("
                SELECT 
                    p.nombres, p.apellidos, p.codigo_hc,
                    i.id_ingreso, i.motivo_consulta,
                    t.id_triaje, t.nivel_prioridad, t.id_area,
                    s.saturacion_oxigeno, s.presion_arterial, s.temperatura,
                    a.nombre_area
                FROM $tabla t
                INNER JOIN ingresoemergencia i ON t.id_ingreso = i.id_ingreso
                INNER JOIN paciente p ON i.id_paciente = p.id_paciente
                INNER JOIN signosvitales s ON t.id_triaje = s.id_triaje
                INNER JOIN areas a ON t.id_area = a.id
                WHERE i.estado = 'activo' 
                /* LÓGICA PARA ADMINISTRADOR (ID 0) O FILTRO POR ÁREA */
                AND (:idArea1 = 0 OR t.id_area = :idArea2)
                AND i.id_ingreso NOT IN (SELECT id_ingreso FROM consultamedica WHERE estado = 1)
                ORDER BY 
                    CASE 
                        WHEN t.nivel_prioridad = 'I' THEN 1
                        WHEN t.nivel_prioridad = 'II' THEN 2
                        WHEN t.nivel_prioridad = 'III' THEN 3
                        WHEN t.nivel_prioridad = 'IV' THEN 4
                        ELSE 5
                    END ASC, 
                    i.fecha_ingreso ASC
            ");

            $stmt->bindParam(":idArea1", $idAreaUsuario, PDO::PARAM_INT);
            $stmt->bindParam(":idArea2", $idAreaUsuario, PDO::PARAM_INT);

            $stmt->execute();
            return $stmt->fetchAll();

            $stmt->close();
            $stmt = null;
        }

        static public function mdlMostrarPacienteConsulta($tabla, $item, $valor) {
            // $tabla es "triaje"
            $stmt = Conexion::conectar()->prepare("
                SELECT 
                    p.id_paciente, p.nombres, p.apellidos, p.codigo_hc,
                    i.id_ingreso, i.motivo_consulta, i.tipo_seguro,
                    t.id_triaje, t.nivel_prioridad,
                    s.presion_arterial, s.temperatura, s.saturacion_oxigeno, s.pulso, s.frecuencia_respiratoria
                FROM $tabla t
                INNER JOIN ingresoemergencia i ON t.id_ingreso = i.id_ingreso
                INNER JOIN paciente p ON i.id_paciente = p.id_paciente
                INNER JOIN signosvitales s ON t.id_triaje = s.id_triaje
                WHERE t.$item = :$item
            ");

            $stmt->bindParam(":".$item, $valor, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetch(); // fetch() porque es un solo paciente
        }

       static public function mdlRegistroMedicoCompleto($datos) {
                $db = Conexion::conectar();
                
                // Iniciamos transacción para asegurar que se graben las 4 tablas o ninguna
                $db->beginTransaction();

                try {
                    // 1. INSERTAR CABECERA DE CONSULTA
                    $stmt = $db->prepare("INSERT INTO consultamedica(id_ingreso, id_medico, anamnesis, examen_fisico, antecedentes, funciones_biologicas) 
                                        VALUES (:id_ingreso, :id_medico, :anamnesis, :examen_fisico, :antecedentes, :funciones_biologicas)");
                    $stmt->execute([
                        ":id_ingreso"    => $datos["id_ingreso"],
                        ":id_medico"     => $datos["id_medico"],
                        ":anamnesis"     => $datos["anamnesis"],
                        ":examen_fisico" => $datos["examen_fisico"],
                        ":antecedentes"     => $datos["antecedentes"],
                        ":funciones_biologicas" => $datos["funciones_biologicas"]

                    ]);
                    $idConsulta = $db->lastInsertId();

                    // 2. INSERTAR DIAGNÓSTICO (RF09)
                    $stmt = $db->prepare("INSERT INTO diagnostico(id_consulta, codigo_cie10, id_usuario) 
                                        VALUES (:id_c, :codigo, :id_u)");
                   foreach ($datos["cie10"] as $codigo) {
                    if (!empty(trim($codigo))) {
                    $stmt->execute([
                        ":id_c"   => $idConsulta,
                        ":codigo" => $codigo, // Se guarda el texto del input
                        ":id_u"   => $datos["id_medico"]
                    ]);
                }

                    $idDiag = $db->lastInsertId();

                    if(!isset($idDiagPrincipal)) { $idDiagPrincipal = $idDiag; }

                    }

                    // 3. INSERTAR TRATAMIENTO (RF09)
                    $stmt = $db->prepare("INSERT INTO tratamiento(id_diagnostico, medicamentos, procedimientos, indicaciones, id_medico) 
                      VALUES (:id_d, :meds, :proc, :ind, :id_u)");

                    $stmt->execute([
                        ":id_d"    => $idDiag,
                        ":meds"    => $datos["tratamiento"],
                        ":proc"    => $datos["procedimientos"], // <--- NUEVO
                        ":ind"     => $datos["indicaciones"],  // <--- NUEVO
                        ":id_u"    => $datos["id_medico"]
                    ]);

                    // 4. LÓGICA DE ESTADOS (RF10)
                    $estadoDB = "";
                    $fechaCierre = null;

                    if($datos["destino"] == "alta" || $datos["destino"] == "deceso") {
                        $estadoDB = $datos["destino"]; // 'alta' o 'deceso'
                        $fechaCierre = date("Y-m-d H:i:s");
                    } else {
                        // 'transferencia_piso' o 'transferencia_UCI'
                        $estadoDB = "observacion"; 
                        $fechaCierre = null; 
                    }

                    // 5. ACTUALIZAR TABLA INGRESOEMERGENCIA
                    $stmt = $db->prepare("UPDATE ingresoemergencia SET 
                        estado = :estado, 
                        destino_final = :destino, 
                        fecha_cierre = :fecha_c,
                        id_usuario_cierre = :id_u
                        WHERE id_ingreso = :id_ingreso");

                    $stmt->execute([
                        ":estado"     => $estadoDB,
                        ":destino"    => $datos["destino"],
                        ":fecha_c"    => $fechaCierre,
                        ":id_u"       => $datos["id_medico"],
                        ":id_ingreso" => $datos["id_ingreso"]
                    ]);

                    // 6. NOTA DE EVOLUCIÓN INICIAL (RF09)
                    $stmt = $db->prepare("INSERT INTO evolucionmedica(id_consulta, nota_evolucion, id_usuario) 
                                        VALUES (:id_c, :nota, :id_u)");
                    $stmt->execute([
                        ":id_c"    => $idConsulta,
                        ":nota"    => "Atención inicial finalizada. Paciente en espera de: " . $datos["destino"],
                        ":id_u"    => $datos["id_medico"]
                    ]);

                    $db->commit();
                    return "ok";

                } catch (Exception $e) {
                    $db->rollBack();
                    return "Error: " . $e->getMessage();
                }
            }

        static public function mdlMostrarHistorialPaciente($idPaciente) {
            $stmt = Conexion::conectar()->prepare("
                SELECT 
                    DATE_FORMAT(c.fecha_consulta, '%d/%m/%Y') as fecha_consulta,
                    DATE_FORMAT(c.fecha_consulta, '%H:%i') as hora,
                    c.anamnesis,
                    d.codigo_cie10,
                    t.medicamentos,
                    i.destino_final,
                    e.nombre as medico,
                    -- Agrupamos los documentos en un string con un separador especial (||)
                    (SELECT GROUP_CONCAT(CONCAT(d.tipo_documento, ':', d.ruta_archivo) SEPARATOR '||') 
                    FROM documento d 
                    WHERE d.id_ingreso = c.id_ingreso) as adjuntos_raw
                FROM consultamedica c
                INNER JOIN ingresoemergencia i ON c.id_ingreso = i.id_ingreso
                LEFT JOIN diagnostico d ON c.id_consulta = d.id_consulta
                LEFT JOIN tratamiento t ON d.id_diagnostico = t.id_diagnostico
                LEFT JOIN usuario u ON c.id_medico = u.id_usuario
                LEFT JOIN empleado e ON u.id_empleado = e.id_empleado
                WHERE i.id_paciente = :id_paciente
                ORDER BY c.fecha_consulta DESC
            ");

            $stmt->bindParam(":id_paciente", $idPaciente, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll();
        }

        static public function mdlMostrarPacientesPorEstado($estado) {
            // Agregamos TIMESTAMPDIFF para obtener las horas reales
            $stmt = Conexion::conectar()->prepare("SELECT i.*, p.nombres, p.apellidos, p.codigo_hc,
                TIMESTAMPDIFF(HOUR, i.fecha_ingreso, NOW()) as horas_transcurridas 
                FROM ingresoemergencia i 
                INNER JOIN paciente p ON i.id_paciente = p.id_paciente 
                WHERE i.estado = :estado");
            
            $stmt->bindParam(":estado", $estado, PDO::PARAM_STR);
            $stmt->execute();
            return $stmt->fetchAll();
        }
        static public function mdlIngresarEvolucion($datos) {
            $db = Conexion::conectar();
            
            // 1. Buscamos el ID de la consulta médica asociada a ese ingreso
            $stmt1 = $db->prepare("SELECT id_consulta FROM consultamedica WHERE id_ingreso = :id_i ORDER BY id_consulta DESC LIMIT 1");
            $stmt1->bindParam(":id_i", $datos["id_ingreso"], PDO::PARAM_INT);
            $stmt1->execute();
            $consulta = $stmt1->fetch();

            if($consulta) {
                // 2. Insertamos la nota
                $stmt2 = $db->prepare("INSERT INTO evolucionmedica(id_consulta, nota_evolucion, id_usuario) VALUES (:id_c, :nota, :id_u)");
                $stmt2->execute([
                    ":id_c"    => $consulta["id_consulta"],
                    ":nota"    => $datos["nota"],
                    ":id_u"    => $datos["id_usuario"]
                ]);
                return "ok";
            }
            
            return "error";
        }

        static public function mdlFinalizarObservacion($datos) {
            $db = Conexion::conectar();
            $db->beginTransaction();

            try {
                // 1. Actualizar el ingreso (Cierre definitivo)
                $stmt = $db->prepare("UPDATE ingresoemergencia SET 
                    estado = :estado, 
                    fecha_cierre = :fecha,
                    id_usuario_cierre = :id_u,
                    destino_final = :estado 
                    WHERE id_ingreso = :id_i");

                $fecha = date("Y-m-d H:i:s");
                $stmt->bindParam(":estado", $datos["estado"], PDO::PARAM_STR);
                $stmt->bindParam(":fecha", $fecha, PDO::PARAM_STR);
                $stmt->bindParam(":id_u", $datos["id_usuario"], PDO::PARAM_INT);
                $stmt->bindParam(":id_i", $datos["id_ingreso"], PDO::PARAM_INT);
                $stmt->execute();

                // 2. Opcional: Registrar la última nota en evolución indicando el egreso
                $stmt2 = $db->prepare("SELECT id_consulta FROM consultamedica WHERE id_ingreso = :id_i ORDER BY id_consulta DESC LIMIT 1");
                $stmt2->execute([":id_i" => $datos["id_ingreso"]]);
                $consulta = $stmt2->fetch();

                if($consulta){
                    $stmt3 = $db->prepare("INSERT INTO evolucionmedica(id_consulta, nota_evolucion, id_usuario) VALUES (:id_c, :nota, :id_u)");
                    $notaFinal = "EGRESO DEL SERVICIO: " . $datos["nota"];
                    $stmt3->execute([
                        ":id_c" => $consulta["id_consulta"],
                        ":nota" => $notaFinal,
                        ":id_u" => $datos["id_usuario"]
                    ]);
                }

                $db->commit();
                return "ok";

            } catch (Exception $e) {
                $db->rollBack();
                return $e->getMessage();
            }
        }

        static public function mdlMostrarDetalleReceta($item, $valor){

            // Usamos INNER JOIN para traer todo de un solo golpe
            $stmt = Conexion::conectar()->prepare("SELECT 
                i.id_ingreso, i.fecha_ingreso, c.id_consulta, i.tipo_seguro, p.direccion, p.contacto,
                p.nombres, p.apellidos, p.id_paciente, p.fecha_nacimiento, p.codigo_hc, p.dni, p.sexo, p.ocupacion, p.estado_civil, p.grado_instruccion, p.religion, TIMESTAMPDIFF(YEAR, p.fecha_nacimiento, CURDATE()) as edad_actual,
                s.presion_arterial, s.temperatura, s.frecuencia_respiratoria, s.saturacion_oxigeno, s.pulso, tr.nivel_prioridad,
                d.codigo_cie10, c.examen_fisico, a.nombre_area, c.anamnesis,
                t.medicamentos, t.procedimientos, t.indicaciones, i.motivo_consulta,
                tr.modo_ingreso, tr.acomp_dni, tr.acomp_nombre, tr.acomp_telefono, tr.acomp_direccion,
                CONCAT(dep.name, ', ', pr.name, ', ', di.name) AS  lugar_nacimiento ,
                CONCAT(dep_p.name, ', ', pr_p.name, ', ', di_p.name) AS procedencia
                FROM ingresoemergencia i
                INNER JOIN paciente p ON i.id_paciente = p.id_paciente
                INNER JOIN ubigeo_peru_districts di ON p.id_ubigeo_nacimiento = di.id
                INNER JOIN ubigeo_peru_provinces pr ON di.province_id = pr.id
                INNER JOIN ubigeo_peru_departments dep ON di.department_id = dep.id
                LEFT JOIN ubigeo_peru_districts di_p ON p.id_ubigeo_procedencia = di_p.id
                LEFT JOIN ubigeo_peru_provinces pr_p ON di_p.province_id = pr_p.id
                LEFT JOIN ubigeo_peru_departments dep_p ON di_p.department_id = dep_p.id
                LEFT JOIN triaje tr ON i.id_ingreso = tr.id_ingreso
                INNER JOIN areas a ON tr.id_area = a.id
                INNER JOIN signosvitales s ON s.id_triaje = tr.id_triaje
                INNER JOIN consultamedica c ON i.id_ingreso = c.id_ingreso
                INNER JOIN diagnostico d ON c.id_consulta = d.id_consulta
                INNER JOIN tratamiento t ON d.id_diagnostico = t.id_diagnostico
                WHERE i.$item = :$item");

            $stmt -> bindParam(":".$item, $valor, PDO::PARAM_INT);
            $stmt -> execute();

            return $stmt -> fetch(); // Retorna un array asociativo con todas las columnas
        }

        static public function mdlMostrarHistorialPaciente1($item, $valor){

            $stmt = Conexion::conectar()->prepare("SELECT 
                i.id_ingreso, i.fecha_ingreso,
                GROUP_CONCAT(DISTINCT d.codigo_cie10 SEPARATOR ', ') as codigo_cie10,
                tr.medicamentos, tr.indicaciones,
                e.nombre as medico,
                /* [RF05] Traemos los adjuntos de este ingreso específico */
                (SELECT GROUP_CONCAT(CONCAT(doc.tipo_documento, ':', doc.ruta_archivo) SEPARATOR '||') 
                FROM documento doc 
                WHERE doc.id_ingreso = i.id_ingreso) as adjuntos_raw
                FROM ingresoemergencia i
                LEFT JOIN consultamedica c ON i.id_ingreso = c.id_ingreso
                LEFT JOIN diagnostico d ON c.id_consulta = d.id_consulta
                LEFT JOIN tratamiento tr ON d.id_diagnostico = tr.id_diagnostico
                LEFT JOIN usuario u ON c.id_medico = u.id_usuario
                LEFT JOIN empleado e ON u.id_empleado = e.id_empleado
                WHERE i.$item = :$item
                GROUP BY i.id_ingreso
                ORDER BY i.fecha_ingreso DESC");

            $stmt->bindParam(":".$item, $valor, PDO::PARAM_INT);
            $stmt->execute();

            return $stmt->fetchAll();

        }
            
        static public function mdlAnularConsulta($idIngreso) {
                $db = Conexion::conectar();
                $db->beginTransaction();

                try {
                    // 1. Anulación lógica de la consulta (tabla consultamedica)
                    // Usamos el campo 'estado' numérico (0) que agregamos antes
                    $stmt1 = $db->prepare("UPDATE consultamedica SET estado = 0 WHERE id_ingreso = :id");
                    $stmt1->execute([":id" => $idIngreso]);

                    // 2. Reactivación del ingreso (tabla ingresoemergencia)
                    // Regresamos el estado a 'activo' y limpiamos el destino y la fecha de cierre
                    $stmt2 = $db->prepare("UPDATE ingresoemergencia SET 
                                            estado = 'activo', 
                                            destino_final = NULL, 
                                            fecha_cierre = NULL 
                                        WHERE id_ingreso = :id");
                    $stmt2->execute([":id" => $idIngreso]);

                    $db->commit();
                    return "ok";

                } catch (Exception $e) {
                    $db->rollBack();
                    return "error: " . $e->getMessage();
                }
            }
                


        static public function mdlMostrarConsultaUnica($tabla, $item, $valor) {

            $stmt = Conexion::conectar()->prepare("SELECT 
                    c.id_consulta, 
                    c.id_ingreso, 
                    c.anamnesis, 
                    c.examen_fisico,
                    d.codigo_cie10,
                    t.medicamentos,
                    t.procedimientos,
                    t.indicaciones,
                    i.destino_final
                FROM $tabla c
                INNER JOIN diagnostico d ON c.id_consulta = d.id_consulta
                INNER JOIN tratamiento t ON d.id_diagnostico = t.id_diagnostico
                INNER JOIN ingresoemergencia i ON c.id_ingreso = i.id_ingreso
                WHERE c.$item = :$item");

            $stmt->bindParam(":".$item, $valor, PDO::PARAM_INT);
            $stmt->execute();

            return $stmt->fetch();

            $stmt = null;
        }


        static public function mdlEditarAtencion($datos) {
            $db = Conexion::conectar();
            
            // Iniciamos transacción
            $db->beginTransaction();

            try {
                // 1. ACTUALIZAR CABECERA DE CONSULTA
                $stmt = $db->prepare("UPDATE consultamedica SET 
                                        anamnesis = :anamnesis, 
                                        examen_fisico = :examen_fisico 
                                    WHERE id_ingreso = :id_ingreso");
                $stmt->execute([
                    ":id_ingreso"    => $datos["id_ingreso"],
                    ":anamnesis"     => $datos["anamnesis"],
                    ":examen_fisico" => $datos["examen_fisico"]
                ]);

                // 2. ACTUALIZAR DIAGNÓSTICO (Vinculado al id_ingreso a través de la consulta)
                // Usamos una subconsulta para hallar el ID de consulta basado en el ingreso
                $stmt = $db->prepare("UPDATE diagnostico SET 
                                        codigo_cie10 = :codigo 
                                    WHERE id_consulta = (SELECT id_consulta FROM consultamedica WHERE id_ingreso = :id_ingreso LIMIT 1)");
                $stmt->execute([
                    ":codigo"     => $datos["cie10"],
                    ":id_ingreso" => $datos["id_ingreso"]
                ]);

                // 3. ACTUALIZAR TRATAMIENTO 
                // Vinculado al diagnóstico, que a su vez está vinculado a la consulta
                $stmt = $db->prepare("UPDATE tratamiento SET 
                                        medicamentos = :meds, 
                                        procedimientos = :proc, 
                                        indicaciones = :ind 
                                    WHERE id_diagnostico = (
                                        SELECT d.id_diagnostico FROM diagnostico d 
                                        INNER JOIN consultamedica c ON d.id_consulta = c.id_consulta 
                                        WHERE c.id_ingreso = :id_ingreso LIMIT 1
                                    )");
                $stmt->execute([
                    ":meds"       => $datos["tratamiento"],
                    ":proc"       => $datos["procedimientos"],
                    ":ind"        => $datos["indicaciones"],
                    ":id_ingreso" => $datos["id_ingreso"]
                ]);

                // 4. ACTUALIZAR ESTADO Y DESTINO EN INGRESOEMERGENCIA (Si cambió el destino)
                $estadoDB = ($datos["destino"] == "alta" || $datos["destino"] == "deceso") ? $datos["destino"] : "observacion";
                $fechaCierre = ($estadoDB != "observacion") ? date("Y-m-d H:i:s") : null;

                $stmt = $db->prepare("UPDATE ingresoemergencia SET 
                                        estado = :estado, 
                                        destino_final = :destino, 
                                        fecha_cierre = :fecha_c 
                                    WHERE id_ingreso = :id_ingreso");
                $stmt->execute([
                    ":estado"     => $estadoDB,
                    ":destino"    => $datos["destino"],
                    ":fecha_c"    => $fechaCierre,
                    ":id_ingreso" => $datos["id_ingreso"]
                ]);

                $db->commit();
                return "ok";

            } catch (Exception $e) {
                $db->rollBack();
                return "Error: " . $e->getMessage();
            }
        }

        static public function mdlListarDiagnosticos($idConsulta) {
            $stmt = Conexion::conectar()->prepare("SELECT codigo_cie10 FROM diagnostico WHERE id_consulta = :id");
            $stmt->bindParam(":id", $idConsulta, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll(); // Retorna todas las filas de diagnósticos
        }

        static public function mdlMostrarEstadisticasInicio() {

            // 1. Pacientes ingresados hoy
            $stmt1 = Conexion::conectar()->prepare("SELECT COUNT(*) as total FROM ingresoemergencia WHERE DATE(fecha_ingreso) = CURDATE()");
            $stmt1->execute();
            $hoy = $stmt1->fetch();

            // 2. Pacientes pendientes (pasaron triaje pero no tienen consulta medica aun)
            $stmt2 = Conexion::conectar()->prepare("SELECT COUNT(i.id_ingreso) as total 
                FROM ingresoemergencia i 
                LEFT JOIN consultamedica c ON i.id_ingreso = c.id_ingreso 
                WHERE c.id_consulta IS NULL AND DATE(i.fecha_ingreso) = CURDATE()");
            $stmt2->execute();
            $pendientes = $stmt2->fetch();

            // 3. Pacientes en Observación (basado en destino_final)
            $stmt3 = Conexion::conectar()->prepare("SELECT COUNT(*) as total FROM ingresoemergencia WHERE destino_final = 'OBSERVACION'");
            $stmt3->execute();
            $observacion = $stmt3->fetch();

            return array(
                "atenciones_hoy" => $hoy["total"],
                "pendientes" => $pendientes["total"],
                "observacion" => $observacion["total"]
            );
        }
  
}