<?php

class Endosso_SolicitacaoController extends Agro_Controller_Proposta {

    public function getForm() {
        $Form = new Endosso_Form_Solicitacao();
        $params = $this->getRequest()->getParams();
        $Form->populate($params);
        $this->view->back = 'javascript:history.back();';

        return $Form;
    }

    public function init() {
        $this->view->title = 'Seguro » Endosso » Solicitar Endosso';
    }

    public function indexAction(){
        $this->view->endosso = 2;
    }

    public function listAction() {

        $this->getRequest()->setParam('id_status', '');
        $this->getHelper('layout')->disableLayout();

        $Model = $this->getModel();
        $where = $this->getFilter();
        $this->_paginator = $this->getRequest()->getParam('show_paginacao');
        $recordsPerPage = ($this->recordsPerPage ? $this->recordsPerPage : RECORDS_PER_PAGE);
        $Rs = $Model->fetchAllPaginator($where, $this->getRequest()->getParam('page'), $recordsPerPage, $this->_paginator);
        $this->view->paginator = $Rs;
    }

    public function getModel() {
        return new Endosso_Model_Solicitacao();
    }

    public function formAction()
    {
        $this->view->back = '/endosso/consulta';

        $endossoPropostas = (new Endosso_Model_Propostas())->find($this->_requestParams['id_nova_proposta'])->current();

        $modelSeguroPropostas = new Seguro_Model_Propostas();
        $modelUsuarios = new Sistema_Model_Usuarios();

        $dsChaveTipoSolicitacao = Endosso_Model_TiposSolicitacao::getChaveById((int) $this->_requestParams['id_tipo']);
       
        $this->view->proposta = $modelSeguroPropostas->get($this->_requestParams['id_proposta']);
        $this->view->endosso = $modelSeguroPropostas->get($this->_requestParams['id_nova_proposta']);
        $this->view->endossoVigente = $modelSeguroPropostas->get($this->view->endosso->recupera_id_proposta_vigente($this->view->endosso->id));
        $this->view->idTipoSolicitacao = $this->_requestParams['id_tipo'];
        $this->view->chaveTipoSolicitacao = $dsChaveTipoSolicitacao;
        $this->view->coberturasContratadas = $this->view->endosso->coberturas_contratadas('adicional');
        $this->view->tiposEndosso = $endossoPropostas->tipos_endosso();
        $this->view->tipoEndossoProposta = $endossoPropostas->tipo_endosso_proposta();
        $this->view->temAvisoAceito = false;
        $this->view->origemConsulta = !empty($this->_requestParams['consulta']);
        $this->view->funcionarioAgro = $modelUsuarios->isFuncionarioAgro();
        $this->view->usuariosAgro = $modelUsuarios
            ->getComboByIdDepartamento(Sistema_Model_Departamentos::AGRO_TECNICA);

        $idSolicitacao = !empty($this->_requestParams['id']) ? (int)$this->_requestParams['id'] : null;
        $this->view->dadosSolicitacao = $this->getSoliciticaoByProposta($this->_requestParams['id_nova_proposta'], $idSolicitacao);
        $this->view->usuarioTecnica = (int) Zend_Auth::getInstance()->getIdentity()->id_departamento === Sistema_Model_Departamentos::AGRO_TECNICA;
        
        if (!empty($this->view->dadosSolicitacao['idSolicitacao'])) {
            $solicitacao = (new Endosso_Model_Solicitacao())->find($this->view->dadosSolicitacao['idSolicitacao'])[0];
            $this->view->id_usuario_responsavel_selecionado = $solicitacao['id_usuario_responsavel'];
        }

        $avisos = (new Sinistro2_Model_AvisosSinistro())->getAvisosEndossos($this->_requestParams['id_nova_proposta']);

        foreach ($avisos as $aviso) {
            if ($aviso['id_status_aviso'] === Sinistro2_Model_AvisosSinistro::ID_STATUS_SA_ACEITO) {
                $this->view->dadosSolicitacao['ocorreuSinistro'] = 'true';
                $this->view->temAvisoAceito = true;
                break;
            }
        }

        if (!empty($this->_requestParams['atualizarStatus'])) {
            (new Seguro_Model_Propostas())->save([
              'id_proposta' => $this->_requestParams['id_nova_proposta'],
              'id_status'   => Seguro_Model_Propostas::ID_STATUS_SOLICITACAO_ENDOSSO
            ]);

            $this->view->back = '/endosso/solicitacao';
        }

        $this->view->configuracaoCarAtiva = (new Produto_Model_Atributogrupos())->isAtributoLiberadoParaProduto(
            (int) $this->view->proposta->id_produto,
            'IS_CAR'
        );
        
        // Possui CAR manual
        $this->view->itensCarsManuais = (new Seguro_Model_ItensSegurados())
            ->getCarsManuaisSelecionadosPorProposta((int) $this->_requestParams['id_nova_proposta']);

    }

    public function verificarsolicitacaovalidaAction()
    {
        $this->isAjax();

        $mensagemErro = 'Já existe uma solicitação em aberto para esta proposta, favor verificar.';
        $retorno = [
          'erro' => false,
          'mensagem' => '',
          'permitirNovaSolicitacao' => true,
          'temSolicitacaoNaoFinalizada' => false,
          'idSolicitacao' => null,
          'idProposta' => null,
        ];

        $statusPermitidosSolicitacao = [
          Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_ACEITO_EFETIVADO,
          Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_CANCELADO_CORRETOR,
          Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_NEGADO,
          Endosso_Model_Solicitacao::ID_STATUS_CANCELADO
        ];

        $rowsSolicitacoes = $this->getModel()->getSolicitacoesByProposta($this->getRequest()->getParam('id_proposta'));

        if ($rowsSolicitacoes[0]['id_status'] === Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_NAO_FINALIZADA) {
            $retorno['temSolicitacaoNaoFinalizada'] = true;
            $retorno['idSolicitacao'] = $rowsSolicitacoes[0]['id'];
            $retorno['idProposta'] = $rowsSolicitacoes[0]['id_proposta'];

            $retorno['mensagem'] = "<b>Existe uma solicitação aberta ainda não finalizada para a proposta. Clique na ação desejada:</b><br>";
            $retorno['mensagem'] .= "<br><b>- Nova Solicitação</b>: criar uma nova solicitação e cancelar a anterior";
            $retorno['mensagem'] .= "<br><b>- Consultar Solicitação</b>: redirecionar para a consulta da solicitação existente";
            $retorno['mensagem'] .= "<br><b>- Cancelar</b>: não realizar nenhuma ação";
        }

        if (!$retorno['temSolicitacaoNaoFinalizada']) {
            foreach ($rowsSolicitacoes as $rowSolicitacao) {
                if (empty($rowSolicitacao['id_status'])) {
                    continue;
                }

                if (!in_array($rowSolicitacao['id_status'], $statusPermitidosSolicitacao)) {
                    $retorno['permitirNovaSolicitacao'] = false;
                    $retorno['mensagem'] = $mensagemErro;
                    break;
                }
            }
        }

        $this->getResponse()->setBody(Zend_Json::encode($retorno));
    }

    public function alteraresponsavelsolicitacaoAction(): void
    {
        $this->isAjax();
        
        $modelSolicitacao = new Endosso_Model_Solicitacao();
        $solicitacao = $modelSolicitacao->find($this->getRequest()->getParam('idSolicitacao'))[0];
        $idUsuarioResponsavel = $this->getRequest()->getParam('idUsuarioResponsavel');

        try {
            if (empty($idUsuarioResponsavel)) {
                throw new Exception('Responsável não foi informado');
            }

            if ($solicitacao['id'] != $this->getRequest()->getParam('id_usuario_responsavel')) {
                $dataStatus = array(
                    'id_solicitacao'     => $solicitacao['id'],
                    'id_status'          => $solicitacao['id_status'],
                    'ds_observacao'      => 'Alteração do responsável.',
                    'id_usuario_criacao' => Zend_Auth::getInstance()->getIdentity()->id
                );
        
                (new Endosso_Model_SolicitacaoStatus())->save($dataStatus);
            }

            $modelSolicitacao->update(
                ['id_usuario_responsavel' => $this->getRequest()->getParam('idUsuarioResponsavel')],
                "id = {$solicitacao['id']}"
            );

            $this->getResponse()->setBody(Zend_Json::encode([
                'erro' => false,
                'mensagem' => 'Responsável alterado com sucesso.'
            ]));
        } catch (Exception $e) {
            $this->getResponse()->setBody(Zend_Json::encode([
                'erro' => true,
                'mensagem' => $e->getMessage()  
            ]));
        } 
    }

    public function salvarsolicitacaoAction()
    {
        $this->isAjax();
        $retorno = ['erro' => false, 'mensagem' => 'Solicitação salva com sucesso.', 'id' => null];
        $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();
        $parametros = $this->getRequest()->getParams();
        $User = Zend_Auth::getInstance()->getIdentity();
        
        try {
            $adapter->beginTransaction();

            $idProposta = (int) $parametros['id_proposta'];
            
            if (!empty($parametros['validarUnidadesCroqui']) && $parametros['chaveTipoSolicitacao'] !== Endosso_Model_TiposSolicitacao::DS_CHAVE_CANCELAMENTO_APOLICE) {
                $this->validarUnidadesCroqui($idProposta);
            }

            if (!empty($parametros['finalizarSolicitacao'])) {
                $this->atualizarStatusOrcamentoEndosso($idProposta);
            }

            $proposta = (new Seguro_Model_Propostas)->find($idProposta)->current();
            
            $configuracaoCarAtiva = (new Produto_Model_Atributogrupos())
				->isAtributoLiberadoParaProduto($proposta->id_produto, 'IS_CAR');

            $possuiItemSemIdentificacaoCar = false;
            // valida apenas na hora de finalizar solicitação de endosso
			if (
                $configuracaoCarAtiva
                && !empty($parametros['finalizarSolicitacao'])
                && Seguro_Service_Car::isCarObrigatorio($idProposta)
            ) {
				$possuiItemSemIdentificacaoCar = (new Seguro_Model_ItensSegurados())->possuiItemSemIdentificacaoCar($idProposta);
				
				if ($possuiItemSemIdentificacaoCar) {
					throw new Exception('Falta identificação de CAR em ao menos um dos itens declarados. Será necessário seleção para efetivação.', 1);
				}
			}
            
            if (!empty($parametros['camposAlterados'])) {
                if (empty($parametros['id'])) {
                    $dadosSaveinicial = $parametros;
                    $dadosSaveinicial['bloco_alteracoes'] = '';
                    $dadosSaveinicial['ds_campos_alteracoes'] = '';
                    $dadosSaveinicial['ds_campos_valores_iniciais'] = '';

                    $this->getRequest()->setParam('id', $this->getModel()->save($dadosSaveinicial));
                    $parametros['id'] = $this->getRequest()->getParam('id');
                }

                $parametros = $this->organizarCamposEditadosSolicitacao($parametros);
            }
            
            if (array_key_exists('fl_ocorreu_sinistro', $parametros)) {
                $parametros['fl_ocorreu_sinistro'] = $parametros['fl_ocorreu_sinistro'] === 'true' ? 'true' : 'false';
            }
            $serviceSolicitacao = new Endosso_Service_Solicitacao();
            $idTipoSolicitacaoAtual = (int)$parametros['id_tipo_solicitacao'];
    
            if (
                in_array(
                    $idTipoSolicitacaoAtual,
                    [
                        Endosso_Model_TiposSolicitacao::ID_STATUS_ALTERACAO_APOLICE,
                        Endosso_Model_TiposSolicitacao::ID_COM_MOVIMENTO_PREMIO,
                        Endosso_Model_TiposSolicitacao::ID_SEM_MOVIMENTO_PREMIO,
                    ]
                )
                && $parametros['camposAlterados']
            ) {
                $serviceSolicitacao = new Endosso_Service_Solicitacao();
                $tipoSolicitacaoComMovimento = $serviceSolicitacao->validarSeTipoSolicitacaoComMovimento(
                    json_decode($parametros['ds_campos_alteracoes'], true),
                    (int)$parametros['id_proposta']
                );

                $solicitacao = (new Endosso_Model_Solicitacao())->find($parametros['id'])->current();

                if($User->id != $solicitacao['id_usuario_responsavel']){
                   
                    if ($tipoSolicitacaoComMovimento && $idTipoSolicitacaoAtual !== Endosso_Model_TiposSolicitacao::ID_COM_MOVIMENTO_PREMIO) {
                        $parametros['id_tipo_solicitacao'] = Endosso_Model_TiposSolicitacao::ID_COM_MOVIMENTO_PREMIO;
                        $parametros['id_usuario_responsavel'] = $serviceSolicitacao
                            ->buscarDadosResponsavelTipoSolicitacao(Endosso_Model_TiposSolicitacao::ID_COM_MOVIMENTO_PREMIO)['id_usuario_responsavel'];
                    }

                    if (!$tipoSolicitacaoComMovimento && $idTipoSolicitacaoAtual !== Endosso_Model_TiposSolicitacao::ID_SEM_MOVIMENTO_PREMIO) {
                        $parametros['id_tipo_solicitacao'] = Endosso_Model_TiposSolicitacao::ID_SEM_MOVIMENTO_PREMIO;
                        $parametros['id_usuario_responsavel'] = $serviceSolicitacao
                            ->buscarDadosResponsavelTipoSolicitacao(Endosso_Model_TiposSolicitacao::ID_SEM_MOVIMENTO_PREMIO)['id_usuario_responsavel'];
                    }
                }

            }
            
            $retorno['id'] = $this->getModel()->save($parametros);
            
            $statusArray = [
                Endosso_Model_Solicitacao::ID_STATUS_CANCELADO,
                Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_NEGADO,
                Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_CANCELADO_CORRETOR
            ];

            if (
                in_array((int) $parametros['id_status'], $statusArray)
                && in_array((int) $parametros['id_tipo_solicitacao'], [
                    Endosso_Model_TiposSolicitacao::ID_CANCELAMENTO_APOLICE,
                    Endosso_Model_TiposSolicitacao::ID_COM_MOVIMENTO_PREMIO,
                    Endosso_Model_TiposSolicitacao::ID_SEM_MOVIMENTO_PREMIO,
                ])
            ) {
                if (!(new Seguro_Model_Propostas())->changeStatusId($parametros['id_proposta'], Seguro_Model_Propostas::ID_STATUS_SOLICITACAO_CANCELADA, 'Solicitação de endosso negada.')) {
                    throw new Exception('Erro ao atualizar status do endosso.');
                }
            }

            if (
                in_array(
                    (int)$this->getRequest()->getParam('id_status'),
                    [Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_PENDENTE, Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_NEGADO]
                )
            ) {
                $this->enviarEmail();
            }

            $adapter->commit();
        } catch (Exception $erro) {
            $adapter->rollback();

            $retorno['erro'] = true;
            $retorno['mensagem'] = 'Erro ao salvar a solicitação.';
            
            if ($erro->getCode() === 1) {
                $retorno['mensagem'] = $erro->getMessage();
            }
        }

        $this->getResponse()->setBody(Zend_Json::encode($retorno));
    }

    private function getSoliciticaoByProposta(int $idProposta, int $idSolicitacao = null) : array
    {
        $retorno = [
            'idSolicitacao' => null,
            'numeroParcelas' => null,
            'justificativa' => '',
            'idStatus' => null,
            'ocorreuSinistro' => false,
            'idTipoSolicitacao' => '',
            'chaveTipoSolicitacao' => '',
            'camposAlterados' => '',
        ];

        $parametros = ["id_proposta = {$idProposta}"];

        if (!empty($idSolicitacao)) {
            $parametros[] = "id = {$idSolicitacao}";
        }

        $rowSolicitacao = $this->getModel()->fetchAll($parametros)->current();

        if (!empty($rowSolicitacao)) {
            $retorno['ocorreuSinistro'] = is_null($rowSolicitacao['fl_ocorreu_sinistro']) ? '' : ($rowSolicitacao['fl_ocorreu_sinistro'] ? 'true' : 'false');
            $retorno['idSolicitacao'] = $rowSolicitacao['id'];
            $retorno['idStatus'] = $rowSolicitacao['id_status'];
            $retorno['justificativa'] = $rowSolicitacao['ds_descricao'];
            $retorno['numeroParcelas'] = $rowSolicitacao['nr_parcelas'];
            $retorno['idTipoSolicitacao'] = $rowSolicitacao['id_tipo_solicitacao'];
            $retorno['chaveTipoSolicitacao'] = Endosso_Model_TiposSolicitacao::getChaveById((int)$rowSolicitacao['id_tipo_solicitacao']);
            $retorno['camposAlterados'] = $rowSolicitacao['ds_campos_alteracoes'];
        }

        return $retorno;
    }

    public function declaracaosinistroAction()
    {
        if ($this->getRequest()->isPost()) {
            $this->isAjax();
            $retorno = ['erro' => false, 'mensagem' => 'Declaração de Sinistro salva com sucesso.'];
            $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();

            try {
                $adapter->beginTransaction();
                if (empty($this->getRequest()->getParam('declaracaoCiencia')) || $this->getRequest()->getParam('declaracaoCiencia') === 'false') {
                    throw new Exception("É necessário marcar a opção 'Tenho ciência de que a declaração inverídica pode acarretar perda de direito à indenização'.", 1);
                }

                $retorno['id'] = $this->getModel()->save($this->getRequest()->getParams());

                $adapter->commit();
            } catch (Exception $erro) {
                $adapter->rollback();
                $retorno = ['erro' => false, 'mensagem' => 'Erro ao salvar a declaração de sinistro.'];

                if ($erro->getCode() === 1) {
                    $retorno = ['erro' => false, 'mensagem' => $erro->getMessage()];
                }
            }

            $this->getResponse()->setBody(Zend_Json::encode($retorno));
        } else {
            $this->getHelper('layout')->disableLayout();

            $parametros = $this->getRequest()->getParams();

            $rowSolicitacao = $this->getModel()->fetchAll(["id_proposta = {$parametros['id']}"])->current();
            $this->view->fl_ocorreu_sinistro = '';

            if (!empty($rowSolicitacao)) {
                $this->view->fl_ocorreu_sinistro = is_null($rowSolicitacao['fl_ocorreu_sinistro']) ? '' : ($rowSolicitacao['fl_ocorreu_sinistro'] ? 'true' : 'false');
            }

            $avisos = (new Sinistro2_Model_AvisosSinistro())->getAvisosEndossos($parametros['id']);

            foreach ($avisos as $aviso) {
                if ($aviso['id_status_aviso'] === Sinistro2_Model_AvisosSinistro::ID_STATUS_SA_ACEITO) {
                    $this->view->fl_ocorreu_sinistro = 'true';
                    $this->view->temAvisoAceitoDeclaracao = true;
                    break;
                }
            }


        }
    }

    public function parcelamentocorretorAction()
    {
        if ($this->getRequest()->isPost()) {
            $this->isAjax();
            $retorno = ['erro' => false, 'mensagem' => 'Parcelamento salvo com sucesso.'];
            $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();
            $parametros = $this->getRequest()->getParams();

            try {
                $adapter->beginTransaction();

                $parametros = $this->organizarParcelamento($parametros);
                $retorno['id'] = $this->getModel()->save($parametros);

                $adapter->commit();
            } catch (Exception $erro) {
                $adapter->rollback();
                $retorno = ['erro' => false, 'mensagem' => 'Erro ao salvar o parcelamento.'];

                if ($erro->getCode() === 1) {
                    $retorno = ['erro' => false, 'mensagem' => $erro->getMessage()];
                }
            }

            $this->getResponse()->setBody(Zend_Json::encode($retorno));
        } else {
            $this->getHelper('layout')->disableLayout();

            $rowSolicitacao = $this->getModel()->fetchAll(["id_proposta = {$this->getRequest()->getParam('id')}"])->current();
            $this->view->nr_parcelas = false;

            if (!empty($rowSolicitacao)) {
                $this->view->nr_parcelas = $rowSolicitacao['nr_parcelas'];
            }
        }
    }

    public function cancelarsolicitacaoAction()
    {
        $this->isAjax();

        $retorno = ['erro' => false, 'mensagem' => 'Solicitação cancelada com sucesso.'];
        $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();

        try {
            $adapter->beginTransaction();

            $this->getModel()->save([
                'id' => $this->getRequest()->getParam('id'),
                'id_status' => Endosso_Model_Solicitacao::ID_STATUS_CANCELADO,
                'id_proposta' => $this->getRequest()->getParam('id_proposta')
            ]);

            (new Seguro_Model_Propostas())->save([
              'id_proposta' => $this->getRequest()->getParam('id_proposta'),
              'id_status'   => Seguro_Model_Propostas::ID_STATUS_SOLICITACAO_CANCELADA
            ]);

            $adapter->commit();
        } catch (Exception $erro) {
            $adapter->rollback();
            $retorno['erro'] = true;
            $retorno['mensagem'] = 'Erro ao atualizar o status da solicitação de endosso não finalizada.';
        }

        $this->getResponse()->setBody(Zend_Json::encode($retorno));
    }

    private function validarUnidadesCroqui(int $idProposta)
    {
        $rowsPropostasCroquis = (new Seguro_Model_PropostasCroquis())->getCroquis($idProposta);
        $rowsItensSegurados = (new Seguro_Model_ItensSegurados())->getAllByProposta($idProposta);
        $talhoesDesenhados = [];

        foreach ($rowsPropostasCroquis as $rowPropostaCroqui) {
            $talhoesDesenhados = array_merge(explode(';', $rowPropostaCroqui['ds_nome']), $talhoesDesenhados);
        }

        foreach ($rowsItensSegurados as $rowItensSegurados) {
            $indice = array_search(str_replace(' ', '', $rowItensSegurados['ds_item_segurado']), $talhoesDesenhados);

            if ($indice === false) {
                throw new Exception('É necessário desenhar no Croqui, todas as quadras referentes as Unidades Seguradas cadastradas.', 1);
            }

            unset($talhoesDesenhados[$indice]);
        }

        return true;
    }

    private function atualizarStatusOrcamentoEndosso(int $idProposta)
    {
        $rowsPropostas = (new Seguro_Model_Propostas())->getTodasPropostas($idProposta);

        foreach ($rowsPropostas as $rowProposta) {
            if ($rowProposta['id'] === $idProposta) {
                continue;
            }

            if ($rowProposta['id_status'] === Seguro_Model_Propostas::ID_STATUS_ORCAMENTO_ENDOSSO) {
                $retorno = (new Endosso_Model_Propostas())->changeStatus(
                  ['id_proposta' => $idProposta],
                  Seguro_Model_Propostas::DS_CHAVE_ENDOSSO_INCOMPLETO,
                  false,
                  true
                );

                if (!$retorno) {
                    throw new Exception('Erro ao apagar o orçamento de endosso.');
                }
            }
        }

        return true;
    }

    private function organizarCamposEditadosSolicitacao(array $parametros)
    {
        $rowPropostaEndossoSolicitacao = $this->getModel()->find($parametros['id'])->current();

        switch ($parametros['bloco_alteracoes']) {
            case 'btnArquivosComplementares':
                $parametros = $this->organizarArquivosComplementares($rowPropostaEndossoSolicitacao, $parametros);
                break;
            case 'btnResumosCoberturas':
                $parametros = $this->organizarResumosCoberturas($rowPropostaEndossoSolicitacao, $parametros);
                break;
            case 'btnCroqui':
                $parametros = $this->organizarCroquis($rowPropostaEndossoSolicitacao, $parametros);
                break;
            default:
                $parametros = $this->organizarPadrao($rowPropostaEndossoSolicitacao, $parametros);
                break;
        }

        return $parametros;
    }

    /**
     * Busca os centroides de cada item pela proposta uma string com um array de objetos indexados pelo id do item
     *
     * @param int $idProposta
     * @param bool $isValorOriginal
     * @return string
     */
    private function getItensCentroidesByIdProposta(int $idProposta, $isValorOriginal = true): string
    {
        $select =  " SELECT json_agg(json_build_object(pct.ds_item_segurado, pct.ds_coordenadas_centroide) ORDER BY pct.ds_item_segurado) AS itens_centroides ";
        $select .= "   FROM seguro.propostas_croquis_talhoes pct ";
        $select .= "   JOIN seguro.propostas_croquis pc ON pc.id = pct.id_croqui ";
        $select .= "  WHERE pc.id_proposta = {$idProposta} ";

        if ($isValorOriginal) {
            $select .= "   AND pc.fl_vigente is false ";
            $select .= " GROUP BY pc.id ";
            $select .= " ORDER BY pc.id ASC ";
            $select .= " LIMIT 1";
        } else {
            $select .= "   AND pc.fl_vigente is true";
        }

        $itensCoordenadas = Agro_Db_Table_Abstract::getDefaultAdapter()->fetchOne($select);
        return !empty($itensCoordenadas) ? $itensCoordenadas : "[]";
    }

    /**
     * Busca os valores dos centroides dos itens cadastrados na criação do endosso e os adicionas no ds_campos_valores_iniciais,
     * após isso, valida se os centroides dos itens do croqui vigente são diferentes do campo ds_campos_valores_iniciais e
     * caso sejam, os adicionamos no ds_campos_alteracoes.
     *
     * @param Seguro_Model_Row_Proposta $rowPropostaEndossoSolicitacao
     * @param array $parametros
     * @return array
     */
    private function organizarCroquis(Seguro_Model_Row_Proposta $rowPropostaEndossoSolicitacao, array $parametros): array
    {
        $itensCentroidesOriginal = $this->getItensCentroidesByIdProposta($rowPropostaEndossoSolicitacao['id_proposta']);
        $jsonItensCentroidesOriginal = json_decode($itensCentroidesOriginal, true);
        $itensCentroidesVigente = $this->getItensCentroidesByIdProposta($rowPropostaEndossoSolicitacao['id_proposta'], false);
        $jsonItensCentroidesVigente = json_decode($itensCentroidesVigente, true);

        // Validações para os valores iniciais
        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'])) {
            $camposValoresIniciais = json_decode($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'], true);

            if (!isset($camposValoresIniciais[$parametros['bloco_alteracoes']])) {
                $camposValoresIniciais[$parametros['bloco_alteracoes']] = $jsonItensCentroidesOriginal;
            }
        } else {
            $camposValoresIniciais = [$parametros['bloco_alteracoes'] => $jsonItensCentroidesOriginal];
        }

        $parametros['ds_campos_valores_iniciais'] = json_encode($camposValoresIniciais);

        // Validações para as alterações
        $camposAlteracoesSalvas = [];
        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'])) {
            $camposAlteracoesSalvas = json_decode($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'], true);

            if (isset($camposAlteracoesSalvas[$parametros['bloco_alteracoes']])) {
                unset($camposAlteracoesSalvas[$parametros['bloco_alteracoes']]);
            }
        }

        if ($itensCentroidesVigente != $itensCentroidesOriginal) {
            $alteracoesSalvar['E'][] = $jsonItensCentroidesVigente;
            $camposAlteracoesSalvas[$parametros['bloco_alteracoes']] = $alteracoesSalvar;
        }

        $parametros['ds_campos_alteracoes'] = json_encode($camposAlteracoesSalvas);
        return $parametros;
    }

    private function organizarPadrao($rowPropostaEndossoSolicitacao, $parametros)
    {
        /**
         * Primeiramente atualiza os valores iniciais, caso seja a primeira vez que está salvando um bloco
         * Desta forma, será possível validar sempre com os dados da forma que estavam ao abrir a solicitação
         */
        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'])) {
            $camposValoresIniciais = (array) json_decode($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais']);

            if (!isset($camposValoresIniciais[$parametros['bloco_alteracoes']])) {
                $camposValoresIniciais[$parametros['bloco_alteracoes']] = json_decode($parametros['ds_campos_valores_iniciais'], true);
                $parametros['ds_campos_valores_iniciais'] = json_encode($camposValoresIniciais);
            } else {
                $parametros['ds_campos_valores_iniciais'] = $rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'];
            }
        } else {
            $camposValoresIniciais = [$parametros['bloco_alteracoes'] => json_decode($parametros['ds_campos_valores_iniciais'], true)];
            $parametros['ds_campos_valores_iniciais'] = json_encode($camposValoresIniciais);
        }

        /**
         * Validações do que foi alterado/excluído/incluído
         */
        if (!empty($parametros['ds_campos_alteracoes'])) {
            $camposAlteracoesTela = json_decode($parametros['ds_campos_alteracoes'], true);
            $camposAlteracoesSalvas = json_decode($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'], true);
            $alteracoesSalvar = [];
            $camposNovos = [];

            foreach ($camposAlteracoesTela as $campoAlteracao) {
                $camposNovos[$campoAlteracao['name']] = $campoAlteracao['value'];

                foreach ($camposValoresIniciais[$parametros['bloco_alteracoes']] as $indice => $campoValorInicial) {
                    $campoValorInicial = (array) $campoValorInicial;

                    if ($campoValorInicial['name'] === $campoAlteracao['name']) {
                        if ($campoValorInicial['value'] !== $campoAlteracao['value']) {
                            $alteracoesSalvar['E'][] = $campoAlteracao;
                        }

                        unset($camposNovos[$campoAlteracao['name']]);
                    }
                }
            }

            foreach ($camposValoresIniciais[$parametros['bloco_alteracoes']] as $indice => $campoValorInicial) {
                $campoValorInicial = (array) $campoValorInicial;
                $campoEncontrado = false;

                foreach ($camposAlteracoesTela as $campoAlteracao) {
                    if ($campoAlteracao['name'] === $campoValorInicial['name']) {
                        $campoEncontrado = true;
                    }
                }

                if (!$campoEncontrado) {
                    $alteracoesSalvar['D'][] = $campoValorInicial;
                }
            }

            foreach ($camposNovos as $nomeCampo => $valorCampo) {
                $alteracoesSalvar['I'][] = ['name' => $nomeCampo, 'value' => $valorCampo];
            }

            if (!empty($alteracoesSalvar)) {
                $camposAlteracoesSalvas[$parametros['bloco_alteracoes']] = $alteracoesSalvar;
            } else {
                unset($camposAlteracoesSalvas[$parametros['bloco_alteracoes']]);
            }

            $parametros['ds_campos_alteracoes'] = !empty($camposAlteracoesSalvas) ? json_encode($camposAlteracoesSalvas) : '';
        }

        return $parametros;
    }

    private function organizarArquivosComplementares($rowPropostaEndossoSolicitacao, $parametros)
    {
        $valoresIniciais = [];
        $arquivosAlterados = json_decode($parametros['ds_campos_alteracoes'], true);

        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'])) {
            $parametros['ds_campos_valores_iniciais'] = json_decode($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'], true);

            if (isset($parametros['ds_campos_valores_iniciais'][$parametros['bloco_alteracoes']])) {
                $valoresIniciais = $parametros['ds_campos_valores_iniciais'][$parametros['bloco_alteracoes']];
            }
        }

        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'])) {
            $parametros['ds_campos_alteracoes'] = json_decode($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'], true);
        }

        if (empty($valoresIniciais)) {
            $dsCamposValoresIniciais = json_decode($parametros['ds_campos_valores_iniciais'], true);
            $valoresIniciais = [$parametros['bloco_alteracoes'] => []];

            if (!empty($dsCamposValoresIniciais)) {
                $valoresIniciais = $dsCamposValoresIniciais;
            }
        }

        $arquivosAlteradosSalvar = [];

        foreach ($arquivosAlterados as $arquivo) {
            if (!in_array($arquivo, $valoresIniciais[$parametros['bloco_alteracoes']])) {
                $arquivosAlteradosSalvar[$parametros['bloco_alteracoes']][] = $arquivo;
            }
        }

        $parametros['ds_campos_alteracoes'][$parametros['bloco_alteracoes']] = $arquivosAlteradosSalvar;
        $parametros['ds_campos_valores_iniciais'][$parametros['bloco_alteracoes']] = $valoresIniciais;

        if (empty($arquivosAlteradosSalvar) && empty($valoresIniciais[$parametros['bloco_alteracoes']])) {
            unset($parametros['ds_campos_alteracoes'][$parametros['bloco_alteracoes']]);
            unset($parametros['ds_campos_valores_iniciais'][$parametros['bloco_alteracoes']]);
        }

        $parametros['ds_campos_alteracoes'] = json_encode($parametros['ds_campos_alteracoes']);
        $parametros['ds_campos_valores_iniciais'] = json_encode($parametros['ds_campos_valores_iniciais']);

        return $parametros;
    }

    private function organizarParcelamento($parametros)
    {
        $valorPadraoBloco = [$parametros['bloco_alteracoes'] => []];

        if (empty($parametros['id'])) {
            $parametros['ds_campos_alteracoes'] = $parametros['ds_campos_valores_iniciais'] = json_encode($valorPadraoBloco);

            return $parametros;
        }

        $rowPropostaEndossoSolicitacao = $this->getModel()->find($parametros['id'])->current();

        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'])) {
            $camposValoresIniciais = (array)json_decode($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais']);

            if (!isset($camposValoresIniciais[$parametros['bloco_alteracoes']])) {
                $camposValoresIniciais[$parametros['bloco_alteracoes']] = $valorPadraoBloco;
                $parametros['ds_campos_alteracoes'] = $parametros['ds_campos_valores_iniciais'] = json_encode($camposValoresIniciais);
            }
        } else {
            $parametros['ds_campos_alteracoes'] = $parametros['ds_campos_valores_iniciais'] = json_encode($valorPadraoBloco);
        }

        return $parametros;
    }

    private function organizarResumosCoberturas($rowPropostaEndossoSolicitacao, $parametros)
    {
        $alteracoesSalvar = [];
        $alteracoesSalvasBase = null;
        $valoresIniciais = json_decode($parametros['ds_campos_valores_iniciais'], true);
        $valoresIniciaisSalvosBase = [];

        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'])) {
            $valoresIniciaisSalvosBase = json_decode($rowPropostaEndossoSolicitacao['ds_campos_valores_iniciais'], true);

            if (isset($valoresIniciaisSalvosBase[$parametros['bloco_alteracoes']])) {
                $valoresIniciais = $valoresIniciaisSalvosBase[$parametros['bloco_alteracoes']];
            }
        }

        if (!empty($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'])) {
            $alteracoesSalvasBase = json_decode($rowPropostaEndossoSolicitacao['ds_campos_alteracoes'], true);
        }

        $valoresAlteracoes = json_decode($parametros['ds_campos_alteracoes'], true);

        foreach ($valoresIniciais as $registroInicial) {
            $camposExisteAlteracao = false;

            foreach ($valoresAlteracoes as $registroAlteracao) {
                if ($registroInicial['name'] === $registroAlteracao['name']) {
                    $camposExisteAlteracao = true;
                    break;
                }
            }

            if (!$camposExisteAlteracao) {
                $alteracoesSalvar['D'][] = $registroInicial;
            }
        }

        foreach ($valoresAlteracoes as $registroAlteracao) {
            $campoExistiaInicialmente = false;

            foreach ($valoresIniciais as $registroInicial) {
                if ($registroInicial['name'] === $registroAlteracao['name']) {
                    if (trim($registroInicial['value']) !== trim($registroAlteracao['value'])) {
                        $alteracoesSalvar['E'][] = $registroAlteracao;
                    }

                    $campoExistiaInicialmente = true;
                    break;
                }
            }

            if (!$campoExistiaInicialmente) {
                $alteracoesSalvar['I'][] = $registroAlteracao;
            }
        }

        if (!empty($alteracoesSalvar)) {
            if (!empty($alteracoesSalvasBase)) {
                unset($alteracoesSalvasBase[$parametros['bloco_alteracoes']]);
            }

            $alteracoesSalvasBase[$parametros['bloco_alteracoes']] = $alteracoesSalvar;
        }

        $valoresIniciaisSalvosBase[$parametros['bloco_alteracoes']] = $valoresIniciais;

        $parametros['ds_campos_valores_iniciais'] = json_encode($valoresIniciaisSalvosBase);
        $parametros['ds_campos_alteracoes'] = !empty($alteracoesSalvasBase) ? json_encode($alteracoesSalvasBase) : '';

        return $parametros;
    }

    private function enviarEmail()
    {
        $Propostas = new Seguro_Model_Propostas();
        $Proposta = $Propostas->get($this->getRequest()->getParam('id_proposta'));
        $Mail = new Agro_Mail();
        $Mail->clearFrom();
        $Mail->setFrom('atendimento@agrobrasilseguros.com.br', 'AgroBrasil - Agronet 2.0');

        $Mail->addBcc([
            'danielle.goncalves@agrobrasilseguros.com.br',
            'ana.madeira@agrobrasilseguros.com.br'
        ]);

        if ($this->getRequest()->getParam('id_status') == Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_PENDENTE) {
            $subject = "Alerta de Pendência na Solicitação de Endosso: Proposta {$Proposta->doc()} / {$Proposta->ds_nome_proponente}";
        }

        if ($this->getRequest()->getParam('id_status') == Endosso_Model_Solicitacao::ID_STATUS_SOLICITACAO_ENDOSSO_NEGADO) {
            $subject = "Negativa na Solicitação de Endosso: Proposta {$Proposta->doc()} / {$Proposta->ds_nome_proponente}";
        }

        $body = $this->getCorpoEmail($Proposta, $Mail);
        $Mail->notificarCorretor($Proposta, $subject, $body, array('html' => true, 'obj_email' => $Mail), false);
    }


    private function getCorpoEmail($Proposta, $Mail)
    {
        $filename = RESOURCES . "/imagens/assinatura_email.png";
        $at = $Mail->createAttachment(file_get_contents($filename));
        $at->type = Agro_Util::getMimeType($filename);
        $at->disposition = Zend_Mime::DISPOSITION_INLINE;
        $at->encoding = Zend_Mime::ENCODING_BASE64;
        $at->id = 'cid_' . md5_file($filename);

        $body = "<p style=\"margin-bottom: 15px\">Prezado Corretor, </p>";

        if ($this->getRequest()->getParam('id_status') == 181) {
            $body .= "<p style=\"margin - bottom: 15px\">";
            $body .= "Informamos que a solicitação de endosso da proposta <b>{$Proposta->doc()}</b> em nome de <b>{$Proposta->ds_nome_proponente}</b> possui uma ou mais pendências, conforme motivo abaixo: ";
            $body .= "</p>";

            $body .= "<p style=\"margin-bottom: 15px\">";
            $body .= "Motivo: <b>{$this->getRequest()->getParam('ds_observacao')}</b><br/>";
            $body .= "Prazo: <b>".Agro_Util::somarDataDiasUteis(date('Y-m-d'), 4)."</b>";
            $body .= "</p>";

            $body .= "<p style=\"margin-bottom: 15px; font-weight: bold;\">";
            $body .= "Para evitar prejuízos ao Segurado, é imprescindível regularizar a pendência dentro do prazo. Para tanto, acesse o módulo de consultar solicitações no sistema. ";
            $body .= "</p>";
        }

        if ($this->getRequest()->getParam('id_status') == 183) {
            $body .= "<p style=\"margin - bottom: 15px\">";
            $body .= "Informamos que a solicitação de endosso da proposta <b>{$Proposta->doc()}</b> em nome de <b>{$Proposta->ds_nome_proponente}</b> foi negada, conforme motivo abaixo:";
            $body .= "</p>";

            $body .= "<p style=\"margin-bottom: 15px\">";
            $body .= "Motivo: <b>{$this->getRequest()->getParam('ds_observacao')}</b><br/>";
            $body .= "</p>";

            $body .= "<p style=\"margin-bottom: 15px; font-weight: bold;\">";
            $body .= "Alertamos que essa negativa deverá ser informada de imediato ao Segurado.";
            $body .= "</p>";
        }

        $modelSolicitacaoStatus = new Endosso_Model_SolicitacaoStatus();
        $retornoSolicitacaoStatus = $modelSolicitacaoStatus->getStatusBySolicitacao($this->getRequest()->getParam('id'))->current();

        $modelUsuarios = new Sistema_Model_Usuarios();
        $retornoUsuario = $modelUsuarios->getRow($retornoSolicitacaoStatus['id_usuario_criacao']);

        $body .= "<p style=\"margin-bottom: 15px;\">";
        $body .= "Ação de: <b>{$retornoUsuario['ds_nome_usuario']}</b>";
        $body .= "</p>";

        $body .= "<p style=\"margin-bottom: 15px\">";
        $body .= "Acesse o sistema Agronet 2.0 através do endereço: http://agronet.agrobrasilseguros.com.br/";
        $body .= "</p>";

        $body .= "<img src=\"cid:".$at->id."\" height=\"102\" width=\"480\" />";
        $body .= "<br />";
        $body .= "<span style=\"color: grey; margin: 0!important;  font-family: Verdana; font-size: .5em; text-align: left; display: block;\">";
        $body .= "<font face='webdings' style=\"color: darkgreen\">i</font> ";
        $body .= "<span style=\"color: darkblue\"> Este e-mail, inclusive anexos, podem conter informações confidenciais de propriedade exclusiva da AgroBrasil Seguros,";
        $body .= "<br />não devendo ser utilizado, copiado ou revelado sem prévia autorização.</span> This e-mail, including attachments, is intended<br /> for";
        $body .= "the person(s) or company named and may contain confidential and/or legally privileged information. Unauthorized<br /> disclosure,";
        $body .= "copying or use of this information may be unlawful and is prohibited. If you are not the intended recipient,<br /> please delete this";
        $body .= "message and notify the sender.";
        $body .= "</span>";
        $body .= "<br />";
        $body .= "<span style=\"color: grey; margin: 0!important; font-family: Verdana; font-size: .5em; text-align: left; display: block\">";
        $body .= "<font face='webdings'  style=\"color: darkgreen\">P</font> <span style=\"font-weight: bold\">Antes de imprimir, pense em seu compromisso com o Meio Ambiente.</span> Before printing, think about your<br /> commitment";
        $body .= "to the environment.";

        return $body;
    }

    public function dadosvalidarsubvencaoestadualAction()
    {
        $this->isAjax();

        try {
            if (empty($this->getRequest()->getParam('id_proposta'))) {
                throw new Zend_Controller_Action_Exception('ID proposta não informado.');
            }

            $this->_return['dadosValidacaoSubvencao'] = (new Endosso_Service_Questionario())->getDadosValidacaoSubvencaoEstadual(
                (int)$this->getRequest()->getParam('id_proposta')
            );
        } catch (Exception $exception) {
            $this->_return['erro'] = true;
            $this->_return['mensagem'] = $exception->getMessage();
        }

        $this->getResponse()->setBody(Zend_Json::encode($this->_return));
    }
}
