<?php

declare(strict_types=1);

class Sinistro2_Service_Buscadespesasvistoria
{
    public function busca(int $idVistoria, int $idProposta, string $tipoVistoria): array
    {
        $modelVistoriadorDespesa = new Sinistro2_Model_VistoriadorDespesa();
        $modelCombustivel = new Sinistro2_Model_CobrancaValorCombustivel();

		$idProposta = (new Seguro_Model_Propostas())->getPropostasVigentes([$idProposta])[0]['id_proposta'];

        // Busca peritos da vistoria e os peritos envolvidos
        $rs = $modelVistoriadorDespesa->getVistoria($idVistoria, $tipoVistoria);
        
        $dataVistoriaSelecionada = $rs->current()['dt_vistoria'];
		$idEstadoVistoria = $rs->current()['id_estado'];
		$idsPeritos = [];
		
		$dateTimeVistoria = DateTime::createFromFormat('Y-m-d H:i:s', $dataVistoriaSelecionada);
		
		foreach ($rs as $row) {
			$idsPeritos[] = $row['id_funcionario'];
		}
		
		// Mapeia id_funcionario com suas respectivas despesas
		$mapIdPeritoDespesas = $this->getDespesasVistoria(
			$idProposta,
			$idsPeritos,
			$idEstadoVistoria,
			$dateTimeVistoria
		);
		
        /**
         * Busca outras vistorias realizadas na mesma data a fim de identificar se a vistoria selecionada é a primeira do dia.
         * */
        $rsVistoriasMesmaData = $modelVistoriadorDespesa->getVistoriasByDataPeritos(
			$idProposta,
			$dateTimeVistoria,
			$idsPeritos,
			$tipoVistoria,
			$idEstadoVistoria
		);
        
        $aux = $despesasVistoriaPorPerito = [];

		$tiposDespesa = (new Sinistro2_Model_TipoDespesa())->fetchAll();
		
		$totalDespesasCombustivel = $totalDespesas = 0;
		
        // Vincula despesas dos funcionários a vistoria
		foreach ($rsVistoriasMesmaData as $vistoria) {
			$idPerito = $vistoria['id_funcionario'];
			
			// Considera apenas primeira vistoria do perito (primeira realizada no dia)
			if (!empty($aux[$idPerito])) {
				continue;
			}
			
			// Se a primeira vistoria do dia realizada pelo perito for igual a vistoria selecionada, vincula despesas a vistoria
			if ($vistoria['id_vistoria'] == $idVistoria && !empty($mapIdPeritoDespesas[$idPerito])) {
				$despesasPerito = [
					'id_funcionario' => $mapIdPeritoDespesas[$idPerito][0]['id_funcionario'],
					'ds_nome_funcionario' => $mapIdPeritoDespesas[$idPerito][0]['ds_nome_funcionario'],
					'total_despesas' => 0,
					'numero_arquivos' => 0
				];

				// Cria uma entrada no array para cada tipo de despesa
				foreach ($tiposDespesa as $tipoDespesa) {
					$despesasPerito[$tipoDespesa['id']] = ['vl_despesa' => 0, 'ds_unidade' => $tipoDespesa['ds_unidade']];
				}
				
				// Soma os valores por tipo de despesa
				foreach ($mapIdPeritoDespesas[$idPerito] as $despesa) {
					$despesasPerito['numero_arquivos'] += $despesa['numero_arquivos'];

					$despesasPerito[$despesa['id_tipo_despesa']]['vl_despesa'] += $despesa['vl_despesa'];
					$despesasPerito['ids_vistoriadores_despesas'] .= !empty($despesasPerito['ids_vistoriadores_despesas'])
						? ',' . $despesa['id_vistoriador_despesa']
						: $despesa['id_vistoriador_despesa'];

					if ($despesa['id_tipo_despesa'] != Sinistro2_Model_TipoDespesa::TIPO_DESPESA_KM) {
						$despesasPerito['total_despesas'] += $despesa['vl_despesa'];
					}
				}
				
				// Calcula gasto combustível
				if (!empty($despesasPerito[Sinistro2_Model_TipoDespesa::TIPO_DESPESA_KM])) {
					$rsPrecoCombustivel = $modelCombustivel->getValorCombustivelByProposta($idProposta, $vistoria['dt_vistoria']);
					$precoCombustivel = $rsPrecoCombustivel['valor'] ?? 0;

					if ($precoCombustivel == 0) {
						$dateTime = DateTime::createFromFormat('Y-m-d H:i:s', $vistoria['dt_vistoria']);
						throw new Exception(
							'Preço de combustível não configurado para o estado ' . $mapIdPeritoDespesas[$idPerito][0]['ds_sigla']
							. ' para a data ' . $dateTime->format('d/m/Y')
						);
					}

					$despesasPerito['gasto_combustivel'] = Sinistro2_Model_CobrancaValorCombustivel::calculaGastoCombustivel(
						$despesasPerito[Sinistro2_Model_TipoDespesa::TIPO_DESPESA_KM]['vl_despesa'],
						$precoCombustivel
					);

					$totalDespesasCombustivel += $despesasPerito['gasto_combustivel'];
				}
				
				$despesasVistoriaPorPerito[$idPerito] = $despesasPerito;
				$totalDespesas += $despesasPerito['total_despesas'] ?? 0;
			}

			$aux[$idPerito] = true;
		}
		
		$despesasVistoriaPorPerito['total_despesas'] = $totalDespesas;
		$despesasVistoriaPorPerito['total_despesas_combustivel'] = $totalDespesasCombustivel;
		
		return $despesasVistoriaPorPerito;
    }

	private function getDespesasVistoria(
		int $idProposta,
		array $idsPeritos,
		int $idEstado,
		DateTime $dateTimeVistoria
	): array {
		$modelVistoriadorDespesa = new Sinistro2_Model_VistoriadorDespesa();

        $rsDespesasPeritos = $modelVistoriadorDespesa->getDespesasPeritos($idProposta, $idsPeritos, $idEstado);
		$mapIdPeritoDespesas = [];
		
		foreach ($rsDespesasPeritos as $despesa) {
			$dateTimeDespesa = DateTime::createFromFormat('Y-m-d H:i:s', $despesa['dt_despesa']);

			if ($dateTimeDespesa->format('Y-m-d') == $dateTimeVistoria->format('Y-m-d')) {
				$mapIdPeritoDespesas[$despesa['id_funcionario']][] = $despesa;
			}
		}
		
		return $mapIdPeritoDespesas;
	}
}