<?php

declare(strict_types=1);

namespace App\Controller;

use Dompdf\Dompdf;
use Dompdf\Options;
use Cake\Routing\Router;
use Cake\ORM\TableRegistry;

/**
 * Pacientes Controller
 *
 * @property \App\Model\Table\PacientesTable $Pacientes
 */
class PacientesController extends AppController
{
    public function exportPacientePdf($id = null)
    {
        $paciente = $this->Pacientes->get($id, contain: [
            'Citas' => [
                'Campanas',
            ],
            'HistoriasClinicas' => [
                'Departamentos',
                'Consultas' => [
                    'Doctores'
                ],
            ],
        ]);

        // Renderizar la vista HTML como contenido para el PDF
        $this->viewBuilder()->enableAutoLayout(false);
        $this->set(compact('paciente'));
        $html = $this->render('historia_clinica');

        // Configurar DomPDF para el PDF
        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);

        // Configurar tamaño de papel
        $dompdf->setPaper('A4', 'portrait');

        // Renderizar el PDF
        $dompdf->render();

        // Descargar el archivo PDF
        $dompdf->stream("Paciente_Detalle_{$id}.pdf", ['Attachment' => 1]);
    }
    /**
     * Index method
     *
     * @return \Cake\Http\Response|null|void Renders view
     */
    public function index()
    {
        $query = $this->Pacientes->find()
            ->contain([
                'HistoriasClinicas' => [
                    'Departamentos'
                ]
            ]);
        $pacientes = $this->paginate($query);

        $query->order(['Pacientes.id' => 'DESC']);

        $searchTerm = $this->request->getQuery('search');
        $searchTermDni = $this->request->getQuery('searchDni');
        $conHistoria = $this->request->getQuery('con_historia');
        $searchTelefono = $this->request->getQuery('searchTelefono');

        if (!empty($searchTerm)) {
            $query->where([
                'OR' => [
                    'LOWER(Pacientes.nombre) LIKE' => '%' . strtolower($searchTerm) . '%',
                    'LOWER(Pacientes.apellido) LIKE' => '%' . strtolower($searchTerm) . '%',
                ]
            ]);
        }

        if (!empty($searchTermDni)) {
            $query->where([
                'OR' => [
                    'HistoriasClinicas.dni LIKE' => '%' . $searchTermDni . '%',
                ]
            ]);
        }
        
        if (!empty($searchTelefono)) {
            $query->where([
                'Pacientes.telefono_celular LIKE' => '%' . $searchTelefono . '%',
            ]);
        }

        if (!empty($conHistoria)) {
            $query->innerJoinWith('HistoriasClinicas');
        }

        $pacientes = $this->paginate($query);

        $this->set(compact('pacientes', 'searchTerm', 'searchTermDni', 'conHistoria','searchTelefono'));
    }

    /**
     * View method
     *
     * @param string|null $id Paciente id.
     * @return \Cake\Http\Response|null|void Renders view
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $paciente = $this->Pacientes->get($id, contain: [
            'Citas' => [
                'Campanas', 'Doctores'
            ],
            'HistoriasClinicas' => [
                'ExamenesFisicos',
                'Departamentos',
                'Users',
                'Consultas' => [
                    'Doctores',
                    'ConsultasCie' => [
                        'Diagnosticoscie10'
                    ]
                ],
                'Procedimientos' => [
                    'Doctores'
                ],
                'Documentos'
            ],
        ]);
        $this->set(compact('paciente'));
        // Si es una solicitud AJAX, usar un layout diferente
        if ($this->request->is('ajax')) {
            $this->viewBuilder()->setLayout('ajax');
        } else {
            $this->viewBuilder()->setLayout('default');
        }
    }

    /**
     * Add method
     *
     * @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
     */
    public function add()
    {
        $paciente = $this->Pacientes->newEmptyEntity();
        $historiaClinicaTable = $this->fetchTable('HistoriasClinicas');
        $historiaClinica = $historiaClinicaTable->newEmptyEntity();
        $usuario = $this->Authentication->getIdentity();

        if ($this->request->is('post')) {
            $data = $this->request->getData();
            $data['user_id'] = $usuario->id;

            $dni = $data['historiaClinica']['dni'] ?? null;

            // Validar duplicado solo si hay un DNI
            if (!empty($dni)) {
                $existeDni = $historiaClinicaTable->find()
                    ->where(['dni' => $dni])
                    ->first();

                if ($existeDni) {
                    $this->Flash->error(__('El DNI ya está registrado para otro paciente.'));
                    return $this->redirect(['action' => 'add']);
                }
            }

            // Continuar con el guardado
            $paciente = $this->Pacientes->patchEntity($paciente, $data);

            if ($this->Pacientes->save($paciente)) {
                $historiaClinicaData = array_filter($data['historiaClinica'] ?? []);

                if (!empty($historiaClinicaData)) {
                    $historiaClinica = $historiaClinicaTable->newEmptyEntity();
                    $historiaClinica = $historiaClinicaTable->patchEntity($historiaClinica, $historiaClinicaData);
                    $historiaClinica->paciente_id = $paciente->id;

                    if ($historiaClinicaTable->save($historiaClinica)) {
                        $this->Flash->success(__('El paciente y su historia clínica han sido creados.'));
                    } else {
                        $this->Flash->error(__('El paciente fue creado, pero hubo un problema al generar la historia clínica.'));
                    }
                } else {
                    $this->Flash->success(__('El paciente ha sido creado sin historia clínica.'));
                }

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('El paciente no pudo ser guardado. Inténtelo de nuevo.'));
        }

        $departamentos = $this->Pacientes->HistoriasClinicas->Departamentos->find('list', limit: 200)->all();
        $campanas = $this->Pacientes->Citas->Campanas->find('list', limit: 200)->all();
        $users = $this->Pacientes->HistoriasClinicas->Users->find('list', limit: 200)->all();

        $this->set(compact('paciente', 'historiaClinica', 'departamentos', 'campanas', 'users', 'usuario'));
    }

    /**
     * Edit method
     *
     * @param string|null $id Paciente id.
     * @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function edit($id = null)
    {
        $paciente = $this->Pacientes->get(
            $id,
            contain: ['HistoriasClinicas']
        );

        $historiaClinicaTable = $this->fetchTable('HistoriasClinicas');

        // Buscar historia clínica existente
        $historiaClinica = $historiaClinicaTable->find()
            ->where(['paciente_id' => $paciente->id])
            ->first(); // Puede ser null

        if ($this->request->is(['patch', 'post', 'put'])) {
            $data = $this->request->getData();

            // Validación de DNI solo si hay historia clínica y se envió
            $dni = $data['historia_clinica']['dni'] ?? null;

            if (!empty($dni) && $historiaClinica) {
                $existeDni = $historiaClinicaTable->find()
                    ->where([
                        'dni' => $dni,
                        'paciente_id !=' => $paciente->id
                    ])
                    ->first();

                if ($existeDni) {
                    $this->Flash->error(__('El DNI ya está registrado para otro paciente.'));
                    return $this->redirect(['action' => 'edit', $id]);
                }

                // Asegura que se guarde el DNI si es válido
                $data['historia_clinica']['dni'] = $dni;
            }

            // Actualizar datos del paciente
            $paciente = $this->Pacientes->patchEntity($paciente, $data);

            // Si hay historia existente y datos, actualizarla
            if (!empty($data['historia_clinica']) && $historiaClinica) {
                $historiaClinica = $historiaClinicaTable->patchEntity($historiaClinica, $data['historia_clinica']);
                $historiaClinica->paciente_id = $paciente->id;
            }

            // Guardar en transacción
            $this->Pacientes->getConnection()->transactional(function () use ($paciente, $historiaClinica, $historiaClinicaTable) {
                if (!$this->Pacientes->save($paciente)) {
                    throw new \Exception('Error al guardar el paciente.');
                }

                // Guardar historia solo si existe
                if ($historiaClinica && !$historiaClinica->isNew() && !$historiaClinicaTable->save($historiaClinica)) {
                    throw new \Exception('Error al guardar la historia clínica.');
                }
            });

            $this->Flash->success(__('El paciente ha sido actualizado.'));
            return $this->redirect(['action' => 'index']);
        }

        // Solo cargar datos para combos si hay historia
        $departamentos = $campanas = $users = [];
        if ($historiaClinica) {
            $departamentos = $this->Pacientes->HistoriasClinicas->Departamentos->find('list', limit: 200)->all();
            $campanas = $this->Pacientes->Citas->Campanas->find('list', limit: 200)->all();
            $users = $this->Pacientes->HistoriasClinicas->Users->find('list', limit: 200)->all();
        }

        $this->set(compact('paciente', 'historiaClinica', 'departamentos', 'campanas', 'users'));
    }


    /**
     * Delete method
     *
     * @param string|null $id Paciente id.
     * @return \Cake\Http\Response|null Redirects to index.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $paciente = $this->Pacientes->get($id);
        if ($this->Pacientes->delete($paciente)) {
            $this->Flash->success(__('The paciente has been deleted.'));
        } else {
            $this->Flash->error(__('The paciente could not be deleted. Please, try again.'));
        }

        return $this->redirect(['action' => 'index']);
    }
    // busqueda en otras tablas
    public function buscarPaciente()
    {
        $this->autoRender = false; // Evitar renderizado automático
        $this->response = $this->response->withType('json');

        $query = $this->request->getQuery('q'); // Obtener término de búsqueda

        if (!$query) {
            return $this->response->withStringBody(json_encode([])); // Si no hay consulta, retornar vacío
        }

        // Nueva forma de consulta en CakePHP 5+
        $resultados = $this->Pacientes->find()
            ->where([
                'OR' => [
                    'Pacientes.nombre LIKE' => '%' . $query . '%',
                    'Pacientes.apellido LIKE' => '%' . $query . '%',
                ]
            ])
            ->select(['id', 'nombre', 'apellido'])
            ->limit(10)
            ->toArray();

        // Formatear resultados
        $pacientes = array_map(fn($paciente) => [
            'id' => $paciente->id,
            'nombre' => $paciente->nombre . ' ' . $paciente->apellido,
        ], $resultados);

        return $this->response->withStringBody(json_encode($pacientes));
    }
}
