<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\Event\Event;
use Cake\ORM\TableRegistry;

/**
 * Patients Controller
 *
 * @property \App\Model\Table\PatientsTable $Patients
 */
class PatientsController extends AppController
{

    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('Permission');

        // View or Controller
        $this->set('title', 'Paciente');
    }

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);

        $this->Auth->allow(['add', 'logout', 'recuperateEmail', 'delete']);
    }

    public function isAuthorized($user)
    {
        return true;
        $action = $this->request->params['action'];

        return $this->Permission->hasPermission($user['role_name'], 'patients', $action);

        //return parent::isAuthorized($user);
    }

    /**
     * Index method
     *
     * @return \Cake\Network\Response|null
     */
    public function index()
    {
        // $patients = $this->paginate($this->Patients);

        // $this->set(compact('patients'));
        // $this->set('_serialize', ['patients']);
        $session = $this->request->session();
        $unit_id = $session->read('selected-unit');

        $unitsTable = TableRegistry::get('Units');

        $param = $this->request;
        $name  = null;
        $cpf   = null;

        $this->paginate = [
            //'contain' => ['Users'],
            'limit' => 6,
            'order' => ['created' => 'desc'],
        ];

        if (isset($param->query['name']) || isset($param->query['cpf'])) {
            $name = $param->query['name'];
            $cpf  = $param->query['cpf'];

            $query = $this->Patients->find()
                ->where(['Patients.document_number LIKE' => $cpf . '%', 'Patients.nome LIKE ' => $name . '%'])
                ->contain(['Units'])
            ;
            $query->innerJoinWith('Units')
                ->distinct(['Patients.id'])
                ->where(['Units.id =' => $unit_id])
            ;
        } else {
            $query = $this->Patients->find()
                ->contain(['Units'])
            ;

            $query->innerJoinWith('Units')
                ->distinct(['Patients.id'])
                ->where(['Units.id =' => $unit_id])
            ;
        }

        // $users = $this->paginate($this->Users);
        $patients = $this->paginate($query);

        $this->set(compact('patients'));
        $this->set('_serialize', ['patients']);
    }

    public function indexSector($sector_id = null)
    {
        // $patients = $this->paginate($this->Patients);

        // $this->set(compact('patients'));
        // $this->set('_serialize', ['patients']);
        $session = $this->request->session();
        $unit_id = $session->read('selected-unit');

        $unitsTable            = TableRegistry::get('Units');
        $sectorsTable          = TableRegistry::get('Sectors');
        $hospitalizationsTable = TableRegistry::get('Hospitalizations');

        $param = $this->request;
        $name  = null;
        $cpf   = null;

        $this->paginate = [
            //'contain' => ['Users'],
            'limit' => 20,
        ];

        $sectors = $sectorsTable->find('list', ['keyField' => 'id', 'valueField' => 'name'])
            ->where(['Sectors.unit_id' => $unit_id]);

        $query = $hospitalizationsTable
            ->find()
            ->select([
                'Hospitalizations.patient_id',
                'Hospitalizations.id',
                'Hospitalizations.numero_do_prontuario',
                'Hospitalizations.date_of_hospitalization',
                'Patients.id',
                'Patients.nome',
                'Patients.birthday',
                'Patients.medical_record_number',

                //'Cultures.germe',
                //'HistoricPatientMovements.id',
            ])

            ->order(['Hospitalizations.created' => 'DESC'])
            ->group(['Hospitalizations.patient_id'])

            ->contain([
                'Patients',
                'Discharges'               => function (\Cake\ORM\Query $q) {
                    return $q->where([
                        'Discharges.data_saida_unidade <>' => null,
                    ])
                    ;
                },

                'Cultures'                 => function (\Cake\ORM\Query $q) {
                    return $q
                        ->limit(10)
                        ->autoFields(true)
                        ->order(['Cultures.created' => 'DESC'])
                        ->where([
                            'Cultures.germe_tem_resistencia' => true,
                        ])
                    ;
                },

                'HistoricPatientMovements.Rooms.Sectors',
                'HistoricPatientMovements' => function (\Cake\ORM\Query $q) {
                    return $q
                    //->contain(['Rooms.Sectors'])
                    ->innerJoinWith('Rooms.Sectors')
                    ->select([ 'Rooms.name'])
                        ->autoFields(true)
                    //->group(['HistoricPatientMovements.data_inicio'])
                        ->order(['HistoricPatientMovements.data_inicio' => 'DESC'])
                        ->limit(1)

                    ;
                },
            ])
        ;

        // $query->innerJoinWith('Rooms.HistoricPatientMovements', function ($q) {
        //     return $q
        //         ->contain(['Hospitalizations.Patients'])
        //         //->innerJoinWith('Rooms.Sectors')
        //         ->select([ 'Rooms.name'])
        //         ->autoFields(true)
        //         //->group(['HistoricPatientMovements.data_inicio'])
        //         ->order(['HistoricPatientMovements.data_inicio' => 'DESC'])
        //         ->limit(1)
        // });

        // if (isset($param->query['name']) || isset($param->query['cpf'])) {
        //     $name = $param->query['name'];
        //     $cpf  = $param->query['cpf'];

        //     // $query = $this->Patients->find()
        //     //     ->where(['Patients.document_number LIKE' => $cpf . '%', 'Patients.nome LIKE ' => $name . '%'])
        //     //     ->contain(['Units'])
        //     // ;

        //         ->where([
        //             'Hospitalizations.unit_id' => $unit_id])
        //         ->contain(['Discharges'                  => function (\Cake\ORM\Query $q) {
        //             return $q->where([
        //                 'Discharges.data_saida_unidade <>' => null,
        //             ])
        //             ;
        //         },
        //             'Patients',
        //             'HistoricPatientMovements.Rooms.Sectors' => function (\Cake\ORM\Query $q) {
        //                 return $q->group(['HistoricPatientMovements.data_inicio'])
        //                     ->order(['HistoricPatientMovements.data_inicio' => 'DESC'])

        //                 ;
        //             },
        //         ])

        //     ;

        // } else {
        // $query = $this->Patients->find()
        //     ->contain(['Units'])
        // ;

        // $query = $hospitalizationsTable->find()
        //     ->where([
        //         'Hospitalizations.unit_id' => $unit_id])
        //     ->contain(['Discharges'                  => function (\Cake\ORM\Query $q) {
        //         return $q->where([
        //             'Discharges.data_saida_unidade <>' => null,
        //         ])
        //         ;
        //     },
        //         'Patients',
        //         'HistoricPatientMovements.Rooms.Sectors' => function (\Cake\ORM\Query $q) {
        //             return $q->group(['HistoricPatientMovements.data_inicio'])
        //                 ->order(['HistoricPatientMovements.data_inicio' => 'DESC'])
        //             ;
        //         },
        //     ])

        // ;

        // $query = $this->Patients->find('all')->contain([
        //     'Hospitalizations' => ['Discharges', 'HistoricPatientMovements' => ['Rooms' => ['Sectors']],
        //     ],
        // ]);

        // $query->innerJoinWith('Hospitalizations', function ($q) use ($unit_id) {
        //     return $q //->where(['Hospitalizations.unit_id ' => $unit_id]);
        //     ;
        // });

        // $query->leftJoinWith('Hospitalizations', function ($q) use ($unit_id) {
        //     return $q->where(['Hospitalizations.unit_id ' => $unit_id]);
        // });

        // $query->matching('HistoricPatientMovements', function ($q) {
        //     return $q->order(['HistoricPatientMovements.data_inicio ' => 'DESC'])
        //         ->limit(1)
        //     ;
        // });

        // $query->matching('Discharges', function ($q) use ($unit_id) {
        //     return $q->order(['Discharges.data_saida_unidade <> ' => 'DESC'])
        //         ->limit(1)
        //     ;
        // });

        // $query->matching('Patients', function ($q) use ($unit_id) {
        //     return $q->limit(1)
        //     ;
        // });
        //}

        // $users = $this->paginate($this->Users);
        $data = $this->paginate(
            $query
            ->select(['HistoricPatientMovements__id'])
            );

        $this->set(compact('data', 'sectors'));
        $this->set('_serialize', ['data']);
    }

    /**
     * View method
     *
     * @param string|null $id Patient id.
     * @return \Cake\Network\Response|null
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $patient = $this->Patients->get($id, [
            //'contain' => ['Telephones', 'Allergies', 'Diagnostics', 'GlasgowComaScales', 'Hospitalizations', 'Responsibles', 'Screenings']
            //'contain' => ['Telephones'],
        ]);

        $this->set('patient', $patient);
        $this->set('_serialize', ['patient']);
    }

    /**
     * Add method
     *
     * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise.
     */
    public function add($patient_id = null, $patient_name = null)
    {
        $session = $this->request->session();
        $unit_id = $session->read('selected-unit');
        $patient = $this->Patients->newEntity();

        $health_insurance_plans_table = TableRegistry::get('HealthInsurancePlans');
        $health_insurance_plans       = $health_insurance_plans_table
            ->find()
            ->where(['HealthInsurancePlans.unit_id =' => $unit_id])
            ->toArray()
        ;

        if ($this->request->is('post')) {
            $patient = $this->Patients->patchEntity($patient, $this->request->data);

            if ($this->Patients->save($patient)) {

                $this->Flash->success(__('O paciente foi salvo.'));
                return $this->redirect(['action' => 'add', $patient->id, $patient->nome]);
            } else {
                $this->Flash->error(__('O paciente não pode ser salvo. Por favor, tente novamente.'));
            }
        }

        //$telephones = $this->Patients->Telephones->find('list', ['limit' => 200]);
        $this->set(compact('patient', "unit_id", 'health_insurance_plans', 'patient_id', 'patient_name'));
        $this->set('_serialize', ['patient']);
    }

    /**
     * Edit method
     *
     * @param string|null $id Patient id.
     * @return \Cake\Network\Response|void Redirects on successful edit, renders view otherwise.
     * @throws \Cake\Network\Exception\NotFoundException When record not found.
     */
    public function edit($id = null)
    {
        $session = $this->request->session();
        $unit_id = $session->read('selected-unit');
        $patient = $this->Patients->newEntity();

        $patient = $this->Patients->get($id, [
            // 'contain' => ['Telephones'],
        ]);

        $health_insurance_plans_table = TableRegistry::get('HealthInsurancePlans');
        $health_insurance_plans       = $health_insurance_plans_table
            ->find()
            ->where(['HealthInsurancePlans.unit_id =' => $unit_id])
            ->toArray()
        ;

        if ($this->request->is(['patch', 'post', 'put'])) {
            $patient = $this->Patients->patchEntity($patient, $this->request->data);
            if ($this->Patients->save($patient)) {
                $this->Flash->success(__('O registro foi salvo.'));
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('O paciente não pode ser salvo. Por favor, tente novamente.'));
            }
        }
        //$telephones = $this->Patients->Telephones->find('list', ['limit' => 200]);
        $this->set(compact('patient', 'health_insurance_plans'));
        $this->set('_serialize', ['patient']);
    }

    /**
     * Delete method
     *
     * @param string|null $id Patient id.
     * @return \Cake\Network\Response|null Redirects to index.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $patient = $this->Patients->get($id);
        if ($this->Patients->delete($patient)) {
            $this->Flash->success(__('O paciente foi deletado.'));
        } else {
            $this->Flash->error(__('O paciente não pode ser deletado.'));
        }
        return $this->redirect(['action' => 'index']);
    }

    //lista os pacientes da unidade
    public function listPatientsFromUnit()
    {
        $session = $this->request->session();
        $unit_id = $session->read('selected-unit');

        $unitsTable = TableRegistry::get('Units');

        $query = $this->Patients->find()
            ->contain(['Units'])
        ;

        $query->innerJoinWith('Units')
            ->distinct(['Patients.id'])
            ->where(['Units.id =' => $unit_id])
        ;

        // $users = $this->paginate($this->Users);
        $patients = $this->paginate($query);

        $this->set(compact('patients'));
        $this->set('_serialize', ['patients']);
    }

    //guarda o id do pacienta na session e redireciona pra pagina de internacao
    public function selectPatient($patient_id = null, $patient_name = null, $go_to_internation = null)
    {
        if ($patient_id !== null) {
            $session = $this->request->session();
            $session->write('selected-patient-name', $patient_name);
            $session->write('selected-pacient', $patient_id);
            $session->write('current-state', 'internacao');

            $patient = $this->Patients->get($patient_id);
            $session->write('selected_patient_birthday', $patient->birthday);
            //$session->write('selected-hospitalization-date', date($data_internacao));

            if ($go_to_internation !== null) {
                return $this->redirect(['controller' => 'hospitalizations', 'action' => 'add']);
            }

            return $this->redirect(['controller' => 'hospitalizations', 'action' => 'index']);

        }
    }

    public function selectPatientEmergency($patient_id = null, $patient_name = null)
    {
        if ($patient_id !== null) {
            $session = $this->request->session();
            $session->write('selected-patient-name', $patient_name);
            $session->write('selected-pacient', $patient_id);
            $session->write('current-state', 'emergencia');

            $patient = $this->Patients->get($patient_id);
            $session->write('selected_patient_birthday', $patient->birthday);

        }
        //$session->write('selected-hospitalization-date', date($data_internacao));

        return $this->redirect(['controller' => 'Screenings', 'action' => 'index']);

    }

    public function selectPatientHosp($patient_id = null, $patient_name = null, $hospitalization_id = null)
    {
        if ($patient_id !== null && $hospitalization_id !== null
            && $patient_name !== null) {

            $session = $this->request->session();
            $session->write('selected-patient-name', $patient_name);
            $session->write('selected-pacient', $patient_id);
            $session->write('current-state', 'internacao');
            $session->write('selected-hospitalization', $hospitalization_id);

            $patient = $this->Patients->get($patient_id);
            $session->write('selected_patient_birthday', $patient->birthday);
            //$session->write('selected-hospitalization-date', date($data_internacao));

            return $this->redirect(['controller' => 'hospitalizations', 'action' => 'edit', $hospitalization_id]);
        }
    }

}
