<?php

class Comercializacao_TaxaController extends Agro_Controller_Action
{
	public function indexAction() {
	}

	public function relacionausuarioAction() {
		$this->getHelper('layout')->disableLayout();

		$Taxas = new Comercializacao_Model_Taxas();

		$this->view->relacionados = $Taxas->getUsuariosRelacionados($this->getRequest()->getParam('id'));
		$this->view->id = $this->getRequest()->getParam('id');
	}
	
	public function relacionataxaAction() {
		$this->isAjax();
		
		$Taxas = new Comercializacao_Model_TaxasAgrupamentoUsuarios();
		$Taxas->clearUsuarios($this->getRequest()->getParam('id'));

		try {
			if (is_array($this->getRequest()->getParam('id_usuario'))) {
				foreach ($this->getRequest()->getParam('id_usuario') as $idUser) {
					$Taxas->save($this->getRequest()->getParam('id'), $idUser);
				}
			}
			
			$result = array("status"=>true, "message"=>"Usuários relacionados com sucesso.");
			
		} catch (Exception $e) {
			$result = array("status"=>false, "message"=>"Não foi possível relacionar usuários.\n\nErro:$e->getMessage()");
			
		}
		
		$this->getResponse()->setBody(Zend_Json::encode($result));
		
	}

    public function relacionaitemtaxaorcamentoAction(): void
    {
        $this->isAjax();

        $return = [
            'mensagem' => 'Produtividade estimada vinculada com sucesso.',
            'erro' => false
        ];
        
        $parametros = $this->getRequest()->getParams();

        try {
            if (!filter_var($parametros['id_taxa_agrupamento'], FILTER_VALIDATE_INT)) {
                throw new Exception('ID taxa de agrupamento não informado.');
            }

            Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

            $model = new Comercializacao_Model_TaxaAgrupamentoOrcamentoItem();

            $model->delete($parametros['id_taxa_agrupamento'], 'id_taxa_agrupamento');
            
            foreach ($parametros['itens'] as $item) {
                $decodedJsonItem = json_decode($item);
                
                if (is_null($decodedJsonItem->produtividadeEstimada) || $decodedJsonItem->produtividadeEstimada == '') {
                    throw new Exception('É obrigatório preencher a produtividade estimada de todos os itens.');
                }
                
                $rs = $model->save([
                    'id_taxa_agrupamento' => $parametros['id_taxa_agrupamento'],
                    'id_item_segurado' => $decodedJsonItem->id,
                    'vl_produtividade_estimada' => $decodedJsonItem->produtividadeEstimada 
                ]);

                if ($rs === null) {
                    throw new Exception('Erro ao vincular produtividade estimada dos itens ao orçamento.');
                }
            }

            (new Seguro_Model_Propostas())
				->update(['fl_taxa_pe_por_item' => true], "id = {$parametros['id_proposta']}");

            Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
        } catch (Exception $e) {
            Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();

            $return['mensagem'] = $e->getMessage();
            $return['erro'] = true;
        }
        
        $this->getResponse()->setBody(Zend_Json::encode($return));
    }

    public function salvartaxaitemseguradovalortoneladaAction()
    {
        $this->isAjax();
        
        try {
            Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

            $parametros = $this->getRequest()->getParams();
            
            if (empty($parametros['id_taxa_agrupamento'])) {
                throw new Exception('ID taxa de agrupamento não informado.', 1);
            }

            if (!filter_var($parametros['id_taxa_agrupamento'], FILTER_VALIDATE_INT)) {
                throw new Exception('ID taxa de agrupamento inválido.', 1);
            }

            if (!empty($parametros['vl_tonelada']) && !filter_var($parametros['vl_tonelada'], FILTER_VALIDATE_FLOAT)) {
                throw new Exception('Valor de limite de IS inválido.', 1);
            }

            $itens = [];

            foreach($parametros['itens'] as $item) {
                $itens[] = json_decode($item, true);
            }

            (new Comercializacao_Service_SalvarValorTonelada())->executar(
                $parametros['id_taxa_agrupamento'],
                !empty($parametros['tipo_valor_is_proposta']),
                $itens,
                !empty($parametros['vl_tonelada']) ? $parametros['vl_tonelada'] : 0
            );

            Agro_Db_Table_Abstract::getDefaultAdapter()->commit();

            $return = [
                'mensagem' => 'Limite de IS salvo com sucesso.',
                'erro' => false
            ];

        } catch (Exception $e) {
            Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
            
            $mensagem = 'Erro ao salvar valor de limite de IS.';
            if ($e->getCode() == 1) {
                $mensagem = $e->getMessage();
            }

            $return = [
                'erro' => true,
                'mensagem' => $mensagem
            ];
        }

        $this->getResponse()->setBody(Zend_Json::encode($return));
    }

    public function salvartaxasagrupamentoorcamentovalorAction()
    {
        $this->isAjax();

        $parametros = $this->getRequest()->getParams();
        $parametros['ds_nome_agrupamento_taxas'] = $parametros['id_proposta'];
        $parametros['tp_taxa_agrupamento'] = Comercializacao_Model_TaxasAgrupamentos::TIPO_ORCAMENTO;

        $mensagem = "Valores salvos com sucesso.";

        Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

        try {
            $parametros = $this->salvarTaxaAgrupamentoOrcamento($parametros);

            $modelTaxasValores = new Comercializacao_Model_TaxasValores();

            if (!empty($parametros['id_taxa'])) {
                $parametros['id'] = $parametros['id_taxa'];
            }

            $idTaxasValores = $modelTaxasValores->save($parametros);
            $modelTaxasValores->relacionarTaxas($parametros, $idTaxasValores);

            Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
        } catch (Exception $exception) {
            $mensagem = 'Erro ao salvar os valores.';

            Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
        }

        $this->getResponse()->setBody(Zend_Json::encode(['mensagem' => $mensagem]));
    }

    public function migrartaxapropostaparataxaorcamentoAction()
    {
        $this->isAjax();
        $parametros = $this->getRequest()->getParams();
        $parametros['ds_nome_agrupamento_taxas'] = $parametros['id_proposta'];
        $parametros['tp_taxa_agrupamento'] = Comercializacao_Model_TaxasAgrupamentos::TIPO_ORCAMENTO;
        $parametros['fl_ativo'] = true;

        $retorno = ['erro' => false, 'mensagem' => 'Agrupamento realizado com sucesso.'];

        Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

        try {
            $modelPropostas = new Seguro_Model_Propostas();
            $rowProposta = $modelPropostas->getRow($parametros['id_proposta']);
            $taxaAgrupamento = $rowProposta->agrupamento(false);

            $parametros['vl_comissao'] = $taxaAgrupamento['vl_comissao'];
            $parametros['id_secao'] = $taxaAgrupamento['id_secao'];
            $parametros = $this->salvarTaxaAgrupamentoOrcamento($parametros);

            $modelTaxasValores = new Comercializacao_Model_TaxasValores();
            $taxaValores = $modelTaxasValores->getTaxasValoresByTaxaAgrupamento($taxaAgrupamento['id'])->toArray();
            $deParaTaxas = [];

            foreach ($taxaValores as $taxaValor) {
                $idTaxaValorAnterior = $taxaValor['id'];
                $taxaValorAtualizada = $this->removerChavesArray($taxaValor);
                $taxaValorAtualizada['id_taxa_agrupamento'] = $parametros['id_taxa_agrupamento'];
                $taxaValorAtualizada['fl_ativo'] = true;

                $idTaxaValorNovo = $modelTaxasValores->save($taxaValorAtualizada);
                $deParaTaxas[$idTaxaValorAnterior] = $idTaxaValorNovo;
            }

            /**
             * Laço para ajustar as taxas relacionadas com base nos códigos anteriores
             */
            foreach ($deParaTaxas as $idTaxaAnterior => $idTaxaNovo) {
                $taxasRelacionadas = $modelTaxasValores->getCoberturasRelacionadas($idTaxaAnterior);

                foreach ($taxasRelacionadas as $taxaRelacionada) {
                    $modelTaxasValores->relacionaTaxas(['id_taxa_relacionada' => $deParaTaxas[$taxaRelacionada]], $idTaxaNovo);
                }
            }

            $modelTaxasMunicipios = new Comercializacao_Model_TaxasAgrupamentoMunicipios();
            $rowsTaxasMunicipios = $modelTaxasMunicipios->getTaxaAgrupamento($taxaAgrupamento['id'])->toArray();

            foreach ($rowsTaxasMunicipios as $taxaMunicipio) {
                $taxaMunicipioAtualizada = $this->removerChavesArray($taxaMunicipio);
                $taxaMunicipioAtualizada['id_taxa_agrupamento'] = $parametros['id_taxa_agrupamento'];

                $modelTaxasMunicipios->save($taxaMunicipioAtualizada);
            }

            $modelTaxasUsuarios = new Comercializacao_Model_TaxasAgrupamentoUsuarios();
            $rowsTaxasUsuarios = $modelTaxasUsuarios->getTaxaAgrupamento($taxaAgrupamento['id'])->toArray();

            foreach ($rowsTaxasUsuarios as $taxaUsuario) {
                $taxaUsuarioAtualizada = $this->removerChavesArray($taxaUsuario);

                $modelTaxasUsuarios->save($parametros['id_taxa_agrupamento'], $taxaUsuarioAtualizada['id_usuario']);
            }

            $modelTaxasProponentes = new Comercializacao_Model_TaxasAgrupamentoProponente();
            $rowsTaxasProponentes = $modelTaxasProponentes->getTaxaAgrupamento($taxaAgrupamento['id'])->toArray();

            foreach ($rowsTaxasProponentes as $taxaProponente) {
                $taxaProponenteAtualizada = $this->removerChavesArray($taxaProponente);
                $taxaProponenteAtualizada['id_taxa_agrupamento'] = $parametros['id_taxa_agrupamento'];

                $modelTaxasProponentes->save($taxaProponenteAtualizada);
            }

            Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
        } catch (Exception $exception) {
            $retorno = ['erro' => true, 'mensagem' => 'Erro ao salvar os valores.'];

            Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
        }

        $this->getResponse()->setBody(Zend_Json::encode($retorno));
    }

    private function salvarTaxaAgrupamentoOrcamento(array $parametros)
    {
        $modelTaxasAgrupamentos = new Comercializacao_Model_TaxasAgrupamentos();
        $rowTaxasAgrupamento = $modelTaxasAgrupamentos->salvar($parametros);

        $rowTaxasAgrupamento->ds_nome_agrupamento_taxas = "{$parametros['id_proposta']}_{$rowTaxasAgrupamento->id}";
        $rowTaxasAgrupamento->save();

        $parametros['id_taxa_agrupamento'] = $rowTaxasAgrupamento->id;

        $modelTaxasAgrupamentosOrcamentos = new Comercializacao_Model_TaxasAgrupamentoOrcamentos();
        $modelTaxasAgrupamentosOrcamentos->save($parametros);

        return $parametros;
    }

    private function removerChavesArray(array $array)
    {
        return array_filter($array, function($chave) {
            return !in_array($chave,  [
              'id_usuario_criacao', 'id_usuario_alteracao', 'dt_criacao', 'dt_alteracao', 'fl_ativo', 'fl_del', 'id'
            ]);
        }, ARRAY_FILTER_USE_KEY);
    }

    public function copiartaxaAction()
    {
        $this->isAjax();

        $parametros = $this->getRequest()->getParams();
        $retorno = ['erro' => false, 'mensagem' => 'Cópia da taxa concluída com sucesso.'];
        $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();

        try {
            $adapter->beginTransaction();

            $modelTaxasAgrupamento = new Comercializacao_Model_TaxasAgrupamentos();
            
            $rowTaxaAgrupamento = $modelTaxasAgrupamento->getRow($parametros['idTaxa'])->toArray();
            $novaTaxaAgrupamento = $this->limparColunasInvalidas($rowTaxaAgrupamento);
            $novaTaxaAgrupamento['id_produto'] = $parametros['produto'];
            $novaTaxaAgrupamento['ds_nome_agrupamento_taxas'] = $parametros['nomeTaxa'];
            $novaTaxaAgrupamento['tp_taxa_agrupamento'] = $parametros['tipoTaxa'];
            $novaTaxaAgrupamento['fl_ativo'] = true;
            
            $novaTaxaAgrupamento = $modelTaxasAgrupamento->salvar($novaTaxaAgrupamento)->toArray();
            
            $modelTaxasValores = new Comercializacao_Model_TaxasValores();
            $rowsTaxasValores = $modelTaxasValores->getTaxasValoresByTaxaAgrupamento($parametros['idTaxa'])->toArray();
            $deParaTaxas = [];
            $taxasRelacionadasVinculadas = [];

            foreach ($rowsTaxasValores as $taxaValor) {
                $novaTaxaValor = $this->limparColunasInvalidas($taxaValor);
                $novaTaxaValor['id_taxa_agrupamento'] = $novaTaxaAgrupamento['id'];
                $novaTaxaValor['fl_ativo'] = true;

                $novaTaxaValor = $modelTaxasValores->save($novaTaxaValor);
                $deParaTaxas[$taxaValor['id']] = $novaTaxaValor;

                $coberturasRelacionadas = $modelTaxasValores->getCoberturasRelacionadas($taxaValor['id']);

                if (!empty($coberturasRelacionadas)) {
                    $taxasRelacionadasVinculadas[$taxaValor['id']] = $coberturasRelacionadas;
                }
            }

            foreach ($taxasRelacionadasVinculadas as $idTaxa => $taxasRelacionadas) {
                $novoIdTaxa = $deParaTaxas[$idTaxa];

                foreach ($taxasRelacionadas as $idTaxaRelacionada) {
                    $dadosTaxaRelacionada = ['id_taxa_relacionada' => $deParaTaxas[$idTaxaRelacionada]];

                    $modelTaxasValores->relacionaTaxas($dadosTaxaRelacionada, $novoIdTaxa);
                }
            }

            switch ($parametros['tipoTaxa']) {
                case Comercializacao_Model_TaxasAgrupamentos::TIPO_ESTADO:
                    $this->copiarTaxaAgrupamentoEstado((int) $parametros['idTaxa'], (int) $novaTaxaAgrupamento['id']);
                    break;

                case Comercializacao_Model_TaxasAgrupamentos::TIPO_PROPONENTE:
                    $this->copiarTaxaAgrupamentoProponente((int) $parametros['idTaxa'], (int) $novaTaxaAgrupamento['id']);

                case Comercializacao_Model_TaxasAgrupamentos::TIPO_USUARIO:
                    $this->copiarTaxaAgrupamentoUsuario((int) $parametros['idTaxa'], (int) $novaTaxaAgrupamento['id']);

                case Comercializacao_Model_TaxasAgrupamentos::TIPO_MUNICIPIO:
                    $this->copiarTaxaAgrupamentoMunicipio((int) $parametros['idTaxa'], (int) $novaTaxaAgrupamento['id']);
                    break;
            }

            $adapter->commit();
        } catch (Exception $erro) {
            $adapter->rollback();

            $retorno['erro'] = true;
            $retorno['mensagem'] = $erro->getMessage();
        }

        $this->getResponse()->setBody(Zend_Json::encode($retorno));
    }

    private function limparColunasInvalidas(array $dados)
    {
        $colunasInvalidas = ['id_usuario_criacao', 'id_usuario_alteracao', 'dt_criacao', 'dt_alteracao', 'fl_ativo', 'fl_del', 'id'];

        return array_filter($dados, function($indice) use ($colunasInvalidas) {
            return !in_array($indice, $colunasInvalidas);
        }, ARRAY_FILTER_USE_KEY);
    }

    private function copiarTaxaAgrupamentoEstado(int $idTaxaAgrupamentoAntigo, int $idTaxaAgrupamentoNovo)
    {
        $modelTaxasAgrupamentoEstados = new Comercializacao_Model_TaxasAgrupamentoEstados();
        $rowsTaxasAgrupamentoEstados = $modelTaxasAgrupamentoEstados->fetchAll(["id_taxa_agrupamento = {$idTaxaAgrupamentoAntigo}"])->toArray();

        foreach ($rowsTaxasAgrupamentoEstados as $taxaAgrupamentoEstado) {
            $novaTaxaAgrupamentoEstado = $this->limparColunasInvalidas($taxaAgrupamentoEstado);
            $novaTaxaAgrupamentoEstado['id_taxa_agrupamento'] = $idTaxaAgrupamentoNovo;

            $modelTaxasAgrupamentoEstados->save($novaTaxaAgrupamentoEstado);
        }
    }

    private function copiarTaxaAgrupamentoProponente(int $idTaxaAgrupamentoAntigo, int $idTaxaAgrupamentoNovo)
    {
        $modelTaxasAgrupamentoProponentes = new Comercializacao_Model_TaxasAgrupamentoProponente();
        $rowsTaxasAgrupamentoProponentes = $modelTaxasAgrupamentoProponentes->fetchAll(["id_taxa_agrupamento = {$idTaxaAgrupamentoAntigo}"])->toArray();

        foreach ($rowsTaxasAgrupamentoProponentes as $taxaAgrupamentoProponente) {
            $novaTaxaAgrupamentoProponente = $this->limparColunasInvalidas($taxaAgrupamentoProponente);
            $novaTaxaAgrupamentoProponente['id_taxa_agrupamento'] = $idTaxaAgrupamentoNovo;

            $modelTaxasAgrupamentoProponentes->save($novaTaxaAgrupamentoProponente);
        }
    }

    private function copiarTaxaAgrupamentoUsuario(int $idTaxaAgrupamentoAntigo, int $idTaxaAgrupamentoNovo)
    {
        $modelTaxasAgrupamentoUsuarios = new Comercializacao_Model_TaxasAgrupamentoUsuarios();
        $rowsTaxasAgrupamentoUsuarios = $modelTaxasAgrupamentoUsuarios->fetchAll(["id_taxa_agrupamento = {$idTaxaAgrupamentoAntigo}"])->toArray();

        foreach ($rowsTaxasAgrupamentoUsuarios as $taxasAgrupamentoUsuario) {
            $modelTaxasAgrupamentoUsuarios->save($idTaxaAgrupamentoNovo, $taxasAgrupamentoUsuario['id_usuario']);
        }
    }

    private function copiarTaxaAgrupamentoMunicipio(int $idTaxaAgrupamentoAntigo, int $idTaxaAgrupamentoNovo)
    {
        $modelTaxasAgrupamentoMunicipios = new Comercializacao_Model_TaxasAgrupamentoMunicipios();
        $rowsTaxasAgrupamentoMunicipios = $modelTaxasAgrupamentoMunicipios->fetchAll(["id_taxa_agrupamento = {$idTaxaAgrupamentoAntigo}"])->toArray();

        foreach ($rowsTaxasAgrupamentoMunicipios as $taxaAgrupamentoMunicipio) {
            $novaTaxaAgrupamentoMunicipio = $this->limparColunasInvalidas($taxaAgrupamentoMunicipio);
            $novaTaxaAgrupamentoMunicipio['id_taxa_agrupamento'] = $idTaxaAgrupamentoNovo;

            $modelTaxasAgrupamentoMunicipios->save($novaTaxaAgrupamentoMunicipio);
        }
    }

    public function copiarAction()
    {
        $this->getHelper('layout')->disableLayout();
    }

    public function alterarcomissaoloteAction()
    {
        $this->view->title = 'Taxas » Alterar Comissão em Lote';

        if ($this->getRequest()->isPost()) {
            $this->isAjax();

            $retorno = ['erro' => false, 'mensagem' => 'Comissões alteradas com sucesso.'];
            $registros = [];

            $adapter = new Zend_File_Transfer_Adapter_Http();
            $adapter->setDestination(APPLICATION_PATH . '/upload_files/temp/');
            $adapter->addValidator('Extension', false, ['csv']);

            $file = $adapter->getFileInfo();
            $nomeArquivo = $file['arquivo']['name'];

            if (!$adapter->isValid()) {
                $retorno['erro'] = true;
                $retorno['mensagem'] = 'Formato de arquivo inválido (formato aceito: .csv).';

                $this->getResponse()->setBody(Zend_Json::encode($retorno));

                return false;
            }

            if (!$adapter->receive($nomeArquivo)) {
                $retorno['erro'] = true;
                $retorno['mensagem'] = 'Erro ao receber o arquivo de alteração de comissão.';

                $this->getResponse()->setBody(Zend_Json::encode($retorno));

                return false;
            }

            $arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $nomeArquivo, 'r');
            $contador = 0;
            $idsTaxasAgrupamento = [];

            while (($dados = fgetcsv($arquivo, 0, ';')) != false) {
                if (count($dados) !== 3) {
                    $mensagem = "Importação inválida. O arquivo deve conter 3 colunas com o cabeçalho/dados na seguinte ordem:";
                    $mensagem .= "\n1ª - Id Validação";
                    $mensagem .= "\n2ª - Tipo Validação";
                    $mensagem .= "\n3ª - Nova Comissão";


                    $retorno['erro'] = true;
                    $retorno['mensagem'] = $mensagem;

                    $this->getResponse()->setBody(Zend_Json::encode($retorno));

                    return false;
                }

                if ($contador === 0) {
                    $contador++;
                    continue;
                }

                $idsTaxasAgrupamento[] = $dados[0];

                $registros[] = [
                  'id_taxa_agrupamento' => $dados[0],
                  'vl_comissao_novo' => $dados[2],
                ];
            }

            fclose($arquivo);

            $modelTaxasAgrupamento = new Comercializacao_Model_TaxasAgrupamentos();
            $modelLogAlteracoesComissaoLote = new Log_Model_LogAlteracoesComissaoLote();

            foreach ($registros as $registro) {
                try {
                    Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

                    $registro['vl_comissao_novo'] = Agro_Util::formatCurrencyDb($registro['vl_comissao_novo']);
                    $rowTaxaAgrupamento = $modelTaxasAgrupamento->find($registro['id_taxa_agrupamento'])->current()->toArray();

                    $dadosLog = [
                      'id_taxa_agrupamento' => $registro['id_taxa_agrupamento'],
                      'vl_comissao_anterior' => $rowTaxaAgrupamento['vl_comissao'],
                      'vl_comissao_novo' => $registro['vl_comissao_novo']
                    ];

                    $modelLogAlteracoesComissaoLote->delete('id_taxa_agrupamento', $registro['id_taxa_agrupamento']);

                    if (!$modelLogAlteracoesComissaoLote->save($dadosLog)) {
                        throw new Exception('Erro ao salvar o log de alteração da comissão.');
                    }

                    $rowTaxaAgrupamento['vl_comissao'] = $registro['vl_comissao_novo'];

                    if (!$modelTaxasAgrupamento->salvar($rowTaxaAgrupamento)) {
                        throw new Exception('Erro ao alterar a comissão');
                    }

                    Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
                } catch (Exception $erro) {
                    $registro['mensagem'] = "Erro ao alterar as comissões de taxas.";
                    $retorno['erro'] = true;

                    Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
                }
            }

            $this->getResponse()->setBody(Zend_Json::encode($retorno));
        }
    }

    public function excluirtaxasrelacionadasAction()
    {
        $this->isAjax();

        $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();

        try {
            $adapter->beginTransaction();

            $this->_return['mensagem'] = 'Exclusão executada com sucesso.';
            $this->_return['tipoTaxa'] = $this->getRequest()->getParam('tipoTaxa');

            (new Comercializacao_Service_Taxas_TaxaExclusao())->excluirEmLote(
                explode(',', $this->getRequest()->getParam('idsLinhasSelecionadas'))
            );

            $adapter->commit();
        } catch (Exception $erro) {
            $adapter->rollBack();
            $this->_return['false'] = true;
            $this->_return['mensagem'] = 'Erro ao excluir taxas.';
        }

        $this->getResponse()->setBody(Zend_Json::encode($this->_return));
    }
}
