<?php
namespace App\Model\Table;

use App\Model\Entity\StrengthAssessmentScale;
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";

/**
 * StrengthAssessmentScales Model
 *
 * @property \Cake\ORM\Association\BelongsTo $Hospitalizations
 */
class StrengthAssessmentScalesTable extends Table
{

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

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

        $this->addBehavior('Timestamp');

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

        $this->belongsTo('Sectors', [
            'foreignKey' => 'sector_id',
            'joinType' => 'INNER',
        ]);
    }

    /**
     * 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
            ->integer('abducao_do_ombro_d')
            ->allowEmpty('abducao_do_ombro_d');

        $validator
            ->integer('abducao_do_ombro_e')
            ->allowEmpty('abducao_do_ombro_e');

        $validator
            ->integer('flexao_do_cotovelo_d')
            ->allowEmpty('flexao_do_cotovelo_d');

        $validator
            ->integer('flexao_do_cotovelo_e')
            ->allowEmpty('flexao_do_cotovelo_e');

        $validator
            ->integer('extensao_do_punho_d')
            ->allowEmpty('extensao_do_punho_d');

        $validator
            ->integer('extensao_do_punho_e')
            ->allowEmpty('extensao_do_punho_e');

        $validator
            ->integer('dorsiflexao_do_tornozelo_e')
            ->allowEmpty('dorsiflexao_do_tornozelo_e');

        $validator
            ->integer('flexao_do_quadril_d')
            ->allowEmpty('flexao_do_quadril_d');

        $validator
            ->integer('flexao_do_quadril_e')
            ->allowEmpty('flexao_do_quadril_e');

        $validator
            ->integer('extensao_do_joelho_d')
            ->allowEmpty('extensao_do_joelho_d');

        $validator
            ->integer('extensao_do_joelho_e')
            ->allowEmpty('extensao_do_joelho_e');

        $validator
            ->integer('dorsiflexao_do_tornozelo_d')
            ->allowEmpty('dorsiflexao_do_tornozelo_d');

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

        $validator
            ->integer('pontuation')
            ->allowEmpty('pontuation');

        return $validator;
    }

    public function getRelatorioData($hospitalizations, $sectors, $date_before, $date_after)
    {
        $calc_obj = new MedidasDispersao();

        $data =
            [
            'strength_assessment_scales' => [],
            'arr_indice_mrc' => [],
            'media_indice_mrc' => 0,
            'variacao_indice_mrc' => 0,
            'tipo_internacao' => [],
            'total_de_registros' => 0,
            'pontuation' => [
                '10' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '20' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '30' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '40' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '50' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '60' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '70' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '80' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '90' => ['arr' => [], 'tot' => 0, 'media' => 0],
                '100' => ['arr' => [], 'tot' => 0, 'media' => 0],
            ],

            'pacientes_queda_mrc' => [
                'arr' => [],
                'tot' => 0,
            ],

            'pacientes_mrc_menor_30' => [
                'arr' => [],
                'media' => 0,
                'tot' => 0,
            ],

            'pacientes' => [
                'arr' => [],
                'tot' => 0,
            ],

            'setores' => [

            ],

            'clinica' => [
                'arr_pacientes' => [],
                'tot_pacientes' => 0,
                'arr_indice_mrc' => [],
                'media_indice_mrc' => 0,
                'variacao_indice_mrc' => 0,

                'arr_paciente_queda_mrc' => [],
                'tot_paciente_queda_mrc' => 0,
                'percen_paciente_queda_mrc' => 0,

                'arr_queda_mrc' => [],
                'media_queda_mrc' => 0, //valor médio e percentual de queda do valor do MRC comparando a internação e o valor mais baixo avaliado
                'percen_queda_mrc' => 0,

                'arr_paciente_mrc_menor_30' => [],
                'tot_paciente_mrc_menor_30' => 0,
                'percen_paciente_mrc_menor_30' => 0,

                'diagnosticos' => [
                ],

                'pontuation' => [
                    '10' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '20' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '30' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '40' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '50' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '60' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '70' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '80' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '90' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '100' => ['arr' => [], 'tot' => 0, 'media' => 0],
                ],
            ],

            'cirurgica' => [
                'arr_pacientes' => [],
                'tot_pacientes' => 0,
                'arr_indice_mrc' => [],
                'media_indice_mrc' => 0,
                'variacao_indice_mrc' => 0,

                'arr_paciente_queda_mrc' => [],
                'tot_paciente_queda_mrc' => 0,
                'percen_paciente_queda_mrc' => 0,

                'arr_queda_mrc' => [],
                'media_queda_mrc' => 0,
                'percen_queda_mrc' => 0,

                'arr_paciente_mrc_menor_30' => [],
                'tot_paciente_mrc_menor_30' => 0,
                'percen_paciente_mrc_menor_30' => 0,

                'diagnosticos' => [
                ],

                'pontuation' => [
                    '10' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '20' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '30' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '40' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '50' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '60' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '70' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '80' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '90' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '100' => ['arr' => [], 'tot' => 0, 'media' => 0],
                ],
            ],
        ];

        //pega o nome dos setores
        foreach ($sectors as $sector)
        {
            $id = $sector['id'];
            $data['setores'][$id] = [
                'name' => $sector['name'],
                'arr_mrc' => [],
                'media_mrc' => 0,
                'variacao_mrc' => 0,
                'pontuation' => [
                    '10' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '20' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '30' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '40' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '50' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '60' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '70' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '80' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '90' => ['arr' => [], 'tot' => 0, 'media' => 0],
                    '100' => ['arr' => [], 'tot' => 0, 'media' => 0],
                ],
            ];
        }

        //pega os diagnósticos principais
        $diagnostics = [];
        foreach ($hospitalizations as $hospitalization)
        {
            foreach ($hospitalization["diagnostics"] as $diagnostic)
            {
                if (isset($diagnostics[$diagnostic['description']]))
                {
                    $diagnostics[$diagnostic['description']]++;
                }
                else
                {
                    $diagnostics[$diagnostic['description']] = 1;
                }
            }
        }
        //pega os 5 principais diagnosticos
        arsort($diagnostics);
        $diagnostics_keys = array_keys($diagnostics);
        $max_count_diag = 0;
        foreach ($diagnostics_keys as $diag_key => $diag_value)
        {
            if ($max_count_diag == 5)
            {
                break;
            }

            $diag = [
                'ordem' => $diag_key,
                'name' => $diag_value,
                'arr_pacientes_queda_mrc' => [],
                'tot_pacientes_queda_mrc' => 0,
                'percentual' => 0,
            ];
            array_push($data['cirurgica']['diagnosticos'], $diag);
            array_push($data['clinica']['diagnosticos'], $diag);

            $max_count_diag++;
        }

        foreach ($hospitalizations as $hospitalization)
        {
            $maior_val_mrc = 0;
            $menor_val_mrc = 61;

            $last_mrc = 0; //valores do mrc na internacao
            $tipo_internacao = null;
            $houve_queda_de_mrc = false;

            if (stripos($hospitalization['type'], 'clínic') !== false)
            {
                $tipo_internacao = 'clinica';

                if (!in_array($hospitalization->id, $data[$tipo_internacao]['arr_pacientes']))
                {
                    array_push($data[$tipo_internacao]['arr_pacientes'], $hospitalization->id);
                    $data[$tipo_internacao]['tot_pacientes']++;
                }
            }
            else if (stripos($hospitalization['type'], 'cirúr') !== false)
            {
                $tipo_internacao = 'cirurgica';
                if (!in_array($hospitalization->id, $data[$tipo_internacao]['arr_pacientes']))
                {
                    array_push($data[$tipo_internacao]['arr_pacientes'], $hospitalization->id);
                    $data[$tipo_internacao]['tot_pacientes']++;
                }
            }
            array_push($data['tipo_internacao'], $tipo_internacao);

            foreach ($hospitalization["strength_assessment_scales"] as $key_1 => $neonatal)
            {
                //verifica se o registro esta dentro do periodo
                if ($neonatal['created'] < $date_before ||
                    $neonatal['created'] > $date_after
                )
                {
                    continue;
                }

                array_push($data['strength_assessment_scales'], $neonatal);
                if (!in_array($hospitalization->id, $data['pacientes']['arr']))
                {
                    array_push($data['pacientes']['arr'], $hospitalization->id);
                    $data['pacientes']['tot']++;
                }

                if ($neonatal['pontuation'])
                {
                    $pontuation = 10;

                    //verifica se houve queda de MRC durante a interção
                    if ($neonatal['pontuation'] < $last_mrc)
                    {
                        if (!in_array($hospitalization->id, $data[$tipo_internacao]['arr_paciente_queda_mrc']))
                        {
                            array_push($data[$tipo_internacao]['arr_paciente_queda_mrc'], $hospitalization->id);
                            $data[$tipo_internacao]['tot_paciente_queda_mrc']++;
                        }

                        if ($neonatal['pontuation'] > $maior_val_mrc)
                        {
                            $maior_val_mrc = $neonatal['pontuation'];
                        }

                        if ($neonatal['pontuation'] < $menor_val_mrc)
                        {
                            $menor_val_mrc = $neonatal['pontuation'];
                        }

                        //$diferenca_queda = $last_mrc - $neonatal['pontuation'] ;
                        //array_push($data[$tipo_internacao]['arr_queda_mrc'], $diferenca_queda);

                        //calcula os pacientes com queda de mrc por diagnosticos
                        foreach ($hospitalization["diagnostics"] as $diagnostic)
                        {
                            $diag_name = $diagnostic['description'];

                            foreach ($data[$tipo_internacao]['diagnosticos'] as $diag_key => $diagnostic)
                            {
                                if ($diagnostic['name'] === $diag_name)
                                {
                                    if (!in_array($hospitalization->id, $data[$tipo_internacao]['diagnosticos'][$diag_key]['arr_pacientes_queda_mrc']))
                                    {
                                        array_push($data[$tipo_internacao]['diagnosticos'][$diag_key]['arr_pacientes_queda_mrc'], $hospitalization->id);
                                        $data[$tipo_internacao]['diagnosticos'][$diag_key]['tot_pacientes_queda_mrc']++;
                                    }
                                }
                            }
                        }
                    }

                    $last_mrc = $neonatal['pontuation'];

                    if ($neonatal['pontuation'] <= 20)
                    {
                        $pontuation = 20;
                    }
                    else if ($neonatal['pontuation'] <= 30)
                    {
                        $pontuation = 30;
                    }
                    else if ($neonatal['pontuation'] <= 40)
                    {
                        $pontuation = 40;
                    }
                    else if ($neonatal['pontuation'] <= 50)
                    {
                        $pontuation = 50;
                    }
                    else if ($neonatal['pontuation'] <= 60)
                    {
                        $pontuation = 60;
                    }
                    else if ($neonatal['pontuation'] <= 70)
                    {
                        $pontuation = 70;
                    }
                    else if ($neonatal['pontuation'] <= 80)
                    {
                        $pontuation = 80;
                    }
                    else if ($neonatal['pontuation'] <= 90)
                    {
                        $pontuation = 90;
                    }
                    else if ($neonatal['pontuation'] <= 100)
                    {
                        $pontuation = 100;
                    }

                    if ($pontuation == 30 &&
                        !in_array($hospitalization->id, $data['pacientes_mrc_menor_30']['arr']))
                    {
                        array_push($data['pacientes_mrc_menor_30']['arr'], $hospitalization->id);
                        $data['pacientes_mrc_menor_30']['tot']++;
                    }

                    //calcula o mrc baseado no setor
                    if ($neonatal['sector_id'])
                    {
                        array_push($data['setores'][$neonatal['sector_id']]['arr_mrc'], $neonatal['pontuation']);
                        array_push($data['setores'][$neonatal['sector_id']]['pontuation'][$pontuation]['arr'], $neonatal['pontuation']);
                        $data['setores'][$neonatal['sector_id']]['pontuation'][$pontuation]['tot']++;
                    }

                    //faz o cálcudo separando pelo tipo de internação
                    if ($tipo_internacao)
                    {
                        array_push($data[$tipo_internacao]['arr_indice_mrc'], $neonatal['pontuation']);

                        if ($pontuation <= 30 &&
                            !in_array($hospitalization->id, $data[$tipo_internacao]['arr_paciente_mrc_menor_30']))
                        {
                            array_push($data[$tipo_internacao]['arr_paciente_mrc_menor_30'], $hospitalization->id);
                            $data[$tipo_internacao]['tot_paciente_mrc_menor_30']++;
                        }
                    }

                    array_push($data['arr_indice_mrc'], $neonatal['pontuation']);

                    array_push($data['pontuation'][$pontuation]['arr'], $neonatal['pontuation']);
                    $data['pontuation'][$pontuation]['tot']++;
                }

                $neonatal_arr = (array) $neonatal;
                $i = 0;

                $data['total_de_registros']++;

                foreach ($neonatal_arr as $key_2 => $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);
                        }
                    }
                }
            }

            if ($menor_val_mrc < 61)
            {
                $diferenca_queda = $maior_val_mrc - $menor_val_mrc;
            }
            else
            {
                $diferenca_queda = $maior_val_mrc - 0;
            }
            if ($tipo_internacao)
            {
                array_push($data[$tipo_internacao]['arr_queda_mrc'], $diferenca_queda);
            }
        }

        foreach ($data as $key => $value)
        {
            if (isset($data[$key]['percentual']) &&
                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++;
                    }
                }

                $data[$key]['total'] = count($data[$key]['arr']);
                $data[$key]['percentual'] = $calc_obj->calculate_percentage($marcados, $data['total_de_registros']);
                $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']);
                $data[$key]['variacao'] = $calc_obj->calc_variance($data[$key]['arr']);
            }
        }

        //calcula o percentual de pacientes com queda de mrc baseado no diagnostico
        foreach ($data['clinica']['diagnosticos'] as $diag_key => $diagnostico)
        {
            if (count($diagnostico['arr_pacientes_queda_mrc']) > 0)
            {
                $tot_pac_queda = count($diagnostico['arr_pacientes_queda_mrc']);
                $tot_pac_clinico_queda = $data['clinica']['tot_paciente_queda_mrc'];

                $data['clinica']['diagnosticos'][$diag_key]['percentual'] = $calc_obj->calculate_percentage($tot_pac_queda, $tot_pac_clinico_queda);
            }
        }

        foreach ($data['cirurgica']['diagnosticos'] as $diag_key => $diagnostico)
        {
            if (count($diagnostico['arr_pacientes_queda_mrc']) > 0)
            {
                $tot_pac_queda = count($diagnostico['arr_pacientes_queda_mrc']);
                $tot_pac_clinico_queda = $data['cirurgica']['tot_paciente_queda_mrc'];

                $data['cirurgica']['diagnosticos'][$diag_key]['percentual'] = $calc_obj->calculate_percentage($tot_pac_queda, $tot_pac_clinico_queda);
            }
        }

        //calcula os dados do setor
        foreach ($data['setores'] as $sector_key => $sector)
        {
            if (count($sector['arr_mrc']) > 0)
            {
                $data['setores'][$sector_key]['media_mrc'] = $calc_obj->calc_average($sector['arr_mrc']);
                $data['setores'][$sector_key]['variacao_mrc'] = $calc_obj->calc_variance($sector['arr_mrc']);
            }
        }

        //calcula a distrubuicao do mrc por dezena
        foreach ($data['cirurgica']['pontuation'] as $pt_key => $pontuation)
        {
            if (count($pontuation['arr']) > 0)
            {
                $data['cirurgica']['pontuation'][$pt_key] = $calc_obj->calc_average($pontuation['arr']);
            }
        }

        foreach ($data['clinica']['pontuation'] as $pt_key => $pontuation)
        {
            if (count($pontuation['arr']) > 0)
            {
                $data['clinica']['pontuation'][$pt_key] = $calc_obj->calc_average($pontuation['arr']);
            }
        }

        if ($data['pacientes_mrc_menor_30']['tot'] > 0)
        {
            $data['pacientes_mrc_menor_30']['media'] = $data['pacientes_mrc_menor_30']['tot'] / $data['pacientes']['tot'];
            $data['pacientes_mrc_menor_30']['media'] = round($data['pacientes_mrc_menor_30']['media'], 2);
        }

        if (count($data['arr_indice_mrc']) > 0)
        {
            $data['media_indice_mrc'] = $calc_obj->calc_average($data['arr_indice_mrc']);
            $data['variacao_indice_mrc'] = $calc_obj->calc_variance($data['arr_indice_mrc']);
        }

        if (count($data['clinica']['arr_indice_mrc']) > 0)
        {
            $data['clinica']['media_indice_mrc'] = $calc_obj->calc_average($data['clinica']['arr_indice_mrc']);
            $data['clinica']['variacao_indice_mrc'] = $calc_obj->calc_variance($data['clinica']['arr_indice_mrc']);
        }

        if (count($data['cirurgica']['arr_indice_mrc']) > 0)
        {
            $data['cirurgica']['media_indice_mrc'] = $calc_obj->calc_average($data['cirurgica']['arr_indice_mrc']);
            $data['cirurgica']['variacao_indice_mrc'] = $calc_obj->calc_variance($data['cirurgica']['arr_indice_mrc']);
        }

        if ($data['clinica']['tot_paciente_mrc_menor_30'] > 0)
        {
            $data['clinica']['percen_paciente_mrc_menor_30'] = ($data['clinica']['tot_paciente_mrc_menor_30'] * 100) / $data['clinica']['tot_pacientes'];
            $data['clinica']['percen_paciente_mrc_menor_30'] = round($data['clinica']['percen_paciente_mrc_menor_30'], 2);
        }

        if ($data['cirurgica']['tot_paciente_mrc_menor_30'] > 0)
        {
            $data['cirurgica']['percen_paciente_mrc_menor_30'] = ($data['cirurgica']['tot_paciente_mrc_menor_30'] * 100) / $data['cirurgica']['tot_pacientes'];
            $data['cirurgica']['percen_paciente_mrc_menor_30'] = round($data['cirurgica']['percen_paciente_mrc_menor_30'], 2);
        }

        if (count($data['cirurgica']['arr_queda_mrc'] > 0))
        {
            $data['cirurgica']['media_queda_mrc'] = $calc_obj->calc_average($data['cirurgica']['arr_queda_mrc']);

            if (count($data['cirurgica']['arr_indice_mrc']) > 0)
            {
                $maior_mrc_no_periodo = max($data['cirurgica']['arr_indice_mrc']);
                $data['cirurgica']['percen_queda_mrc'] = ($data['cirurgica']['media_queda_mrc'] * 100) / $maior_mrc_no_periodo;
                $data['cirurgica']['percen_queda_mrc'] = round($data['cirurgica']['percen_queda_mrc'], 2);
            }
        }

        if (count($data['clinica']['arr_queda_mrc'] > 0))
        {
            $data['clinica']['media_queda_mrc'] = $calc_obj->calc_average($data['clinica']['arr_queda_mrc']);

            if (count($data['clinica']['arr_indice_mrc']) > 0)
            {
                $maior_mrc_no_periodo = max($data['clinica']['arr_indice_mrc']);
                $data['clinica']['percen_queda_mrc'] = ($data['clinica']['media_queda_mrc'] * 100) / $maior_mrc_no_periodo;
                $data['clinica']['percen_queda_mrc'] = round($data['clinica']['percen_queda_mrc'], 2);
            }
        }

        if ($data['clinica']['tot_paciente_queda_mrc'] > 0 && $data['clinica']['tot_pacientes'] > 0)
        {
            $data['clinica']['percen_paciente_queda_mrc'] = ($data['clinica']['tot_paciente_queda_mrc'] * 100) / $data['clinica']['tot_pacientes'];
            $data['clinica']['percen_paciente_queda_mrc'] = round($data['clinica']['percen_paciente_queda_mrc'], 2);
        }

        if ($data['cirurgica']['tot_paciente_queda_mrc'] > 0 && $data['cirurgica']['tot_pacientes'] > 0)
        {
            $data['cirurgica']['percen_paciente_queda_mrc'] = ($data['cirurgica']['tot_paciente_queda_mrc'] * 100) / $data['cirurgica']['tot_pacientes'];
            $data['cirurgica']['percen_paciente_queda_mrc'] = round($data['cirurgica']['percen_paciente_queda_mrc'], 2);
        }

        // '' => [],
        //         'tot_queda_mrc' => 0,
        //         'percen_queda_mrc' => 0,

        $data['diagnosticos'] = $diagnostics;

        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;
    }
}
