<?php
class Seguro_Model_ItensSeguradosCAR extends Agro_Db_Table_Abstract {
	protected $_name = 'itens_segurados_car';
	protected $_schema = 'seguro';
	protected $_primary = 'id';

    public function save(array $dados) :? int
    {
        $row = $this->createRow();

        $row->id_item_segurado = $dados['id_item_segurado'];
        $row->id_car = $dados['id_car'];
        $row->ds_car = Agro_Util::carUnmask($dados['ds_car']);
        $row->ds_status_imovel = $dados['ds_status_imovel'];
        $row->vl_area = $dados['vl_area'];
        $row->ds_condicao = $dados['ds_condicao'];
        $row->ds_uf = $dados['ds_uf'];
        $row->ds_municipio = $dados['ds_municipio'];
        $row->ds_tipo_imovel = $dados['ds_tipo_imovel'];
        $row->fl_manual = $dados['fl_manual'] ? 1 : 0;
        $row->fl_selecionado = $dados['fl_selecionado'] ? 1 : 0;
       
        return $row->save();
    }

    public function deleteByItemSegurado($idItemSegurado)
    {
        parent::delete($idItemSegurado, 'id_item_segurado');
    }

    public function deleteCarsManuais(int $idProposta, array $numerosItens)
    {
        $stringNumerosItens = implode(', ', $numerosItens);
        
        $this->_db->query("
            DELETE FROM seguro.itens_segurados_car
            WHERE
                id IN (
                    SELECT
                        sisc.id
                    FROM seguro.itens_segurados sis
                    INNER JOIN seguro.itens_segurados_car sisc
                        ON sisc.id_item_segurado = sis.id
                    WHERE
                        sis.id_proposta = {$idProposta}
                        AND sis.nr_item_segurado IN({$stringNumerosItens})
                        AND sisc.fl_manual IS TRUE
                )
        ");
    }

    public function unselect(int $idItemSegurado, bool $isCarApi = false)
    {
        $where = "id_item_segurado = {$idItemSegurado}";
        if ($isCarApi) {
            $where .= " AND fl_manual IS FALSE";
        }
        $this->update([
            'fl_selecionado' => 0
        ], $where);
    }

    /**
     * Retorna o código de imóvel (CAR) agrupados por itens da proposta informada
     *
     * @param int $idProposta
     * @return array
     */
    public function getCarAgrupadosPorItemByProposta(int $idProposta): array
    {
		$select = $this->select()->setIntegrityCheck(false);
        $select->from(['sis' => 'seguro.itens_segurados'], 'nr_item_segurado');
        $select->joinLeft(['sisc'=> "{$this->_schema}.{$this->_name}"], "sisc.id_item_segurado = sis.id", "array_to_string(ARRAY_AGG(sisc.ds_car), ',') as cars");
        $select->where("sis.id_proposta = ?", $idProposta);
        $select->group("sis.nr_item_segurado");
        $select->order("sis.nr_item_segurado");
        
        return $this->fetchAll($select)->toArray();
    }

    public function mapItemSeguradoCarsByProposta(
        int $idProposta,
        bool $isSelecionado = false,
        bool $isManual = false,
        string $chaveMapeamento = 'id_item_segurado'
    ): array {
        $select = $this->select()
            ->setIntegrityCheck(false)
            ->from(
                ['sis' => 'seguro.itens_segurados'],
                ['nr_item_segurado', 'id as id_item_segurado', 'vl_lmga']
            )
            ->join(
                ['sisc'=> "{$this->_schema}.{$this->_name}"],
                "sisc.id_item_segurado = sis.id",
                'id as id_car, ds_car, fl_manual, fl_selecionado'
            )
            ->where("sis.id_proposta = ?", $idProposta)
            ->order('nr_item_segurado');

        if ($isSelecionado) {
            $select->where('fl_selecionado IS TRUE');
        }

        if ($isManual) {
            $select->where('fl_manual IS TRUE');
        }

        $rs = $this->fetchAll($select);

        $map = [];

        foreach ($rs as $row) {
            $map[$row[$chaveMapeamento]][] = $row->toArray();
        }

        return $map;
    }

    public function getCarByNumeroItemSeguradoNumeroCar(int $idProposta, int $numeroItemSegurado, string $numeroCar)
    {
        return $this->fetchRow(
            $this->select()
                ->setIntegrityCheck(false)
                ->from(['sisc' => 'seguro.itens_segurados_car'])
                ->join(['sis' => 'seguro.itens_segurados'], 'sis.id = sisc.id_item_segurado', false)
                ->where('nr_item_segurado = ?', $numeroItemSegurado)
                ->where('id_proposta = ?', $idProposta)
                ->where('ds_car = ?', Agro_Util::carUnmask($numeroCar))
        );
    }

    public function getCarsByNumerosItens(int $idProposta, array $numerosItens): array
    {
        $select = $this->select()
            ->setIntegrityCheck(false)
            ->from(['sisc'=> "{$this->_schema}.{$this->_name}"])
            ->join(['sis'=> 'seguro.itens_segurados'], "sisc.id_item_segurado = sis.id", 'nr_item_segurado')
            ->where('sis.id_proposta = ?', $idProposta)
            ->where('sis.nr_item_segurado in (?)', $numerosItens);
        
        return $this->fetchAll($select)->toArray();
    }

    public function getCarByNumeroCar(int $idProposta, String $numeroCar)
    {
        $select = $this->select()
            ->setIntegrityCheck(false)
            ->from(['sisc'=> "{$this->_schema}.{$this->_name}"])
            ->join(['sis'=> 'seguro.itens_segurados'], "sisc.id_item_segurado = sis.id", false)
            ->where('ds_car = ?', Agro_Util::carUnmask($numeroCar))
            ->where('sis.id_proposta  = ?', $idProposta)
            ->limit(1);
        
        return $this->fetchRow($select);
    }

    public function getCarSelecionado(int $idItemSegurado)
    {
        $select = $this->select()
            ->setIntegrityCheck(false)
            ->from(['sisc'=> "{$this->_schema}.{$this->_name}"])
            ->where('id_item_segurado = ?', $idItemSegurado)
            ->where('fl_selecionado IS TRUE')
            ->limit(1);
        
        return $this->fetchRow($select);
    }
}
