<?php

class Produto_Model_ContratosResseguro extends Agro_Db_Table_Abstract
{
    protected $_schema = 'produto';
    protected $_name = 'contratos_resseguro';
    protected $_primary = 'id';
    public $_order = 'dt_inicio_vigencia';

    public function save(array $values)
    {
        $row = $this->getRow($values['id']);
        $row->ds_nome = $values['ds_nome'];
        $row->dt_inicio_vigencia = Agro_Util::formatDate($values['dt_inicio_vigencia'], Zend_Date::W3C);
        $row->dt_termino_vigencia = Agro_Util::formatDate($values['dt_termino_vigencia'], Zend_Date::W3C);
        $row->save();

        if (!$row) {
            throw new Exception("Erro ao salvar o contrato de resseguro.");
        }

        $this->vincularPropostas($row);

        return $row;
    }

    /**
     * Vincula todas as propostas que tenham emissão no período do contrato cadastrado
     *
     * @param Zend_Db_Table_Row $row
     */
    private function vincularPropostas(Zend_Db_Table_Row $row): void
    {
        $rsDelete = $this->_db->query("DELETE FROM seguro.propostas_contratos_resseguro WHERE id_contrato_resseguro = {$row['id']}");

        if (!$rsDelete) {
            throw new Exception("Erro remover o vinculo das propostas com o contrato de resseguro.");
        }

        $sqlTemp  = " CREATE temp TABLE tmp_emissao_apolice AS ( ";
        $sqlTemp .= "     SELECT min(ps.dt_criacao)::DATE AS dt_emissao_apolice ";
        $sqlTemp .= "           ,pr.id_proposta_mae AS id_proposta_mae ";
        $sqlTemp .= "       FROM seguro.propostas pr ";
        $sqlTemp .= "       JOIN seguro.propostas_status ps ON ps.id_proposta = pr.id ";
        $sqlTemp .= "       JOIN sistema.status st ON st.id = ps.id_status ";
        $sqlTemp .= "      WHERE st.ds_chave = '". Seguro_Model_Propostas::DS_CHAVE_APOLICE_EMITIDA ."' ";
        $sqlTemp .= "        AND pr.id = pr.id_proposta_mae ";
        $sqlTemp .= "      GROUP BY pr.id ";
        $sqlTemp .= " ); ";
        $rsTemp = $this->_db->query($sqlTemp);

        if (!$rsTemp) {
            throw new Exception("Erro ao buscar as propostas para vínculo com o contrato de resseguro.");
        }

        $idUsuario = !empty($row['id_usuario_alteracao']) ? $row['id_usuario_alteracao'] :$row['id_usuario_criacao'];
        $sqlInsert  = " INSERT INTO seguro.propostas_contratos_resseguro (id_proposta, id_contrato_resseguro, id_usuario_criacao, dt_criacao) ";
        $sqlInsert .= "   SELECT pr.id AS id_proposta";
        $sqlInsert .= "        ,{$row['id']} AS id_contrato_resseguro ";
        $sqlInsert .= "        ,{$idUsuario} AS id_usuario_criacao ";
        $sqlInsert .= "        ,now() AS dt_criacao ";
        $sqlInsert .= "     FROM seguro.propostas pr ";
        $sqlInsert .= "     JOIN tmp_emissao_apolice tea ON tea.id_proposta_mae = pr.id_proposta_mae ";
        $sqlInsert .= "    WHERE pr.id_status IN (". Seguro_Model_Propostas::ID_STATUS_APOLICE_EMITIDA .", ". Seguro_Model_Propostas::ID_STATUS_APOLICE_CANCELADA .") ";
        $sqlInsert .= "      AND dt_emissao_apolice BETWEEN '{$row['dt_inicio_vigencia']}' AND '{$row['dt_termino_vigencia']}'; ";
        $rsInsert = $this->_db->query($sqlInsert);

        if (!$rsInsert) {
            throw new Exception("Erro ao vincular as propostas com o contrato de resseguro.");
        }
    }

    /**
     * Valida se o período informado conflita com algum já cadastrado no banco
     *
     * @param string $dtInicioVigencia
     * @param string $dtFinalVigencia
     * @param int|null $id
     * @return bool
     */
    public function isPeriodoValido(string $dtInicioVigencia, string $dtTerminoVigencia, ?int $id = null): bool
    {
        $periodoValido = true;
        $dtInicioVigencia = Agro_Util::formatDate($dtInicioVigencia, 'yyyy-MM-dd');
        $dtTerminoVigencia = Agro_Util::formatDate($dtTerminoVigencia, 'yyyy-MM-dd');

        //Precisei adicionar/diminuir um dia nas datas pois a função OVERLAPS não considera o último dia do primeiro período como parte do intervalo.
        $sql  = " SELECT DISTINCT ";
        $sql .= "     ((dt_inicio_vigencia::date - INTERVAL '1 day')::date, (dt_termino_vigencia::date + INTERVAL '1 day')::date) ";
        $sql .= "  OVERLAPS ";
        $sql .= "     ('{$dtInicioVigencia}'::date, '{$dtTerminoVigencia}'::date) ";
        $sql .= "   FROM produto.contratos_resseguro ";
        
        if (!empty($id)) {
            $sql .= " WHERE id <> {$id}";
        }

        $rs = $this->_db->query($sql);

        foreach ($rs as $row) {
            if ($row['overlaps']) {
                $periodoValido = false;
                break;
            }
        }
        
        return $periodoValido;
    }

    public function delete($id, $field='id')
    {
        $modelPropostasContratosResseguro = new Seguro_Model_PropostasContratosResseguro();
        $modelPropostasContratosResseguro->delete($id, 'id_contrato_resseguro');
        return parent::delete($id, $field);
    }

    /**
     * Busca qual o Id de contrato que a proposta informada se encaixa
     *
     * @param int $idProposta
     * @return int|null
     */
    public function getIdContratoResseguroByProposta(int $idProposta): ?int
    {
        $idPropostaMae = (new Endosso_Model_Propostas())->getPropostaMae($idProposta);
        $subQuery  = "  (SELECT min(ps.dt_criacao)::date AS dt_emissao_apolice ";
        $subQuery .= "        ,pr.id_proposta_mae ";
        $subQuery .= "    FROM seguro.propostas pr ";
        $subQuery .= "    JOIN seguro.propostas_status ps ON ps.id_proposta = pr.id ";
        $subQuery .= "    JOIN sistema.status st ON st.id = ps.id_status ";
        $subQuery .= "   WHERE st.ds_chave = '". Seguro_Model_Propostas::DS_CHAVE_APOLICE_EMITIDA ."' ";
        $subQuery .= "     AND pr.id_proposta_mae = {$idPropostaMae}  ";
        $subQuery .= "   GROUP BY pr.id_proposta_mae )";

        $select = $this->select();
		$select->setIntegrityCheck(false);
		$select->from(['cr' => "{$this->_schema}.{$this->_name}"], ['id']);
        $select->join(['apolice' => new Zend_Db_Expr($subQuery)], "apolice.dt_emissao_apolice BETWEEN cr.dt_inicio_vigencia AND cr.dt_termino_vigencia", false);
        $idContratoResseguro = $this->getDefaultAdapter()->fetchOne($select);
        return !empty($idContratoResseguro) ? $idContratoResseguro : null;
    }

    public function getCombo($flVazio=true) {
		$Select = $this->select();
		$Select->Where('fl_ativo=true');
		//$Select->order('ds_nome_cultura ASC');

		$Rs = $this->fetchAll($Select);

		$options = array();
		if ($Rs->count()) {
		    if($flVazio){
			    $options[''] = '';
		    }
			foreach ($Rs as $row) {
				$options[$row['id']] = $row['ds_nome'];
			}

			return $options;
		} else {
			return false;
		}
	}
}
