<?php

declare(strict_types=1);

class Sinistro2_Service_Buscahonorarios
{

    /**
     * @var bool
     */
    private $isPrevia;
    
    /**
     * @var Sinistro2_Model_CobrancaPreviaEssor|Sinistro2_Model_CobrancaPreliminarFinalEssor
     */
    private $modelLaudo;

    public function __construct(bool $isPrevia)
    {
        $this->isPrevia = $isPrevia;

        if (!$this->isPrevia) {
            $this->modelLaudo = new Sinistro2_Model_CobrancaPreliminarFinalEssor();
        } else {
            $this->modelLaudo = new Sinistro2_Model_CobrancaPreviaEssor();
        }
    }

    //order o array de vistorias pelo id de vistoria ou id da proposta
	private static function custom_sort($value1, $value2) {
		if ($value1['id_proposta'] == $value2['id_proposta']) {
			return $value1['id'] > $value2['id'];
		}

		return $value1['id_proposta'] > $value2['id_proposta'];
	}

    public function getItensVariedade($dados){
		return $this->modelLaudo->getItensVariedade($dados['id_vistoria'], $dados['ds_safra']);
	}

	public function getItensAreaTotal($dados){
		return $this->modelLaudo->getAreaTotalVistoriada($dados['id_vistoria'], $dados['ds_safra']);
	}

    private function validacaoCobrancaHonorarios($dadosHonorario) : array
    {
        if (empty($dadosHonorario)) {
            return [];
        }

        $coberturasQualidade = [
            'COB_QUALIDADE',
            'COB_QUALIDADE_I',
            'COB_QUALIDADE_II',
            'COB_QUALIDADE_CEV',
            'COB_QUALIDADEII_CEV',
        ];

        $temCoberturaQualidade = false;
        $indiceCoberturaQualidade = null;
        $indicesCoberturaQualidade = [];

        foreach ($dadosHonorario as $processo => $dadosValidacao) {
            if (count($dadosValidacao['ds_chave_cobertura']) <= 1) {
                continue;
            }

            $tipoVistoria = array_filter($dadosValidacao['tp_vistoria'], function($tipo, $chave) use (&$dadosValidacao) {
                if ($tipo !== 'Preliminar') {
                    unset($dadosValidacao['tp_vistoria'][$chave]);
                    unset($dadosValidacao['ds_chave_cobertura'][$chave]);
                    unset($dadosValidacao['dt_vistoria'][$chave]);

                    return false;
                }

                return true;
            }, ARRAY_FILTER_USE_BOTH);

            if (count($tipoVistoria) <= 1) {
                continue;
            }

            foreach ($dadosValidacao['ds_chave_cobertura'] as $indice => $cobertura) {
                if (in_array($cobertura, $coberturasQualidade) && $tipoVistoria[$indice] === 'Preliminar') {
                    $temCoberturaQualidade = true;
                    $indiceCoberturaQualidade = $indice;

                    break;
                }
            }

            if ($temCoberturaQualidade) {
                $datas = array_map(function($data) {
                    return Agro_Util::formatDate($data, Zend_Date::DATES);
                }, $dadosValidacao['dt_vistoria']);

                $dataMenor = array_reduce($datas, function($dataControle, $data) {
                    if (empty($dataControle)) {
                        $dataControle = $data;
                    } elseif (Agro_Util::validaDataInicioFim($data, $dataControle)) {
                        $dataControle = $data;
                    }

                    return $dataControle;
                });

                $dataMaior = array_reduce($datas, function($dataControle, $data) {
                    if (empty($dataControle)) {
                        $dataControle = $data;
                    } elseif (Agro_Util::validaDataInicioFim($dataControle, $data)) {
                        $dataControle = $data;
                    }

                    return $dataControle;
                });

                $dias = Agro_Util::contarDiasEntreDatas($dataMenor, $dataMaior);

                if ($dias >= 0 && $dias <= 4) {
                    $indicesCoberturaQualidade[] = $indiceCoberturaQualidade;
                }
            }
        }

        return $indicesCoberturaQualidade;
    }

    public function buscaHonorarios(array $dadosVistorias)
    {
        /**
         * Tarefa: 2209091609
         * Período de corte alinhado para que seja possível gerar cobrança para vistorias que não tenham aviso vinculado,
         * evitando cobranças manuais.
         */
        $periodoPermissaoCobrancaVistoriaSemAviso = '2023-01';

		if ($dadosVistorias) {
            $arIds = $dados = [];
            $i = 0;

            /*
             * Controle para casos em que há mais de um aviso vinculado a mesma vistoria.
             */
            $controleVistorias = [];
			
			usort($dadosVistorias, 'self::custom_sort');

            foreach ($dadosVistorias as $vist) {
                array_push($arIds, $vist['id']);
            }
			
			$q = (new Sistema_Model_Vistorias())->getSelectDadosGerarRelatorio([], $this->isPrevia, $arIds);
			
            $arVistorias = $this->modelLaudo->buscaDados($q);
			
			foreach ($arVistorias as $vistoria) {
                if (in_array($vistoria['id_vistoria'], $controleVistorias)) {
                    continue;
                }

                if(
					($vistoria['tp_vistoria'] != 'Previa')
					&& empty($vistoria['id_aviso'])
					&& $periodoPermissaoCobrancaVistoriaSemAviso > Agro_Util::formatDate($vistoria['dt_vistoria'], 'YYYY-MM')
				) {
                    unset($dados[$i]);
                    continue;
                }
                
				$dados[$i] = $this->preparaDados($vistoria);
                $i++;
                $controleVistorias[] = $vistoria['id_vistoria'];
			}
            
			$dadosHonorario = [];
			$notaHonorarios = 0;
			
			//validações
			foreach($dados as $key => $value){
			    $idProcesso = $dados[$key]['id_processo'];

			    if (in_array($dados[$key]['id_produto_geral'], [15, 16])) {
                    if (!isset($dadosHonorario[$idProcesso]['dt_vistoria'])) {
                        $dadosHonorario[$idProcesso]['dt_vistoria'] = [];
                    }

                    if (!isset($dadosHonorario[$idProcesso]['ds_chave_cobertura'])) {
                        $dadosHonorario[$idProcesso]['ds_chave_cobertura'] = [];
                    }

                    $dadosHonorario[$idProcesso]['dt_vistoria'][$key] = $dados[$key]['dt_vistoria'];
                    $dadosHonorario[$idProcesso]['ds_chave_cobertura'][$key] = $dados[$key]['ds_chave_cobertura'];
                    $dadosHonorario[$idProcesso]['tp_vistoria'][$key] = $dados[$key]['tp_vistoria'];
                }

				foreach($dados as $chave => $valor){
					$data1 = substr($dados[$key]['dt_vistoria'], 0, 10);
					$data2 = substr($valor['dt_vistoria'], 0, 10);
		
					//verifica sempre a próxima vistoria
					if($chave-1 == $key) {

						//desconsidera vistoria já validada
						if(!$validado[$key]){
                            //se a vistoria é Preliminar, e o mesmo perito fez uma vistoria Final da mesma proposta
                            //dentro de 4 dias, cobrar apenas a Final e desativar preliminar
                            if(
                              $dados[$key]['id_proposta'] == $valor['id_proposta']
                              && $dados[$key]['id_vistoria'] != $valor['id_vistoria']
                              && $dados[$key]['id_cobertura'] == $valor['id_cobertura']
                              && $dados[$key]['idTipoVistoria'] != $valor['idTipoVistoria']
                              && $dados[$key]['tp_vistoria'] === 'Preliminar'
                              && Agro_Util::contarDiasEntreDatas($data1, $data2) <= 4
                              && Agro_Util::contarDiasEntreDatas($data1, $data2) >= -4
                            ) {
                                $dados[$key]['vl_honorarios'] = 0;
                                $dados[$key]['vistoriaHonorarios'] = 0;
                            }

							//marca a vistoria já validada
							$validado[$key] = true;
						}
					}
				}

				//total de honorários na nota
				$notaHonorarios += $dados[$key]['vistoriaHonorarios'];
			}

            $indicesHonorarioZerado = $this->validacaoCobrancaHonorarios($dadosHonorario);

			foreach ($indicesHonorarioZerado as $indiceHonorarioZerado) {
                $dados[$indiceHonorarioZerado]['vistoriaHonorarios'] = 0.00;
				$valorHonorario = $dados[$indiceHonorarioZerado]['vistoriaHonorarios'];
				$notaHonorarios -= $valorHonorario;
            }
			
			$retorno['dados'] = $dados;
			$retorno['notaHonorarios'] = $notaHonorarios;
		}

		return $retorno;
    }

    public function preparaDados($dados, $semValor = true){
		//tipo da vistoria
		$dados['idTipoVistoria'] = $this->modelLaudo->getTipoVistoria($dados['tp_vistoria']);
        
		//busca o grupo de vistoria
		$grupoVistoria = $this->modelLaudo->getGrupoVistoria(
		  $dados['id_cultura'],
          Agro_Util::formatDate($dados['dt_vistoria'], Zend_Date::DATES),
          $dados['ds_chave_cobertura'],
          $dados['ds_nome_cultura'],
          $dados['id_estado'],
          181,
          $dados['id_tipo_produto']
        );
        
		if($dados['idTipoVistoria'] == 3){//prévia
			$temPreliminar = false;
            
			//área total dos ítens vistoriados
			$dados['itensAreaTotal'] = $this->getItensAreaTotal($dados);
            
			//variedades e itens
			$itensVariedades = $this->getItensVariedade($dados);
			$dados['itens'] = $itensVariedades['itens'];
			$dados['variedade'] = $itensVariedades['variedade'];

		}else{//preliminar ou final
			//área total dos ítens vistoriados
			$dados['itensAreaTotal'] = ($dados['vl_area_vistoriada'] ? $dados['vl_area_vistoriada'] : 0);
		}

		//valor total dos honorarios da vistoria
		$dados['grupoVistoria'] = $grupoVistoria;

		
		if(!$dados['vistoriaHonorarios'] && $semValor){

			$valorVistoria = $this->modelLaudo->getValorVistoria($dados);

			//se a flag de multiplicar é true, multiplica o total da área pelo valor da vistoria
			if($valorVistoria['fl_multiplica_area'] === true){
				if ($valorVistoria['vl_total_maximo'] && ($dados['itensAreaTotal'] * $valorVistoria['vl_custo_vistoria']) > $valorVistoria['vl_total_maximo']) {
					$dados['vistoriaHonorarios'] = $valorVistoria['vl_total_maximo'];
				} else {
					$dados['vistoriaHonorarios'] = ($dados['itensAreaTotal'] * $valorVistoria['vl_custo_vistoria']);
				}
			}else{
				if($dados['evento_nao_constatado']){ //pega a area total qndo o evento não é constatado.
					$dados['itensAreaTotal'] = $this->modelLaudo->getAreaTotalVistoriada($dados['id_proposta']); 
					$valorVistoria = $this->modelLaudo->getValorVistoria($dados);
					$dados['vistoriaHonorarios'] = $valorVistoria['vl_custo_vistoria'];
					$dados['itensAreaTotal'] = 0;
				}else{
					$dados['vistoriaHonorarios'] = $valorVistoria['vl_custo_vistoria'];
				}
			}
		}

        if (
            get_class($this->modelLaudo) != 'Sinistro2_Model_CobrancaPreviaEssor'
            && $this->modelLaudo->existeTalhaoDispensado($dados['id_vistoria']) > 0
            && $dados['vistoriaHonorarios'] <= 0
        ) {
            $dados['vistoriaHonorarios'] = 150;

            if (strtotime($dados['dt_vistoria']) >= strtotime('2017-11-15') && strtotime($dados['dt_vistoria']) <= strtotime('2021-06-30')) {
                $dados['vistoriaHonorarios'] = 190;
            }

            if (strtotime($dados['dt_vistoria']) >= strtotime('2021-07-01') && strtotime($dados['dt_vistoria']) <= strtotime('2024-03-11')) {
                $dados['vistoriaHonorarios'] = 200;
            }

            if (strtotime($dados['dt_vistoria']) >= strtotime('2024-03-12') && strtotime($dados['dt_vistoria']) <= strtotime('2025-05-31')) {
                $dados['vistoriaHonorarios'] = 210;
            }

            if (strtotime($dados['dt_vistoria']) >= strtotime('2025-05-31') && strtotime($dados['dt_vistoria']) <= strtotime('2026-08-31')) {
                $dados['vistoriaHonorarios'] = 222;
            }

            if (strtotime($dados['dt_vistoria']) >= strtotime('2026-09-01')) {
                $dados['vistoriaHonorarios'] = 232;
            }
        }

		//dados do grupo utilizados para validação no JS (id, valores máximos de hospedagem e refeição)
		$dados['grupoVistoria'] = $grupoVistoria;
		$dados['dt_laudo_order'] = Agro_Util::formatDate($dados['dt_laudo_order'], Zend_Date::DATES);

		return $dados;
	}
}

?>