<?php
namespace App\Model\Table;

use App\Model\Entity\Prescription;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use MedidasDispersao\MedidasDispersao;

require_once ROOT . DS . "vendor" . DS . "Zurubabel" . DS . "MedidasDispersao.php";

/**
 * Prescriptions Model
 *
 * @property \Cake\ORM\Association\BelongsTo $Hospitalizations
 * @property \Cake\ORM\Association\HasMany $Medications
 */
class PrescriptionsTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('prescriptions');
        $this->displayField('id');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');

        $this->belongsTo('Hospitalizations', [
            'foreignKey' => 'hospitalization_id',
            'joinType' => 'INNER',
        ]);
        $this->hasMany('Medications', [
            'foreignKey' => 'prescription_id',
        ]);
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->allowEmpty('precaution');

        $validator
            ->allowEmpty('germs');

        $validator
            ->allowEmpty('nutrition');

        $validator
            ->allowEmpty('speech_therapy');

        $validator
            ->allowEmpty('odontology');

        $validator
            ->boolean('is_active')
            ->allowEmpty('is_active');

        $validator
            ->allowEmpty('allergy');

        // $validator
        //     ->date('start_date');

        // $validator
        //     ->date('end_date');

        return $validator;
    }

    public function getRelatorioData($hospitalizations, $sectors, $date_begin, $date_end)
    {
        $calc_obj = new MedidasDispersao();

        $data =
            [
            'total_prescricoes' => 0,
            'total_medicacoes' => 0,
            'total_pacientes' => 0,
            'arr_pacientes' => [],

            'media_medicacao_por_prescricao' => 0,

            'medicacoes_dispensadas' =>
            [
                'tot_madrugada' => 0, //TOTAL DE MEDICAÇÕES DISPENSADAS NO PERÍODO POR TURNO - MANHA , TARDE, NOITE E MADRUGADA
                'percen_madrugada' => 0,
                'tot_manha' => 0,
                'percen_manha' => 0,
                'tot_tarde' => 0,
                'percen_tarde' => 0,
                'tot_noite' => 0,       
                'percen_noite' => 0,         
            ],

            'tipo_medicacao' =>
            [
                'arr' => [],
                'interacao_medicamentosa' =>
                [
                    'total' => 0,
                    'percentual' => 0,
                    'arr_total_prescricoes' => [], //Total de interação medicamentosa por prescrição
                    'total_prescricoes' => 0, //total de prescricoes com iteração medicamentosa
                    'arr_prescricoes' => [], //array id das  prescricoes com iteração medicamentosa
                    'media_total_interacao_por_prescricao' => 0,
                    'media_total_interacao_por_prescricao_interacao_medicamentosa' => 0,
                ],

                'baixo_estoque' =>
                [
                    'total' => 0, //total de medicacoes com baixo estoque
                    'percentual' => 0, //percen de medicacoes com baixo estoque

                    'arr_total_prescricoes' => [], //Total de medicacoes com baixo estoque
                    'total_prescricoes' => 0, //total de prescricoes com baixo estoque
                    'arr_prescricoes' => [], //array id das  prescricoes com iteração medicamentosa

                    'percen_total_por_prescricao' => 0,

                    'media_medicacao_por_paciente' => 0,

                    'media_medicacoes_prescricao' => 0,
                    'media_medicacoes_prescricao_com_baixo_estoque' => 0,

                    'percen_total_por_prescricao_baix_esto' => 0,
                ],

                'alta_vigilancia' =>
                [
                    'total' => 0,
                    'arr_total_prescricoes' => [], //Total de medicacoes com alta vigilancia
                    'total_prescricoes' => 0, //total de prescricoes com iteração medicamentosa
                    'arr_prescricoes' => [], //array id das  prescricoes com iteração medicamentosa
                    'arr_pacientes_com_alta_vigilancia' => [], //array id dos pacientes com medicamento de alta vigilancia
                    'tot_pacientes_com_alta_vigilancia' => [], //tot de pacientes com medicamento de alta vigilancia
                    'percen_pacientes_com_alta_vigilancia' => 0, //percen medicações de alta vigilancia por paciente
                    'media_pacientes_com_alta_vigilancia' => 0, //media medicações de alta vigilancia por paciente
                    'percentual' => 0,

                    'media_medicacoes_por_prescricao' => 0,
                    'media_medicacoes_por_prescricao_com_alta_vigilancia' => 0,
                ],

                'estoque_zerado' =>
                [
                    'total' => 0,
                    'percentual' => 0,

                    'arr_total_prescricoes' => [], //Total de medicacoes com estoque zerado
                    'iteracao_por_prescricao' => 0, //Total de interação medicamentosa por prescrição

                    'total_prescricoes' => 0, //total de prescricoes com iteração medicamentosa
                    'arr_prescricoes' => [], //array id das  prescricoes com iteração medicamentosa
                    'percen_total_por_prescricao' => 0,

                    'media_medicacoes_prescricao' => 0,
                    'media_medicacoes_prescricao_com_estoque_zerado' => 0,

                    'media_medicacao_por_paciente' => 0,
                ],

                'nao_padronizada' =>
                [
                    'total' => 0,
                    'percentual' => 0,

                    'arr_total_prescricoes' => [], //Total de medicacoes não padronizada
                    'iteracao_por_prescricao' => 0, //Total de interação medicamentosa por prescrição
                    'total_prescricoes' => 0, //total de prescricoes com iteração medicamentosa
                    'arr_prescricoes' => [], //array id das  prescricoes com iteração medicamentosa

                    'media_medic_n_padro_por_med_prescritas' => 0,
                    'percen_medic_n_padro_por_med_prescritas' => 0, //TOTAL DE MEDICAÇÃO COM NÃO PADRONIZADAS DISPENSADAS POR MEDICAÇÕES PRESCRITAS DISPENSADAS                    

                    'media_medicacoes_prescricao' => 0,
                    'percen_total_por_prescricao' => 0,
                ],

                'medicamentacao_regular' =>
                [
                    'total' => 0,
                    'arr_total_prescricoes' => [], //Total de medicacoes com medicamento regular
                    'medicamentacao_regular' => 0, //Total de interação medicamentosa por prescrição
                    'total_prescricoes' => 0, //total de prescricoes com iteração medicamentosa
                    'arr_prescricoes' => [], //array id das  prescricoes com iteração medicamentosa
                    'percentual' => 0,
                ],
            ],

            'setores' => [],
        ];

        foreach ($sectors as $sector)
        {
            $sector_id = $sector['id'];

            $data['setores'][$sector_id] = [
                'name' => $sector['name'],
                'total_medicacoes' => 0,
                'percen_medicacoes' => 0,

                'total_prescricoes' => 0,
                'media_medicacao_por_prescricao' => 0,
            ];
        }

        foreach ($hospitalizations as $hospitalization)
        {
            if (in_array($hospitalization['patient_id'], $data['arr_pacientes']) == false)
            {
                array_push($data['arr_pacientes'], $hospitalization['patient_id']);
                $data['total_pacientes']++;
            }

            //$data = $hospitalization["neonatal_checklists"];
            
            foreach ($hospitalization["prescriptions"] as $prescription)
            {
                if ($prescription['created'] < $date_begin ||
                    $prescription['created'] > $date_end)
                {
                    continue;
                }
                
                $data['total_prescricoes']++;
                $sector_id = null;

                if ($prescription['sector_id'])
                {
                    $sector_id = $prescription['sector_id'];
                    $data['setores'][$sector_id]['total_prescricoes']++;
                }

                $interacao_medicamentosa = true;

                foreach ($prescription["medications"] as $medication)
                {
                    $data['total_medicacoes']++;
                    if ($sector_id)
                    {
                        $data['setores'][$sector_id]['total_medicacoes']++;
                    }

                    $time = $medication['created']->format('H:i:s');
                    if (strtotime($time) >=  strtotime('00:00:00') &&
                        strtotime($time) <= strtotime('06:00:00'))
                    {
                        $data['medicacoes_dispensadas']['tot_madrugada']++;
                    }
                    else if (strtotime($time) >= strtotime('06:00:00') &&
                        strtotime($time) <= strtotime('11:59:00'))
                    {
                        $data['medicacoes_dispensadas']['tot_manha']++;
                    }
                    else if (strtotime($time) >= strtotime('12:00:00') &&
                        strtotime($time) <= strtotime('17:59:00'))
                    {
                        $data['medicacoes_dispensadas']['tot_tarde']++;
                    }
                    else if (strtotime($time) >= strtotime('18:00:00') &&
                        strtotime($time) <= strtotime('23:59:00'))
                    {
                        $data['medicacoes_dispensadas']['tot_noite']++;
                    }

                    if (isset($medication['sign']['description']))
                    {
                        $description = null;

                        switch ($medication['sign']['description'])
                        {
                            case 'Sinalização de interação medicamentosa':
                                $data['tipo_medicacao']['interacao_medicamentosa']['total']++;
                                $description = 'interacao_medicamentosa';
                                break;

                            case 'Sinalização de medicação com baixo estoque':
                                $data['tipo_medicacao']['baixo_estoque']['total']++;
                                $description = 'baixo_estoque';
                                break;

                            case 'Sinalização de medicação de alta vigilância':
                                $data['tipo_medicacao']['alta_vigilancia']['total']++;
                                $description = 'alta_vigilancia';

                                //calcula total prescricos com ieracao medicamentosa
                                if (in_array($hospitalization['patient_id'], $data['tipo_medicacao']['alta_vigilancia']['arr_pacientes_com_alta_vigilancia']) == false)
                                {
                                    array_push($data['tipo_medicacao']['alta_vigilancia']['arr_pacientes_com_alta_vigilancia'], $hospitalization['patient_id']);
                                    $data['tipo_medicacao']['alta_vigilancia']['tot_pacientes_com_alta_vigilancia']++;
                                }
                                break;

                            case 'Sinalização de medicação com estoque zerado':
                                $data['tipo_medicacao']['estoque_zerado']['total']++;
                                $description = 'estoque_zerado';
                                break;

                            case 'Sinalização de medicação não padronizada':
                                $data['tipo_medicacao']['nao_padronizada']['total']++;
                                $description = 'nao_padronizada';
                                break;
                            case 'Medicação regular (sem restrição e padronizada)':
                                $data['tipo_medicacao']['medicamentacao_regular']['total']++;
                                $description = 'medicamentacao_regular';
                                break;
                        }

                        if ($description)
                        {
                            //calcula total prescricos com ieracao medicamentosa
                            if (in_array($prescription['id'], $data['tipo_medicacao'][$description]['arr_total_prescricoes']) == false)
                            {
                                array_push($data['tipo_medicacao'][$description]['arr_total_prescricoes'], $prescription['id']);
                                $data['tipo_medicacao'][$description]['total_prescricoes']++;
                            }
                        }
                    }

                    $properties_arr = (array) $medication;
                    $i = 0;

                    foreach ($properties_arr as $value_2)
                    {
                        $i++;
                        if ($i == 2) //acessa as propriades do obj
                        {
                            foreach ($value_2 as $key_3 => $value_3)
                            {
                                //$data[$key_3] = $value_3;
                                formatArr($value_3, $data, $key_3);
                            }
                        }
                    }
                }
            }
        }

        foreach ($data as $key => $value)
        {
            if (isset($data[$key]['arr']))
            {
                $marcados = 0;

                $len = count($data[$key]['arr']);

                for ($i = 0; $i < $len; $i++)
                {
                    if ($data[$key]['arr'][$i] || $data[$key]['arr'][$i] !== 0)
                    {
                        $marcados++;
                    }
                }

                if (isset($data[$key]['percentual']))
                {
                    $data[$key]['total'] = count($data[$key]['arr']);
                    $data[$key]['percentual'] = $calc_obj->calculate_percentage($marcados, $data['total_prescricoes']);
                    $data[$key]['media'] = $calc_obj->calc_average($data[$key]['arr']);
                    $data[$key]['mediana'] = $calc_obj->calculate_median($data[$key]['arr']);
                    $data[$key]['desvio_padrao'] = $calc_obj->standard_deviation($data[$key]['arr']);
                }
            }
        }

        foreach ($data['tipo_medicacao'] as $key => $value)
        {
            if (isset($value['total']) &&
                $data['total_prescricoes'] > 0 &&
                $value['total_prescricoes'] > 0)
            {
                // if ($key == "interacao_medicamentosa" && $value['total'] > 0 && $data['total_prescricoes'] > 0)
                // {
                $data['tipo_medicacao'][$key]['percentual'] = ($value['total_prescricoes'] * 100) / $data['total_prescricoes'];
                $data['tipo_medicacao'][$key]['percentual'] = round($data['tipo_medicacao'][$key]['percentual'], 2);
                //}

                if ($key == "alta_vigilancia" && $value['total'] > 0 && $value['tot_pacientes_com_alta_vigilancia'] > 0)
                {
                    $data['tipo_medicacao'][$key]['percen_pacientes_com_alta_vigilancia'] = ($value['total'] * 100) / $data['total_pacientes'];
                    $data['tipo_medicacao'][$key]['percen_pacientes_com_alta_vigilancia'] = round($data['tipo_medicacao'][$key]['percen_pacientes_com_alta_vigilancia'], 2);

                    $data['tipo_medicacao'][$key]['media_pacientes_com_alta_vigilancia'] = round($value['total'] / $data['total_pacientes'], 2);

                    $data['tipo_medicacao'][$key]['media_medicacoes_por_prescricao'] = round($value['total'] / $data['total_prescricoes'], 2);
                    $data['tipo_medicacao'][$key]['media_medicacoes_por_prescricao_com_alta_vigilancia'] = round($value['total'] / $value['total_prescricoes'], 2);
                }
                elseif ($key == "baixo_estoque" && $value['total'] > 0 && $data['total_prescricoes'] > 0)
                {
                    $data['tipo_medicacao'][$key]['percen_total_por_prescricao_baix_esto'] = ($value['total_prescricoes'] * 100) / $data['total_prescricoes'];
                    $data['tipo_medicacao'][$key]['percen_total_por_prescricao_baix_esto'] = round($data['tipo_medicacao'][$key]['percen_total_por_prescricao_baix_esto'], 2);

                    $data['tipo_medicacao'][$key]['media_medicacao_por_paciente'] = round($value['total'] / $data['total_pacientes'], 2);

                    $data['tipo_medicacao'][$key]['media_medicacoes_prescricao'] = round($value['total'] / $data['total_prescricoes'], 2);
                    $data['tipo_medicacao'][$key]['media_medicacoes_prescricao_com_baixo_estoque'] = round($value['total'] / $value['total_prescricoes'], 2);
                }
                elseif ($key == "estoque_zerado" && $value['total'] > 0 && $data['total_prescricoes'] > 0)
                {
                    $data['tipo_medicacao'][$key]['media_medicacao_por_paciente'] = round($value['total'] / $data['total_pacientes'], 2);

                    $data['tipo_medicacao'][$key]['media_medicacoes_prescricao'] = round($value['total'] / $data['total_prescricoes'], 2);
                    $data['tipo_medicacao'][$key]['media_medicacoes_prescricao_com_estoque_zerado'] = round($value['total'] / $value['total_prescricoes'], 2);
                }
                elseif ($key == "nao_padronizada" && $value['total'] > 0 && $data['total_prescricoes'] > 0)
                {
                    
                    $data['tipo_medicacao'][$key]['media_medicacoes_prescricao'] = round($value['total'] / $data['total_prescricoes'], 2);                        
                    $data['tipo_medicacao'][$key]['media_medic_n_padro_por_med_prescritas'] = round($value['total'] / $data['total_medicacoes'], 2);                        

                    $data['tipo_medicacao'][$key]['percen_medic_n_padro_por_med_prescritas'] = ($value['total'] * 100) / $data['total_medicacoes'];
                    $data['tipo_medicacao'][$key]['percen_medic_n_padro_por_med_prescritas'] = round($data['tipo_medicacao'][$key]['percen_medic_n_padro_por_med_prescritas'], 2);
                }
                elseif ($key == "interacao_medicamentosa" && count($value['arr_total_prescricoes']) > 0)
                {

                    $data['tipo_medicacao'][$key]['media_total_interacao_por_prescricao_interacao_medicamentosa'] = round($value['total'] / $value['total_prescricoes'], 2);
                    $data['tipo_medicacao'][$key]['media_medicacoes_prescricao'] = round($value['total'] / $data['total_prescricoes'], 2);
                }

                $data['tipo_medicacao'][$key]['percen_total_por_prescricao'] = ($value['total'] * 100) / $value['total_prescricoes'];
                $data['tipo_medicacao'][$key]['percen_total_por_prescricao'] = round($data['tipo_medicacao'][$key]['percen_total_por_prescricao'], 2);

                // $res = ($value['total'] / $data['tipo_medicacao'][$key]['total_prescricoes']) * 100;
                // $res = round($res, 2);

                //$data['tipo_medicacao'][$key]['percentual'] = $res;
            }

            //media_total_interacao_por_prescricao
        }

        foreach ($data['setores'] as $setor_key => $setor)
        {
            if ($data['total_medicacoes'] > 0)
            {
                if ( $setor['total_prescricoes'] > 0 )
                {
                    $data['setores'][$setor_key]['media_medicacao_por_prescricao'] = round($data['total_medicacoes'] / $setor['total_prescricoes'], 2);    
                }

                $data['setores'][$setor_key]['percen_medicacoes'] = round( ($setor['total_medicacoes'] * 100) / $data['total_medicacoes'], 2);    
            }
        }

        if ($data['total_prescricoes'] > 0 && $data['total_medicacoes'] > 0)
        {
            $data['media_medicacao_por_prescricao'] = round($data['total_medicacoes'] / $data['total_prescricoes'], 2);
        }
        
        if ($data['medicacoes_dispensadas']['tot_madrugada'] > 0)
        {
            $data['medicacoes_dispensadas']['percen_madrugada'] = ($data['medicacoes_dispensadas']['tot_madrugada'] * 100) / $data['total_medicacoes'];
            $data['medicacoes_dispensadas']['percen_madrugada'] = round($data['medicacoes_dispensadas']['percen_madrugada'], 2);
        }
        if ($data['medicacoes_dispensadas']['tot_manha'] > 0)
        {
            $data['medicacoes_dispensadas']['percen_manha'] = ($data['medicacoes_dispensadas']['tot_manha'] * 100) / $data['total_medicacoes'];
            $data['medicacoes_dispensadas']['percen_manha'] = round($data['medicacoes_dispensadas']['percen_manha'], 2);
        }
        if ($data['medicacoes_dispensadas']['tot_tarde'] > 0)
        {
            $data['medicacoes_dispensadas']['percen_tarde'] = ($data['medicacoes_dispensadas']['tot_tarde'] * 100) / $data['total_medicacoes'];
            $data['medicacoes_dispensadas']['percen_tarde'] = round($data['medicacoes_dispensadas']['percen_tarde'], 2);
        }
        if ($data['medicacoes_dispensadas']['tot_noite'] > 0)
        {
            $data['medicacoes_dispensadas']['percen_noite'] = ($data['medicacoes_dispensadas']['tot_noite'] * 100) / $data['total_medicacoes'];
            $data['medicacoes_dispensadas']['percen_noite'] = round($data['medicacoes_dispensadas']['percen_noite'], 2);
        }


        return $data;
    }

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['hospitalization_id'], 'Hospitalizations'));
        return $rules;
    }
}
