<?php

class Seguro_Model_PropostasCroquisTalhoes extends Agro_Db_Table_Abstract
{
    protected $_log = true;
    protected $_schema = 'seguro';
    protected $_name = 'propostas_croquis_talhoes';
    protected $_primary = 'id';

    public function save($dados) {
        if (!$dados['id']) {
            $Row = $this->createRow();
        } else {
            $Row = $this->getRow($dados['id']);
        }

        $Row->id_croqui = $dados['id_croqui'];
        $Row->ds_coordenadas = $dados['ds_coordenadas'];
        $Row->fl_area = $dados['fl_area'];
        $Row->ds_nome = preg_replace('/\s+/', ' ', $dados['ds_nome']);
        $Row->ds_item_segurado = $dados['ds_item_segurado'];

        if (array_key_exists('ds_coordenadas_centroide', $dados)) {
            $Row->ds_coordenadas_centroide = $dados['ds_coordenadas_centroide'];
        }

        return $Row->save();
    }

	public function centroidesIguais($lat1, $lon1, $lat2, $lon2)
	{
		$select = " SELECT
			ST_DWithin(
				ST_SetSRID(ST_MakePoint({$lon1}, {$lat1}), 4326),
				ST_SetSRID(ST_MakePoint({$lon2}, {$lat2}), 4326),
				0.00001
			) AS iguais
			";

		return $this->_db->fetchRow($select)['iguais'];
	}

    /**
	 * Verifica se todos os itens da proposta estão no croqui
	 */
	public function verificaItemCroqui(int $id_proposta, int $id_croqui, string &$motivo='') : bool {

		$it = $tl = $atl = array();

		$Itens = (new Seguro_Model_ItensSegurados())->fetchAll("id_proposta = $id_proposta")->toArray();
		$Talhoes = $this->fetchAll("id_croqui = $id_croqui")->toArray();

		foreach ($Itens as $item) {
			array_push($it, $item['id']);
		}

		foreach ($Talhoes as $talhao) {
			$atl = explode(',', $talhao['ds_item_segurado']);
			foreach ($atl as $x) {
				array_push($tl, $x);
			}
		}

		if (count((array_diff($tl,$it))) > 0) {
			$motivo = 'POLIGONO';
			return false;
		}

		if (count((array_diff($it,$tl))) > 0) {
			$motivo = 'ITEM';
			return false;
		}

		return true;
	}

	public function verificaItemCroquiSolicitacao(int $id_proposta, int $id_croqui) : bool {
		$it = $tl = $atl = array();

		$Itens = (new Seguro_Model_ItensSegurados())->fetchAll("id_proposta = $id_proposta")->toArray();
		$Talhoes = $this->fetchAll("id_croqui = $id_croqui")->toArray();

		foreach ($Itens as $item) {
			array_push($it, $item['id']);
		}

		foreach ($Talhoes as $talhao) {
			if (!empty($talhao['ds_item_segurado'])) {
				$atl = explode(',', $talhao['ds_item_segurado']);
				foreach ($atl as $x) {
					array_push($tl, $x);
				}
			}
		}

		if (count(array_diff($tl,$it)) > 0) {
			return false;
		}

		if (count(array_diff($it,$tl)) > 0) {
			return false;
		}

		return true;
	}

	// comentado para poder enviar todos croquis em todos itens até que uma solução definitiva seja implementada
	public function getByCroquiIdItemSegurado(int $id_proposta, int $id_item_segurado = null, bool $bo_first=false) {
		$select = $this->select()->setIntegrityCheck(false)
			->from(array('pc' => 'seguro.propostas_croquis'), array('id_proposta', 'id as id_croqui','fl_vigente'))
			->join(
				array('pct' => 'seguro.propostas_croquis_talhoes'),
				'pc.id = pct.id_croqui',
				array(
					'id',
					'id_croqui',
					"trim(regexp_replace(ds_nome, '\s+', '', 'g')) as ds_nome",
					'ds_coordenadas',
					'ds_item_segurado',
					'ds_coordenadas_centroide'
				)
			);

		if (!empty($id_item_segurado)) {
			$select->where("$id_item_segurado::varchar = any(string_to_array(pct.ds_item_segurado,','))");
		}

		$select->where('pc.id_proposta = ?', $id_proposta)
			->where('pc.fl_vigente = true');

		return $this->getAdapter()->fetchAll($select);
	}

	/**
	 * Busca as coordenadas do croqui de acordo com a proposta e a descrição do item informados
	 *
	 * @param int $idProposta
	 * @param string $dsItemSegurado
	 */
	public function getByDsItemSegurado(int $idProposta, string $dsItemSegurado)
	{
		$select = $this->select()->setIntegrityCheck(false)
			->from(['pc' => 'seguro.propostas_croquis'], ['id_proposta', 'id as id_croqui','fl_vigente'])
			->join(
				['pct' => 'seguro.propostas_croquis_talhoes'],
				'pc.id = pct.id_croqui',
				[
					'id',
					'id_croqui',
					"trim(regexp_replace(ds_nome, '\s+', '', 'g')) as ds_nome",
					'ds_coordenadas',
					'ds_item_segurado'
				]
			)
			->where('pc.id_proposta = ?', $idProposta)
			->where('pc.fl_vigente = true')
			->where("trim(regexp_replace(pct.ds_nome, '\s+', '', 'g')) = trim(regexp_replace('{$dsItemSegurado}', '\s+', '', 'g'))");

		return $this->getAdapter()->fetchAll($select);
	}



	public function getByCroquiIdItemSeguradoSolicitacao(int $id_proposta, string $ds_item_segurado) {

		$select = $this->select()->setIntegrityCheck(false)
			->from(array('pc' => 'seguro.propostas_croquis'), array('id_proposta', 'id as id_croqui', 'fl_vigente'))
			->join(array('pct' => 'seguro.propostas_croquis_talhoes'), 'pc.id = pct.id_croqui',
				array('id', "trim(regexp_replace(ds_nome, '\s+', '', 'g')) as ds_nome", 'ds_coordenadas'))
			->join(array('pes' => 'seguro.propostas_endosso_solicitacao'), 'pc.id_proposta = pes.id_proposta', false)
			->join(array('pesc' => 'seguro.propostas_endosso_solicitacao_croqui'), 'pc.id = pesc.id_croqui', false)
			//->where("trim(regexp_replace(pct.ds_nome, '\s+', '', 'g')) = trim(regexp_replace('$ds_item_segurado', '\s+', '', 'g'))")
			->where('pc.id_proposta = ?', $id_proposta)
			->where('pc.fl_vigente = false')
			->where('pes.id_status = 198')
			->order('pct.id desc');
			//->limit(1);

		return $this->getAdapter()->fetchAll($select);
	}

	public function getByCroquiIdItemSeguradoSolicitacaoByItem(int $id_proposta, int $nr_item) {
		$sql = "SELECT * 
				  FROM (
					  	SELECT pc.id_proposta
							, pc.id AS id_croqui
							, row_number() over (partition by pc.id_proposta order by pesc.dt_criacao desc) AS nr_item
							, pct.id, trim(regexp_replace(ds_nome, '\s+', '', 'g')) AS ds_nome
							, pct.ds_coordenadas 
						FROM seguro.propostas_croquis AS pc
					INNER JOIN seguro.propostas_croquis_talhoes AS pct ON pc.id = pct.id_croqui
					INNER JOIN seguro.propostas_endosso_solicitacao AS pes ON pc.id_proposta = pes.id_proposta
					INNER JOIN seguro.propostas_endosso_solicitacao_croqui AS pesc ON pc.id = pesc.id_croqui 
						WHERE pc.id_proposta = $id_proposta
						AND pc.fl_vigente = false 
						AND pes.id_status = 198
					ORDER BY pes.dt_criacao desc
				) AS it
				 WHERE nr_item = $nr_item";

		return $this->getAdapter()->fetchAll($sql);
	}

	/**
	 * Busca o centroide cadastrado nos talhões da proposta
	 * @param int $idProposta
	 * @param int $nrItem
	 */
	public function getCentroidesByProposta(int $idProposta, int $nrItem = null)
	{
		$where = ["sis.id_proposta = {$idProposta}", "spc.fl_vigente is true"];

		if (!empty($nrItem)) {
			$where[] = "is.nr_item_segurado = {$nrItem}";
		}

		$where = implode(" AND ", $where);
		$sql = " SELECT spct.ds_coordenadas_centroide,
						sis.id,
		         	    sis.nr_item_segurado
		           FROM seguro.propostas_croquis spc
		           JOIN seguro.itens_segurados sis ON sis.id_proposta = spc.id_proposta
		           JOIN seguro.propostas_croquis_talhoes spct ON spct.id_croqui = spc.id AND spct.ds_nome = sis.ds_item_segurado
		          WHERE {$where}
		          GROUP BY spct.id, spct.ds_coordenadas_centroide, spct.ds_coordenadas, sis.nr_item_segurado, sis.id
		          ORDER BY sis.nr_item_segurado";

		return $this->getAdapter()->fetchAll($sql);
	}

    /**
     * Exemplo de array:
     * Array (
     *   [0] => -23.796842336216613 -48.836679277265624
     *   [1] => -23.80391016137946 -48.83599263175781
     *   [2] => -23.80351751451467 -48.828439531171874
     *   [3] => -23.796214066481784 -48.82878285392579
     *   [4] => -23.796842336216613 -48.836679277265624
     * )
     * Cada posição do array contêm primeiro a latitude e depois a longitude. A última posição deve ser a mesma da primeira,
     * obrigatoriamente
     *
     * @param array $coordenadas
     * @return array|false|string[]
     */
    public function getCentroide(array $coordenadas)
    {
        if (empty($coordenadas)) {
            return [];
        }

        $row = $this->_db->fetchRow("SELECT ST_AsText(ST_PointOnSurface('POLYGON((" . implode(',', $coordenadas) . "))'::geometry)) as coordenadas");

        return explode(' ', trim(str_replace(')', '', str_replace('POINT(', '', $row['coordenadas']))));
    }
}
