<?php

class Produto_Model_ProdutosCoberturas extends Agro_Db_Table_Abstract {
	protected $_schema = 'produto';
	protected $_name = 'produtos_coberturas';
	protected $_primary = array('id_produto', 'id_cobertura');
	protected $_rowClass = 'Produto_Model_Row_ProdutoCobertura';
	protected $_sequence = false;

	public function getData($where = false) {
		$select = $this->select();
		$select->setIntegrityCheck(false);
		$select->from(array('pc' => 'produto.produtos_coberturas'), '*');
		$select->join(array('c' => 'produto.coberturas'), 'pc.id_cobertura = c.id', array('ds_nome_cobertura', 'cd_cob_seguradora' => 'cd_cobertura_seguradora'));
		$select->joinLeft(array('cob' => 'produto.coberturas'), 'pc.id_cobertura_dependencia = cob.id', 'ds_nome_cobertura as ds_nome_cobertura_dependente');

		if (is_array($where)) {
			foreach ($where as $clause) {
				$field = $clause['field'];
				$operator = $clause['operator'];
				$value = $clause['value'];

				$select->where("$field $operator ?", $value);
			}

		} elseif ($where != '') {
			$select->where($where);
		}

		if ($this->_order) {
			$select->order('c.ds_nome_cobertura');
		}

		return $select;
	}

	public function getCoberturasDependentes($idProduto) {
		$Select = $this->select()->distinct(true)->setIntegrityCheck(false);
		$Select->from(array('pc' => 'produto.produtos_coberturas'));
		$Select->join(array('c' => 'produto.coberturas'), 'pc.id_cobertura = c.id');
		$Select->where("fl_cobertura_dependente = false");
		$Select->where("pc.id_produto = ?", $idProduto);
		$Select->order('ds_nome_cobertura');
		$Rs = $this->fetchAll($Select);

		$options = array();
		if ($Rs->count()) {
			foreach ($Rs as $Row) {
				$options[$Row->id_cobertura] = $Row->ds_nome_cobertura;
			}
		}

		return $options;
	}

	public function getCombo($first = true, $field = NULL) {
		$comercializacao = new Zend_Session_Namespace('comercializacao');
		$Select = $this->select();
		$Select->setIntegrityCheck(false);
		$Select->from(array('c'=>'produto.coberturas'), array('id', 'ds_nome_cobertura'));
		$Select->join(array('pc'=>'produto.produtos_coberturas'), 'pc.id_cobertura = c.id', null);
		$Select->join(array('co'=>'comercializacao.comercializacoes'), 'pc.id_produto = co.id_produto', null);
		$Select->where('co.id = ?', $comercializacao->id);
		$Rs = $this->fetchAll($Select, 'ds_nome_cobertura')->toArray();
		if (is_array($Rs)) {
			$options[] = null;
			foreach ($Rs as $row) {
				$options[$row['id']] = $row['ds_nome_cobertura'];
			}

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

	public function fetchCoberturas($idCobertura, $idComercializacao) {
		$Select = $this->select();
		$Select->setIntegrityCheck(false);
		$Select->from(array('pc'=>'produto.produtos_coberturas'), '*');
		$Select->join(array('c'=>'produto.coberturas'), 'pc.id_cobertura = c.id', 'ds_nome_cobertura');
		$Select->join(array('t'=>'comercializacao.taxas'), 'pc.id_cobertura = t.id_cobertura', 'vl_franquia');
		$Select->where('pc.fl_cobertura_principal = true', null);
		$Select->where('t.fl_cobertura_principal = ?', $idComercializacao);

		return $this->fetchAll($Select)->toArray();
	}

	public function mostraRelacionados($idCobertura) {
		$agrupamento = new Zend_Session_Namespace('agrupamento');

		$Select = $this->select();
		$Select->setIntegrityCheck(false);
		$Select->from(array('a'=>'comercializacao.taxas_agrupamento'), null);
		$Select->join(array('p'=>'produto.produtos'), 'a.id_produto = p.id', null);
		$Select->join(array('pc'=>'produto.produtos_coberturas'), 'pc.id_produto = p.id', 'fl_taxa_relacionada');
		$Select->where('pc.fl_cobertura_principal is false', '');
		$Select->where('pc.id_cobertura = ?', $idCobertura);
		$Select->where('a.id = ?', $agrupamento->id);

		$Row = $this->fetchRow($Select);
		return $Row['fl_taxa_relacionada'];
	}

	public function remove($idProduto, $idCobertura) {
		if (
			$this->_db->query("delete from produto.produto_cobertura_config where id_produto = $idProduto and id_cobertura = $idCobertura")
			&& $this->_db->query("delete from produto.produtos_coberturas where id_produto = $idProduto and id_cobertura = $idCobertura")
		) {
			return true;
		} else {
			return false;
		}
	}

	public function getCoberturaPrincipal($idProduto, $idCobertura="") {
		$Select = $this->select()->setIntegrityCheck(false);
		$Select->from(array('c'=>'produto.coberturas'));
		$Select->join(array('pc'=>'produto.produtos_coberturas'), 'c.id = pc.id_cobertura');
		$Select->where('pc.id_produto = ?', $idProduto);
		if ($idCobertura) {
			$Select->where('pc.id_cobertura = ?', $idCobertura);
		} else {
			$Select->where('pc.fl_cobertura_principal is true', '');
		}

		return $this->fetchRow($Select);
	}

	public function getCoberturaAdicionais($idProduto, $agrupamento) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->join(array('c'=>'produto.coberturas'), 't.id_cobertura = c.id', array('id','ds_nome_cobertura'));
		$Select->join(array('pc'=>'produto.produtos_coberturas'), 'pc.id_cobertura = c.id');
		$Select->where('pc.fl_cobertura_principal is false', '');
		$Select->where('pc.id_produto = ?', $idProduto);
		$Select->order('ds_nome_cobertura');

		return $this->fetchAll($Select);
	}

	public function getCoberturasPrevia($idProduto,$idProposta="") {
		$Select = $this->select()->distinct(true)->setIntegrityCheck(false);
		$Select->from(array('pc' => 'produto.produtos_coberturas'));
		$Select->join(array('prc'=>'seguro.propostas_coberturas'), 'prc.id_cobertura = pc.id_cobertura');

		if (!empty($idProposta)) {
			$Select->where("prc.id_proposta = ?", $idProposta);
		}
		
		$Select->where("pc.fl_vistoria_previa = true");
		$Select->where("pc.id_produto = ?", $idProduto);
		
		$Rs = $this->fetchAll($Select);

		if ($Rs->count()) {
			return true;
		}
		return false;
	}

	public function save(array $data) {
		$id_produto = null;
		
		if (!$data['id_produto']) {
			//Recupera nome da cobertura pra adicionar no e-mail de aviso de alteração.
			$ModelCobertura = new Produto_Model_Coberturas();
			$Cobertura = $ModelCobertura->find($data['id_cobertura'])->current()->toArray();

			//Recupera nome do produto para adicionar no e-mail de aviso de alteração
			$ModelProduto = new Produto_Model_Produtos();
			$arr = explode(',',$data['id']);
			$id_produto = $arr[0];
			$Produto = $ModelProduto->find($id_produto)->current()->toArray();
		}

		try {
			if (!$data["id_produto"]){
				if (strpos($data["id"], ",")){
					$id = explode(",", $data['id']);
					$data['id_produto'] = $id[0];

				} else {
					$data["id_produto"] = $data["id"];
				}
			}

			// Busca ou cria um registro para a insercao ou alteracao
			$Row = $this->find($data['id_produto'], $data['id_cobertura'])->current();
			if (!$Row) $Row = $this->createRow();

			/**
			 * Verifica se é a cobertura principal e coloca para 0 todas as outras
			 * Analiza se deve ou não exibir na regulação de perdas
			 */
			if ($data['fl_cobertura_principal']) {
				$this->update(array('id_usuario_alteracao' => Zend_Auth::getInstance()->getIdentity()->id, 'dt_alteracao' => 'now()', 'fl_cobertura_principal'=> 0), "id_produto = {$data['id_produto']}");
				$Row->fl_exibir_regulacao_perdas = 1;

			} else {
				if ($data['fl_vistoria_preliminar'] || $data['fl_vistoria_final']){
					$Row->fl_exibir_regulacao_perdas = 1;

				} elseif ($data['id_tipo_liquidacao']){
					$CoberturaPrincipal = $this->getCoberturaPrincipal($data['id_produto']);

					if ($data['id_tipo_liquidacao'] == $CoberturaPrincipal->id_tipo_liquidacao){
						$Row->fl_exibir_regulacao_perdas = 0;

					} else {
						$Row->fl_exibir_regulacao_perdas = 1;
					}

				} else {
					$Row->fl_exibir_regulacao_perdas = 0;
				}
			}

			$Row->id_produto = $data['id_produto'];
			$Row->id_cobertura = $data['id_cobertura'];
			//$Row->id_condicao_especial = ($data['id_condicao_especial'] ? $data['id_condicao_especial'] : null);
			$Row->fl_cobertura_principal = ($data['fl_cobertura_principal'] ? 1 : 0);
			$Row->fl_taxa_relacionada = ($data['fl_taxa_relacionada'] ? 1 : 0);
			$Row->fl_ativo = ($data['fl_ativo'] ? 1 : 0);
			$Row->fl_somente_renovacoes = ($data['fl_somente_renovacoes'] ? 1 : 0);
			$Row->fl_vistoria_previa = ($data['fl_vistoria_previa'] ? 1 : 0);
			$Row->fl_vistoria_final = ($data['fl_vistoria_final'] ? 1 : 0);
			$Row->fl_vistoria_preliminar = ($data['fl_vistoria_preliminar'] ? 1 : 0);
			$Row->fl_validar_capacidade = ($data['fl_cobertura_principal'] == 1 ? 1 : ($data['fl_validar_capacidade'] ? 1 : 0));
			$Row->fl_cobertura_dependente = ($data['fl_cobertura_dependente'] ? 1 : 0);
			$Row->fl_exibir_franquia = ($data['fl_exibir_franquia'] ? 1 : 0);
			$Row->id_cobertura_dependencia = ($data['id_cobertura_dependencia'] ? $data['id_cobertura_dependencia'] : null);
			$Row->vl_lmi = ($data['vl_lmi'] ? $data['vl_lmi'] : null);
			$Row->fl_contratacao_automatica = ($data['fl_contratacao_automatica'] ? 1 : 0);
			$Row->id_tipo_laudo_preliminar = ($data['id_tipo_laudo_preliminar'] ? $data['id_tipo_laudo_preliminar'] : null);
			$Row->id_tipo_laudo_final = ($data['id_tipo_laudo_final'] ? $data['id_tipo_laudo_final'] : null);
			$Row->id_tipo_liquidacao = ($data['id_tipo_liquidacao'] ? $data['id_tipo_liquidacao'] : null);
			$Row->cd_cobertura_seguradora = ($data['cd_cobertura_seguradora'] ? $data['cd_cobertura_seguradora'] : null);
			$Row->fl_transmitir_tagh = ($data['fl_transmitir_tagh'] ? 1 : 0);
			$Row->ds_observacao_interna = ($data['ds_observacao_interna'] ? $data['ds_observacao_interna'] : null);
			$Row->ds_observacao = ($data['ds_observacao'] ? $data['ds_observacao'] : null);

			if ($data['fl_assinatura_segurado'] !== null) {
				$Row->fl_assinatura_segurado = ($data['fl_assinatura_segurado'] ? 1 : 0);
			}

			//se a cobertura for principal, obriga que a validação de capacidade seja feita na mesma
			if($data['fl_cobertura_principal']){
				$Row->fl_validar_capacidade = true;
			} else {
				$Row->fl_validar_capacidade = ($data['fl_validar_capacidade'] ? 1 : 0);
			}
			
			if($Row->save() and is_array($data['id_condicao_especial'])){
				(new Produto_Model_ProdutosCoberturasCondicoesEspeciais())->save(
					$data['id_produto'],
					$data['id_cobertura'],
					$data['id_condicao_especial']
				);

				$configuracaoDataCorte = (new Produto_Model_ConfiguracaoDataCorte())
					->find($data['id_configuracao_data_corte'])
					->current();
				
				$idProdutoCoberturaConfig = (new Produto_Model_ProdutoCoberturaConfig())->save([
					'id_produto' => $Row->id_produto,
					'id_cobertura' => $Row->id_cobertura,
					'ds_frase_outros_riscos_excluidos' => ($data['ds_frase_outros_riscos_excluidos']
						? $data['ds_frase_outros_riscos_excluidos']
						: null
					),
					'ds_frase_condicoes_particulares' => ($data['ds_frase_condicoes_particulares']
						? $data['ds_frase_condicoes_particulares']
						: null
					),
					'dt_inicio_validade' => $configuracaoDataCorte['dt_corte']
				]);
				
				if (empty($idProdutoCoberturaConfig)) {
					throw new Exception('Erro ao salvar configuração da cobertura.');
				}

				$To = 'tiago.zschornack@agrobrasilseguros.com.br';
				$Cc = 'tonismar.bernardo@agrobrasilseguros.com.br';
				$Cc1 = 'marcia.correa@agrobrasilseguros.com.br';

				$assunto = "Alteração ou Inclusão de Cobertura {$Cobertura['ds_nome_cobertura']} (Id: {$Row->id_cobertura}) para o Produto {$Produto['ds_nome_produto']} (Id: {$Produto['id']})";
				$content = "\nInformamos que a cobertura {$Cobertura['ds_nome_cobertura']} (Id: {$Row->id_cobertura}) para o produto {$Produto['ds_nome_produto']} (Id: {$Produto['id']}) foi cadastrada ou alterada pelo usuário: ".Zend_Auth::getInstance()->getIdentity()->ds_nome_usuario.".\n";
				$content .= "Provavelmente é necessário avaliar as configurações de Laudos de Sinistro para seu correto funcionamento.\n\n";
				$Mail = new Agro_Mail();
				$Mail->addTo($To);
				$Mail->addCc($Cc);
				$Mail->addCc($Cc1);
				$Mail->setTipoUsuario('Usuário');
				$Mail->setBody($content);
				$Mail->setSubject($assunto);
				if ($id_produto) {
					$Mail->send();
				}

				return true;
			}
			
			return false;
		} catch (Exception $e) {
			$this->setMessage($e->getMessage());
			return false;
		}
	}

	public function getFlVistoriaPreliminar($idProduto, $idCobertura) {
		$Select = $this->select()->distinct(true)->setIntegrityCheck(false);
		$Select->from('produto.produtos_coberturas', 'fl_vistoria_preliminar');
		$Select->where("id_cobertura = ?", $idCobertura);
		$Select->where("id_produto = ?", $idProduto);

		return $this->_db->fetchOne($Select);
	}


	public function getTipoLiquidacaoByProduto($idProduto, $idProposta) {

		$alias = new Zend_Db_Expr("(SELECT
									distinct
									        pc.id_tipo_liquidacao,
											tl.ds_chave,
											CASE WHEN tl.ds_chave <> 'LIQ05' THEN
												array_to_string(array_agg(co.ds_nome_cobertura::text) OVER (PARTITION BY pc.id_tipo_liquidacao), ', ') 
											ELSE co.ds_nome_cobertura END AS coberturas,
									        co.id
									FROM
									          produto.produtos_coberturas AS pc
									    INNER JOIN sinistro.tipo_liquidacao AS tl ON tl.id = pc.id_tipo_liquidacao
									    INNER JOIN produto.coberturas AS co ON co.id = pc.id_cobertura
									WHERE
									    (pc.id_produto = ".$idProduto.") 
										AND (pc.id_tipo_liquidacao is not null)
										AND pc.id_cobertura in (select id_cobertura from seguro.propostas_coberturas where id_proposta=".$idProposta.")
									)");

		$Select = $this->select()->distinct(true)->setIntegrityCheck(false);
		$Select->from(array('liq' => $alias), array('liq.id_tipo_liquidacao', 'liq.ds_chave', 'liq.coberturas', 'min(liq.id) as id_cobertura'));
		$Select->group(array('liq.id_tipo_liquidacao','liq.ds_chave','liq.coberturas'));

		return $this->_db->fetchAll($Select);
	}

	public function getTipoLiquidacao($id_produto, $id_cobertura){
		$ModelTipoLiquidacao = new Sinistro2_Model_TipoLiquidacao();

		$Row = $this->find($id_produto, $id_cobertura)->current();

		$TipoLiquidacao = false;

		if($Row){
			$RowTL = $ModelTipoLiquidacao->find($Row->id_tipo_liquidacao)->current();

			$TipoLiquidacao = array("id_tipo_liquidacao" 		=> $RowTL->id,
									"ds_nome_tipo_liquidacao" 	=> $RowTL->ds_nome_tipo_liquidacao,
									"ds_chave" 					=> $RowTL->ds_chave,
									"fl_liquidacao_avulsa" 		=> $RowTL->fl_liquidacao_avulsa,
									"fl_liquidacao_manual" 		=> $RowTL->fl_liquidacao_manual
							  );
		}

		return $TipoLiquidacao;

	}

	/**
	 * Retorna as coberturas de um produto de acordo com a flag da Taxa Relacionada
	 *
	 * @param int $idProduto
	 * @param bool $flTaxaRelacionada
	 * @param array|null $idsCoberturas
	 */
	public function getCoberturasTaxaRelacionada(int $idProduto, bool $flTaxaRelacionada = false, ?array $idsCoberturas = null): array
	{
		$select = $this->select()->setIntegrityCheck(false);
		$select->from(['pc' => 'produto.produtos_coberturas'], ['id_cobertura']);
		$select->where('pc.id_produto = ?', $idProduto);
		$select->where('pc.fl_taxa_relacionada = ?', $flTaxaRelacionada ? 't' : 'f');

		if (!empty($idsCoberturas)) {
			$ids = implode(', ', $idsCoberturas);
			$select->where("pc.id_cobertura IN ({$ids})");
		}
		
		return $this->fetchAll($select)->toArray();
	}

	/**
	 * Retorna o código da cobertura de acordo com o de/para de ids antigos da cobertura e os novos (válidos a partir de 2025)
	 *
	 * @param int $idProposta
	 * @param int $cdCoberturaSeguradora
	 * @return int
	 */
	public static function deParaI4Pro(int $idProposta, int $cdCoberturaSeguradora): int
	{
		$sql = "SELECT produto.de_para_coberturas_i4pro({$idProposta}, {$cdCoberturaSeguradora});";
		return Agro_Db_Table_Abstract::getDefaultAdapter()->fetchOne($sql);
	}

	/**
	 * Retorna o código da cobertura de acordo com o ID do Aviso informado
	 *
	 * @param int $idAviso
	 * @return int
	 */
	public static function getCoberturaI4ProByAviso(int $idAviso): int
	{
		$sql = "SELECT produto.get_cobertura_i4pro_by_aviso({$idAviso});";
		return Agro_Db_Table_Abstract::getDefaultAdapter()->fetchOne($sql);
	}
}
