<?php
/**
 * Enfermera — Gestión del personal de enfermería (domicilios).
 */

require_once __DIR__ . '/../../classes/Database.php';
require_once __DIR__ . '/ActividadAdmin.php';

class Enfermera {

    private Database $db;
    private ActividadAdmin $log;

    public function __construct() {
        $this->db  = Database::getInstance();
        $this->log = new ActividadAdmin();
    }

    // ─────────────────────────────────────────────────────────────────────────
    // CRUD
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Lista de enfermeras activas/todas.
     */
    public function listar(bool $soloActivas = true): array {
        $where = $soloActivas ? 'WHERE is_active = 1' : '';
        return $this->db->fetchAll("
            SELECT
                e.*,
                (SELECT COUNT(*) FROM lab_asignaciones a
                    JOIN lab_domicilios d ON d.id = a.domicilio_id
                    WHERE a.enfermera_id = e.id
                      AND d.fecha_programada = CURDATE()
                      AND a.estado NOT IN ('liberada','completada')
                ) AS domicilios_hoy
            FROM lab_enfermeras e
            $where
            ORDER BY e.nombre_completo ASC
        ");
    }

    /**
     * Enfermera por ID.
     */
    public function obtener(int $id): ?array {
        return $this->db->fetch(
            'SELECT * FROM lab_enfermeras WHERE id = ?',
            [$id]
        ) ?: null;
    }

    /**
     * Crear enfermera.
     */
    public function crear(array $datos, ?int $adminId = null): int {
        $campos = $this->filtrarCampos($datos);
        $id     = $this->db->insert('lab_enfermeras', $campos);
        $this->log->registrar($adminId, 'enfermeras', 'crear', $id, $campos);
        return $id;
    }

    /**
     * Actualizar enfermera.
     */
    public function actualizar(int $id, array $datos, ?int $adminId = null): bool {
        $campos = $this->filtrarCampos($datos);
        $ok     = $this->db->update('lab_enfermeras', $campos, 'id = ?', [$id]);
        $this->log->registrar($adminId, 'enfermeras', 'editar', $id, $campos);
        return $ok > 0;
    }

    /**
     * Desactivar (soft-delete).
     */
    public function desactivar(int $id, ?int $adminId = null): bool {
        $ok = $this->db->update('lab_enfermeras', ['is_active' => 0], 'id = ?', [$id]);
        $this->log->registrar($adminId, 'enfermeras', 'desactivar', $id);
        return $ok > 0;
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Agenda
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Agenda completa de una enfermera (domicilios asignados con detalle).
     *
     * @param int    $enfermeraId
     * @param string $fecha  YYYY-MM-DD, por defecto hoy
     */
    public function agenda(int $enfermeraId, string $fecha = ''): array {
        $fecha = $fecha ?: date('Y-m-d');
        $rows = $this->db->fetchAll("
            SELECT
                d.id                  AS domicilio_id,
                d.fecha_programada,
                d.hora_programada,
                d.estado              AS domicilio_estado,
                d.direccion,
                d.barrio,
                d.ciudad,
                d.indicaciones_dir,
                d.notas_admin,
                d.tipo_servicio,
                d.examenes_solicitados,
                d.tipo_cliente,
                d.seguro_nombre,
                d.orden_id,
                d.valor_domicilio,
                d.valor_copago,
                d.copago_laboratorio,
                d.autorizacion,
                d.pago_estado,
                d.pago_modo,
                d.pago_monto,
                d.pago_notas,
                d.hora_llegada,
                d.temperatura_inicio,
                d.hora_salida,
                d.temperatura_salida,
                p.id                  AS paciente_id,
                p.nombre_completo     AS paciente_nombre,
                p.telefono            AS paciente_telefono,
                p.email               AS paciente_email,
                p.fecha_nacimiento    AS paciente_fecha_nacimiento,
                p.tipo_documento      AS paciente_tipo_documento,
                p.numero_documento    AS paciente_numero_documento,
                p.eps                 AS paciente_eps,
                om.local_file         AS orden_local_file,
                d.orden_id            AS orden_id_display,
                a.estado              AS asignacion_estado,
                a.id                  AS asignacion_id,
                d.creado_por
            FROM  lab_asignaciones a
            JOIN  lab_domicilios  d  ON d.id  = a.domicilio_id
            JOIN  lab_pacientes   p  ON p.id  = d.paciente_id
            LEFT  JOIN lab_ordenes_medicas om ON om.id = d.orden_id
            WHERE a.enfermera_id      = ?
              AND d.fecha_programada  = ?
            ORDER BY d.hora_programada IS NULL ASC, d.hora_programada ASC
        ", [$enfermeraId, $fecha]);

        // Bulk-load todos los archivos de órdenes vinculados a estos domicilios
        $domIds = array_values(array_filter(array_column($rows, 'domicilio_id')));
        if (!empty($domIds)) {
            $ph       = implode(',', array_fill(0, count($domIds), '?'));
            $archivos = $this->db->fetchAll(
                "SELECT domicilio_id, id AS orden_id, local_file
                 FROM lab_ordenes_medicas
                 WHERE domicilio_id IN ($ph) AND local_file IS NOT NULL
                 ORDER BY id ASC",
                $domIds
            );
            $archivosPorDom = [];
            foreach ($archivos as $a) {
                $archivosPorDom[$a['domicilio_id']][] = $a;
            }
            foreach ($rows as &$row) {
                $did = $row['domicilio_id'];
                if (!empty($archivosPorDom[$did])) {
                    $row['archivos_ordenes'] = $archivosPorDom[$did];
                } elseif (!empty($row['orden_local_file'])) {
                    // Fallback: domicilio creado antes de la migración
                    $row['archivos_ordenes'] = [[
                        'orden_id'   => $row['orden_id_display'] ?? $row['orden_id'],
                        'local_file' => $row['orden_local_file'],
                    ]];
                } else {
                    $row['archivos_ordenes'] = [];
                }
            }
            unset($row);
        } else {
            foreach ($rows as &$row) {
                if (!empty($row['orden_local_file'])) {
                    $row['archivos_ordenes'] = [[
                        'orden_id'   => $row['orden_id_display'] ?? $row['orden_id'],
                        'local_file' => $row['orden_local_file'],
                    ]];
                } else {
                    $row['archivos_ordenes'] = [];
                }
            }
            unset($row);
        }

        return $rows;
    }

    /**
     * Carga de trabajo por período: domicilios asignados por día.
     */
    public function cargaTrabajo(int $enfermeraId, string $desde, string $hasta): array {
        return $this->db->fetchAll("
            SELECT
                d.fecha_programada,
                COUNT(*) AS total,
                SUM(d.estado = 'completado') AS completados
            FROM  lab_asignaciones a
            JOIN  lab_domicilios d ON d.id = a.domicilio_id
            WHERE a.enfermera_id = ?
              AND d.fecha_programada BETWEEN ? AND ?
            GROUP BY d.fecha_programada
            ORDER BY d.fecha_programada ASC
        ", [$enfermeraId, $desde, $hasta]);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Helpers
    // ─────────────────────────────────────────────────────────────────────────

    private function filtrarCampos(array $datos): array {
        $permitidos = [
            'numero_documento', 'tipo_documento', 'nombre_completo',
            'telefono', 'telefono_alt', 'email',
            'zona', 'notas', 'is_active',
        ];
        return array_intersect_key($datos, array_flip($permitidos));
    }
}
