<?php

class Produto_Model_GestaoComissao extends Agro_Db_Table_Abstract
{
    protected $_schema = 'produto';
    protected $_name = 'gestao_comissao';
    protected $_primary = 'id';

    /**
     * Retorna qual comissão deve ser utilizada de acordo com a proposta informada
     *
     * @param int $idProposta
     * @return array|null
     */
    public function getComissaoByProposta(int $idProposta): ?array
    {
        $modelPropostas = new Seguro_Model_Propostas();
        $proposta = $modelPropostas->find($idProposta)->current();
        $produto = $proposta->produto();
        $propriedade = $proposta->propriedade();

        return $this->getComissao(
            $proposta['id_usuario_criacao'],
            $produto['id'],
            $propriedade['id_estado']
        );
    }

    /**
     * Executa a consulta na base para buscar qual comissão deve ser utilizada
     *
     * @param int $idUsuario
     * @param int $idProduto
     * @param int $idEstado
     * @return array|null
     */
    public function getComissao(int $idUsuario, int $idProduto, int $idEstado): ?array
    {
        $select = $this->select()->distinct(true)->setIntegrityCheck(false);
        $select->from(['gc' => "{$this->_schema}.{$this->_name}"]);
        $select->join(['gce' => 'produto.gestao_comissao_estados'], 'gce.id_gestao_comissao = gc.id', 'id_estado');
        $select->join(['gcp' => 'produto.gestao_comissao_produtos'], 'gcp.id_gestao_comissao = gc.id', 'id_produto');
        $select->joinLeft(['gcu' => 'produto.gestao_comissao_usuarios'], 'gcu.id_gestao_comissao = gc.id', 'id_usuario');
        $select->joinLeft(['prep' => 'sistema.prepostos'], 'prep.id_usuario = gcu.id_usuario', ['ds_nome_preposto']);
        $select->joinLeft(['cor' => 'sistema.corretores'], 'cor.id_usuario = gcu.id_usuario', ['ds_nome_corretor']);
        $select->joinLeft(['e' => 'sistema.estados'], 'e.id = gce.id_estado', false);
        $select->joinLeft(['pp' => 'produto.produtos'], 'pp.id = gcp.id_produto', false);
        $select->where("(gcu.id_usuario = {$idUsuario} OR gcu.id IS NULL)");
        $select->where('gce.id_estado = ?', $idEstado);
        $select->where('gcp.id_produto = ?', $idProduto);
        $select->where('gc.fl_ativo is true');
        $select->order('gc.id DESC');

        $rs = Agro_Db_Table_Abstract::getDefaultAdapter()->fetchRow($select);

        return !empty($rs) ? $rs : [];
    }

    public function getData($where = false)
    {
        $select = $this->select()->distinct(true)->setIntegrityCheck(false);
        $select->from(['gc' => "{$this->_schema}.{$this->_name}"]);
        $select->join(['gcc' => 'produto.gestao_comissao_culturas'], 'gcc.id_gestao_comissao = gc.id', false);
        $select->joinLeft(['gcu' => 'produto.gestao_comissao_usuarios'], 'gcu.id_gestao_comissao = gc.id', false);
        $select->joinLeft(['gce' => 'produto.gestao_comissao_estados'], 'gce.id_gestao_comissao = gc.id', false);
        $select->joinLeft(['gcp' => 'produto.gestao_comissao_produtos'], 'gcp.id_gestao_comissao = gc.id', false);

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

                    if ($operator === 'in') {
                        $select->where("$field $operator $value");
                    } else {
                        $select->where("$field $operator ?", $value);
                    }
                } else {
                    $select->where($clause, '');
                }
            }
        } elseif ($where != '') {
            $select->where($where);
        }

        $select->order('gc.id');

        return $select;
    }

    /**
     * Retorna os vínculos da gestão de comissão
     *
     * @param int $idGestaoComissao
     */
    public function getVinculosByGestaoComissao(int $idGestaoComissao): array
    {
        $select = $this->select()->distinct(true)->setIntegrityCheck(false);
        $select->from(['gc' => "{$this->_schema}.{$this->_name}"]);
        $select->join(['gcc' => 'produto.gestao_comissao_culturas'], 'gcc.id_gestao_comissao = gc.id', 'id_cultura');
        $select->joinLeft(['gcu' => 'produto.gestao_comissao_usuarios'], 'gcu.id_gestao_comissao = gc.id', 'id_usuario');
        $select->joinLeft(['gce' => 'produto.gestao_comissao_estados'], 'gce.id_gestao_comissao = gc.id', 'id_estado');
        $select->joinLeft(['gcp' => 'produto.gestao_comissao_produtos'], 'gcp.id_gestao_comissao = gc.id', 'id_produto');
        $select->where("gc.id = ?", $idGestaoComissao);
        $select->order('gc.id');

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

    public function save(array $dados)
    {
        $row = $this->getRow($dados['id']);
        $row->ds_descricao = !empty($dados['ds_descricao']) ? $dados['ds_descricao'] : $row->ds_descricao;
        $row->vl_comissao = !empty($dados['vl_comissao']) ? $dados['vl_comissao'] : $row->vl_comissao;
        $row->id_safra = !empty($dados['id_safra']) ? $dados['id_safra'] : $row->id_safra;
        $row->save();

        return $row;
    }

    /**
     * Retorna todas as gestões de comissão conflitantes
     *
     * @param array $produtos
     * @param array $ufs
     * @param array|null $usuarios
     * @param int|null $desconsiderarIdGestaoComissao
     * @return array
     */
    public function getConfiguracoesConflitantes(array $produtos, array $ufs, ?array $usuarios, ?int $desconsiderarIdGestaoComissao = null): array
    {
        $produtos = implode(", ", $produtos);
        $ufs = implode(", ", $ufs);

        $where = [
            "gcp.id_produto IN ({$produtos})",
            "gce.id_estado IN ({$ufs})",
        ];

        if (!empty($usuarios)) {
            $usuarios = implode(", ", $usuarios);
            $where[] = "gcu.id_usuario IN ({$usuarios})";
        }

        if (!empty($desconsiderarIdGestaoComissao)) {
            $where[] = "gc.id <> {$desconsiderarIdGestaoComissao}";
        }

        $where = implode(" AND ", $where);

        $sql = $this->getData($where);
        return $this->fetchAll($sql)->toArray();
    }

    /**
     * Deleta primeiro os vínculos antes de deletar a comissão
     *
     * @param int $id
     * @param string $field
     */
    public function delete($id, $field = 'id')
    {
        $this->deleteVinculos($id);
        return parent::delete($id, $field);
    }

    /**
     * Deleta os vínculos de culturas, usuários, estados e produtos da comissão
     *
     * @param int $idComissao
     */
    public function deleteVinculos(int $idComissao): void
    {
        (new Produto_Model_GestaoComissaoCulturas())->deleteByGestaoComissao($idComissao);
        (new Produto_Model_GestaoComissaoUsuarios())->deleteByGestaoComissao($idComissao);
        (new Produto_Model_GestaoComissaoEstados())->deleteByGestaoComissao($idComissao);
        (new Produto_Model_GestaoComissaoProdutos())->deleteByGestaoComissao($idComissao);
    }
}
