<?php

class Produto_Model_Habilitacoes extends Agro_Db_Table_Abstract {
	protected $_schema = 'produto';
	protected $_name = 'produtos_habilitacoes';
	protected $_sequence = false;

    public function remove($idUsuario, $idProduto, $idEstado, $idMunicipio=false)
    {
        $where = [
            "id_produto = {$idProduto}",
            "id_usuario = {$idUsuario}",
            "id_estado = {$idEstado}"
        ];

        $rowProdutoHabilitacao = $this->fetchAll(implode(' AND ', $where))->current();

        if (!empty($rowProdutoHabilitacao)) {
            $rowProdutoHabilitacao = $rowProdutoHabilitacao->toArray();
            $whereHabilitacoesMunicipios = ["id_produtos_habilitacoes = {$rowProdutoHabilitacao['id']}"];

            if (!empty($idMunicipio)) {
                $whereHabilitacoesMunicipios[] = "id_municipio = {$idMunicipio}";
            }

            $modelProdutosHabilitacoesMunicipios = new Produto_Model_ProdutosHabilitacoesMunicipios();
            $rowProdutosHabilitacoesMunicipios = $modelProdutosHabilitacoesMunicipios->fetchAll(
                implode(' AND ', $whereHabilitacoesMunicipios)
            )->toArray();

            foreach ($rowProdutosHabilitacoesMunicipios as $row) {
                $modelProdutosHabilitacoesMunicipios->delete($row['id']);
            }

            $this->delete($rowProdutoHabilitacao['id']);
        }
    }

	public function removeEstados($idUsuario, $idProduto, $idEstado=false)
    {
        $where = [
            "id_produto = {$idProduto}",
            "id_usuario = {$idUsuario}",
        ];

        if ($idEstado) {
            $where[] = " id_estado = {$idEstado}";
        }

        $rowsProdutoHabilitacao = $this->fetchAll(implode(' AND ', $where))->toArray();

        if (!empty($rowsProdutoHabilitacao)) {
            $modelProdutosHabilitacoesMunicipios = new Produto_Model_ProdutosHabilitacoesMunicipios();

            foreach ($rowsProdutoHabilitacao as $produtoHabilitacao) {
                $modelProdutosHabilitacoesMunicipios->delete(
                    $produtoHabilitacao['id'],
                    'id_produtos_habilitacoes'
                );

                $this->delete($produtoHabilitacao['id']);
            }
        }
    }

	public function fetchUsuario($id) {
		$select = $this->select();
		$select->setIntegrityCheck(false);
		$select->from(array('h' => 'produto.produtos_habilitacoes'));
		$select->join(array('p' => 'produto.produtos'), 'h.id_produto = p.id', array('ds_nome_produto'));
		$select->join(array('e' => 'sistema.estados'), 'm.id_estado = e.id', array('ds_sigla'));
		$select->where('h.id_usuario = ?', $id);
		$select->order(array('e.ds_sigla'));

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

	public function fetchCheckeds($params) {
		$select = $this->select();
		$select->setIntegrityCheck(false);
		$select->from(array('h' => 'produto.produtos_habilitacoes'), 'id_municipio');

		if ($params['corretor'] && $params['preposto']) {
			$select->where("id_usuario = ?", $params['preposto']);
		} else if ($params['corretor']) {
			$select->where("id_usuario = ?", $params['corretor']);
		}

		$select->where('id_produto = ?', $params['produto']);

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

    public function adicionarHabilitacoesFila($data): void
    {
        $data['prepostos'] = !empty($data['prepostos']) ? $data['prepostos'] : [];

        if ($data['fl_habilitar_prepostos']) {
            $modelCorretores = new Sistema_Model_Corretores();
            $data['prepostos'] = $modelCorretores->getPrepostosUsuario($data['id_corretor'])->toArray();
        }

        $enviarEmailConclusao = array_key_exists('enviar_email_conclusao', $data ) ? $data['enviar_email_conclusao'] : true;
        $limparHabilitacoes = array_key_exists('limpar_habilitacoes', $data ) ? $data['limpar_habilitacoes'] : true;
        $incluirCorretor = array_key_exists('incluir_corretor', $data ) ? $data['incluir_corretor'] : empty($data['id_preposto']);
        $habilitar = array_key_exists('habilitar', $data ) ? $data['habilitar'] : true;
        $hashSolicitacao = !empty($data['hash_solicitacao']) ? $data['hash_solicitacao'] : hash('sha256', uniqid(mt_rand(), true));
        $nomeAqruivo = !empty($data['nome_arquivo']) ? $data['nome_arquivo'] : "";
        $municipios = !empty($data['municipios']) ? $data['municipios'] : [];

        $data['estados'] = $this->agruparPorEstado($municipios);

        $dados = [
            'id_usuario_corretor' => $data['id_corretor'],
            'id_usuario_preposto' => $data['id_preposto'],
            'id_produto' => $data['id_produto'],
            'prepostos' => $data['prepostos'],
            'estados' => $data['estados'],
            'hash_solicitacao' => $hashSolicitacao,
            'enviar_email_conclusao' => $enviarEmailConclusao,
            'limpar_habilitacoes' => $limparHabilitacoes,
            'habilitar' => $habilitar,
            'nome_arquivo' => $nomeAqruivo,
            'incluir_corretor' => $incluirCorretor
        ];

        $os = strtoupper(substr(PHP_OS, 0, 3));
        $env = ($os == 'WIN') ? 'docker' : getenv('APPLICATION_ENV');
        $usuarioLogado = Zend_Auth::getInstance()->getIdentity();
        $modelRpcClient = new Agro_RabbitMQ_RelacionarHabilitacoes_RpcClient($env, 'relacionarHabilitacoes');
        $modelRpcClient->execute([
            'data' => $dados,
            'id_usuario' => $usuarioLogado->id,
            'acao' => 'relacionarHabilitacoes'
        ]);
    }

	public function saveEstados(array $data)
    {
        try {
            $this->getAdapter()->beginTransaction();
            
            $this->removeEstados(
                $data['id_preposto'] ? $data['id_preposto'] : $data['id_corretor'],
                $data['id_produto']
            );

            $municipios = !empty($data['municipios']) ? $data['municipios'] : [];
            $data['estados'] = $this->agruparPorEstado($municipios);

            if (!empty($data['estados'])) {
                $this->inserirRegistrosPorMunicipio($data);
            }
            
            $this->getAdapter()->commit();
        } catch (Exception $e) {
            $this->getAdapter()->rollBack();
            throw $e;
        }
    }

	public function getHabilitacoes($values, int $idMunicipio = 0)
    {
        $idUsuario = array_key_exists('id_corretor', $values) && !empty($values['id_corretor'])
            ? $values['id_corretor']
            : null;
        $idUsuario = array_key_exists('id_preposto', $values) && !empty($values['id_preposto'])
            ? $values['id_preposto']
            : $idUsuario;
        $idUsuario = !Agro_Util::filterVariable($idUsuario) ? 0 : (int)$idUsuario;

        $idProduto = !Agro_Util::filterVariable($values['id_produto']) ? 0 : (int)$values['id_produto'];

        $select = $this->select()->setIntegrityCheck(false)->distinct();
        $select->from(array('m' => 'sistema.municipios'), array('id', 'ds_nome_municipio'));
        $select->joinLeft(
            array('h' => 'produto.produtos_habilitacoes'),
            "h.id_municipio = m.id and h.id_usuario = {$idUsuario} and h.id_produto = {$idProduto}",
            array('id_municipio as habilitado')
        );
        $select->order("ds_nome_municipio");

        if ($idMunicipio) {
            $select->where("h.id_municipio = ?", $idMunicipio);
            $rs = $this->fetchRow($select);
        } else {
            $idEstado = !Agro_Util::filterVariable($values['id_estado']) ? 0 : (int)$values['id_estado'];

            $select->where("m.id_estado = ?", $idEstado);
            $rs = $this->fetchAll($select);
        }

        return $rs;
    }

	public function getHabilitacoesEstados($values, $idEstado=false)
    {
        $idUsuario = array_key_exists('id_corretor', $values) && !empty($values['id_corretor'])
            ? $values['id_corretor']
            : null;
        $idUsuario = array_key_exists('id_preposto', $values) && !empty($values['id_preposto'])
            ? $values['id_preposto']
            : $idUsuario;
        $idProduto = $values['id_produto'];

        $uf = Agro_Db_Table_Abstract::getDefaultAdapter()->fetchOne(
            "select comercializacao.taxas_habilitadas_uf({$idProduto})"
        );

        if (empty($uf)) {
            return [];
        }

        $select = $this->select()->setIntegrityCheck(false)->distinct();
        $select->from(array('e' => 'sistema.estados'), array('id', 'ds_nome_estado', 'ds_sigla'));
        $select->joinLeft(
            array('h' => 'produto.produtos_habilitacoes'),
            "h.id_estado = e.id and h.id_usuario = {$idUsuario} and h.id_produto = {$idProduto}",
            array('id_estado as estado_habilitado')
        );
        $select->joinLeft(
            ['pphm' => 'produto.produtos_habilitacoes_municipios'],
            'pphm.id_produtos_habilitacoes = h.id',
            'id_municipio'
        );
        $select->order('e.ds_nome_estado');
        $select->where('e.fl_ativo = true');
        $select->where("e.id in ($uf)");

        if ($idEstado) {
            $select->where('h.id_estado = ?', $idEstado);
        }
       
        $rs = $this->fetchAll($select)->toArray();
        $retorno = [];

        foreach ($rs as $registro) {
            $retorno[$registro['id']]['ds_nome_estado'] = $registro['ds_nome_estado'];
            $retorno[$registro['id']]['ds_sigla'] = $registro['ds_sigla'];
            $retorno[$registro['id']]['estado_habilitado'] = $registro['estado_habilitado'];

            if (!isset($retorno[$registro['id']]['municipios'])) {
                $retorno[$registro['id']]['municipios'] = [];
            }

            if (!empty($registro['id_municipio'])) {
                $retorno[$registro['id']]['municipios'][] = $registro['id_municipio'];
            }
        }

        return $retorno;
    }

	public function getHabilitacoesXls($dados) {
		$Select = $this->select()->setIntegrityCheck(false);
		$Select->from(array("ph" => "produto.produtos_habilitacoes"), null);
		$Select->joinInner(array("p" => "produto.produtos"), "ph.id_produto = p.id", 'ds_nome_produto');
		$Select->joinInner(array("s" => "produto.safras"), "p.id_safra = s.id", 's.ds_nome_safra');
		//$Select->joinInner(array("m" => "sistema.municipios"), "ph.id_municipio = m.id", 'ds_nome_municipio');
		$Select->joinInner(array("e" => "sistema.estados"), "ph.id_estado = e.id", "ds_sigla");
		$Select->joinInner(array("c" => "sistema.corretores"), "ph.id_usuario = c.id_usuario", 'ds_nome_corretor');

		if($dados['id_corretor_search']) {
			$Select->where("ph.id_usuario = ?", $dados['id_corretor_search']);
		}
		if($dados['id_produto_search']) {
			$Select->where("ph.id_produto = ?", $dados['id_produto_search']);
		}
		if($dados['id_safra_search']) {
			$Select->where("s.id = ?", $dados['id_safra_search']);
		}
		if($dados['id_estado_search']) {
			$Select->where("e.id = ?", $dados['id_estado_search']);
		}
		if($dados['id_comercial']){
			$Select->where("c.id_comercial = ?", $dados['id_comercial']);
		}
		$Select->order(array('ds_nome_corretor', 'ds_nome_safra', 'ds_nome_produto', 'ds_sigla'));
		$Select->group(array('ds_nome_corretor', 'ds_nome_safra', 'ds_nome_produto', 'ds_sigla'));
		$Rs = $this->fetchAll($Select);

		return $Rs;
	}


	public function habilitado($idCorretor, $idUsuarioCriacao, $idProduto, $idEstado) {
		$Select = $this->select()->setIntegrityCheck(false);
		$Select->where('id_estado = ?', $idEstado);
		$Select->where('id_usuario in (?)', array($idCorretor, $idUsuarioCriacao));
		$Select->where('id_produto = ?', $idProduto);

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

    public function desabilitaByProduto($idProduto)
    {
        if ($idProduto) {
            $modelProdutosHabilitacoesMunicipios = new Produto_Model_ProdutosHabilitacoesMunicipios();
            $rowsProdutoHabilitacao = $this->fetchAll("id_produto = {$idProduto}")->toArray();

            foreach ($rowsProdutoHabilitacao as $row) {
                $modelProdutosHabilitacoesMunicipios->delete($row['id'], 'id_produtos_habilitacoes');
            }

            $this->delete($idProduto, 'id_produto');
        }
    }

    public function desabilitaByCorretor($idUsuario)
    {
        if ($idUsuario) {
            $modelProdutosHabilitacoesMunicipios = new Produto_Model_ProdutosHabilitacoesMunicipios();
            $rowsProdutoHabilitacao = $this->fetchAll("id_usuario = {$idUsuario}")->toArray();

            foreach ($rowsProdutoHabilitacao as $row) {
                $modelProdutosHabilitacoesMunicipios->delete($row['id'], 'id_produtos_habilitacoes');
            }

            $this->delete($idUsuario, 'id_usuario');
        }
    }
	
	/*
	 * Replica as habilitações que o corretor do preposto tiver
	 * Utilizada no momento em que um preposto é cadastrado
	 */
	public function replicaHabilitacoes($idUsuarioPreposto, $idUsuarioCorretor)
    {
		if ($idUsuarioPreposto && $idUsuarioCorretor) {
			$sql = "insert into produto.produtos_habilitacoes (
					id_usuario,
					id_produto,
					id_estado)
					select $idUsuarioPreposto,
					id_produto,
					id_estado
					from produto.produtos_habilitacoes
					where id_usuario = $idUsuarioCorretor";

            $sqlMunicipios = "INSERT INTO produto.produtos_habilitacoes_municipios ( ";
            $sqlMunicipios .= "  id_produtos_habilitacoes, ";
            $sqlMunicipios .= "  id_municipio) ";
            $sqlMunicipios .= "    SELECT pph_sublogin.id  as id_pph_sublogin ";
            $sqlMunicipios .= "         , pphm.id_municipio as id_municipio ";
            $sqlMunicipios .= " FROM produto.produtos_habilitacoes pph_corretor ";
            $sqlMunicipios .= "      INNER JOIN produto.produtos_habilitacoes pph_sublogin ON pph_sublogin.id_produto = pph_corretor.id_produto ";
            $sqlMunicipios .= "                                                           AND pph_sublogin.id_estado = pph_corretor.id_estado ";
            $sqlMunicipios .= "      INNER JOIN produto.produtos_habilitacoes_municipios pphm ON pphm.id_produtos_habilitacoes = pph_corretor.id ";
            $sqlMunicipios .= "WHERE pph_corretor.id_usuario = {$idUsuarioCorretor} ";
            $sqlMunicipios .= "  AND pph_sublogin.id_usuario = {$idUsuarioPreposto} ";

			$this->getDefaultAdapter()->beginTransaction();
			
			try {
				$this->getAdapter()->query($sql);
				$this->getAdapter()->query($sqlMunicipios);

				$this->getDefaultAdapter()->commit();
				return true;
			} catch (Exception $e) {
				$this->getDefaultadapter()->rollback();
				return $e->getMessage();
			}
		}
	}

    private function inserirRegistrosPorMunicipio(array &$data) : void
    {
        $idUsuario = !empty($data['id_preposto']) ? $data['id_preposto'] : $data['id_corretor'];
        $modelProdutosHabilitacoesMunicipios = new Produto_Model_ProdutosHabilitacoesMunicipios();

        foreach ($data['estados'] as $idEstado => $estado) {
            $this->insert([
                'id_usuario' => (int) $idUsuario,
                'id_produto' => (int) $data['id_produto'],
                'id_estado' => (int) $idEstado,
            ]);

            $idProdutoHabilitacao = $this->getAdapter()->lastInsertId();

            if (empty($idProdutoHabilitacao)) {
                throw new Exception("Erro ao incluir a habilitação do produto.");
            }

            if (count($estado['municipios']) == $estado['total_municipios_estado']) {
                continue;
            }

            foreach ($estado['municipios'] as $idMunicipio) {
                $modelProdutosHabilitacoesMunicipios->save([
                    'id_produtos_habilitacoes' => $idProdutoHabilitacao,
                    'id_municipio' => $idMunicipio,
                ]);
            }
        }
    }

    /**
     * Agrupa os municípios por estado
     *
     * @param array $dados
     * @return
     */
    private function agruparPorEstado(array $dados): array
    {
        $modelMunicipios = new Sistema_Model_Municipios();
        $estados = [];
        foreach ($dados as $item) {
            list($idEstado, $idMunicipio) = explode('#', $item);
            if (!array_key_exists($idEstado, $estados)) {
                $estados[(int)$idEstado]['total_municipios_estado'] = $modelMunicipios->getTotalMunicipiosByEstado($idEstado);
                $estados[(int)$idEstado]['municipios'] = [];
            }
            if (!empty($idMunicipio)) {
                $estados[(int)$idEstado]['municipios'][] = $idMunicipio;
            }
        }

        return $estados;
    }
}
