<?php
/**
 * Arquivo de declaração da classe PerfilDAO.
 */
class PerfilDAO extends Model
{
    private $conexao;

    /**
     * Método construtor.
     */
    public function __construct()
    {
        $this->conexao = Conexao::getInstancia();
    }

    /**
     * Método para retornar a quantidade de objetos, conforme condição informada.
     *
     * @param  string $condicao
     * @param  array  $parametros
     * @return string
     */
    public function contador($condicao = '', $parametros = array())
    {
        $condicao = Util::verificaCampo($condicao, 'AND');

        $txtSql = "SELECT count(id) as quantidade FROM cp_perfil WHERE ((excluido IS NULL) OR (excluido = 0))  $condicao";

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $this->conexao->setParametros($sql, $parametros);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) $resultado;
    }

    /**
     * Método para retornar o ultimo id os perfis.
     */
    public function ultimoId()
    {
        $txtSql = 'SELECT max(id) as max FROM cp_perfil';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) $resultado;
    }

    /**
     * Método para retornar a quantidade de objetos, conforme condição informada.
     *
     * @param  int $perfil
     * @return string
     */
    public function rows($perfil = 0)
    {
        $txtSql = 'SELECT count(perfil_id) as quantidade
                    FROM
                        cp_usuarios
                    WHERE
                        ((excluido IS NULL) OR (excluido = 0)) 
                    AND
                        perfil_id = :perfil';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindParam(':perfil', $perfil, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) $resultado;
    }

    /**
     * Método para inserir.
     *
     * @param  Perfil $obj
     */
    public function inserir(Perfil $obj)
    {
        $txtSql = 'INSERT INTO cp_perfil (nome, slug) VALUES (:nome, :slug)';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':nome', $obj->nome, PDO::PARAM_STR);
            $sql->bindValue(':slug', Util::slugify($obj->nome), PDO::PARAM_STR);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $lastId = $sql->rowCount() > 0 ? (int) $this->conexao->getConexao()->lastInsertId() : null;
        $sql->closeCursor();

        $objTelas = Tela::listar('', array());

        if (count($objTelas) > 0) {
            foreach ($objTelas as $tela) {
                $obj = Permissao::inserePerfilTela($lastId, $tela->id);
            }
        }

        return $lastId;
    }

    /**
     * Editar dados.
     *
     * @param  Perfil $obj
     */
    public function editar(Perfil $obj)
    {
        $txtSql = 'UPDATE cp_perfil SET nome = :nome, atualizado_em = NOW() WHERE id = :id';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':nome', $obj->nome, PDO::PARAM_STR);
            $sql->bindValue(':id', $obj->id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $sql->closeCursor();
    }

    /**
     * Método para excluir.
     *
     * @param  int $id
     */
    public function excluir($id = 0)
    {
        $txtSql = 'UPDATE cp_perfil SET excluido = now() WHERE id = :id';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':id', $id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->rowCount() > 0 ? true : false;
        $sql->closeCursor();

        return $resultado;
    }

    /**
     * Método para listar os objetos.
     *
     * @param  string $condicao
     * @param  array  $parametros
     * @param  string $order
     * @param  string $limit
     * @param  string $offset
     */
    public function listar($condicao = '', $parametros = array(), $order = '', $limit = '', $offset = '')
    {
        $condicao = Util::verificaCampo($condicao, 'AND');
        $order = Util::verificaCampo($order, 'ORDER BY');
        $limit = Util::verificaCampo($limit, 'LIMIT');
        $offset = Util::verificaCampo($offset, 'OFFSET');

        $select = $this->getSelect();

        $txtSql = "SELECT $select FROM cp_perfil WHERE ((excluido IS NULL) OR (excluido = 0))  $condicao $order $limit $offset";

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $this->conexao->setParametros($sql, $parametros);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchAll(PDO::FETCH_ASSOC);
        $sql->closeCursor();

        if (!$resultado) {
            return null;
        }

        foreach ($resultado as $res) {
            $arrObjeto[] = $this->classObject($res);
        }

        return $arrObjeto;
    }

    /**
     * Método para buscar o objeto.
     *
     * @param  int $id
     */
    public function buscar($id = 0)
    {
        $select = $this->getSelect();

        $txtSql = "SELECT $select FROM cp_perfil WHERE ((excluido IS NULL) OR (excluido = 0))  AND id = :id";

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':id', $id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetch(PDO::FETCH_ASSOC);
        $sql->closeCursor();

        if (!$resultado) {
            return null;
        }

        return $this->classObject($resultado);
    }

    /**
     * Método para mudar o status.
     *
     * @param  int $id
     */
    public function mudaStatus($id = 0)
    {
        $txtSql = 'SELECT ativo FROM cp_perfil WHERE id = :id;
                UPDATE cp_perfil SET ativo = (ativo ^ 1), atualizado_em = NOW() WHERE id = :id';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':id', $id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) !$resultado;
    }

    /**
     * Método para alterar a permissão.
     *
     * @param  int $id
     * @param  string  $operacao
     * @return string
     */
    public function mudaPermissao($id = 0, $operacao = '')
    {
        $permissao = Permissao::buscar($id);

        $valor = (int) !$permissao[$operacao];

        $mudaPermissao = Permissao::mudaPermissao($id, $operacao, $valor);

        return $valor;
    }

    /**
     * Objeto da classe.
     *
     * @param  array  $resultado
     * @return object
     */
    private function classObject($resultado = array())
    {
        $obj = null;
        $obj = new Perfil();
        isset($resultado['id']) ? $obj->id = $resultado['id'] : '';
        isset($resultado['nome']) ? $obj->nome = $resultado['nome'] : '';
        isset($resultado['slug']) ? $obj->slug = $resultado['slug'] : '';
        isset($resultado['ativo']) ? $obj->ativo = $resultado['ativo'] : '';
        isset($resultado['criado_em']) ? $obj->criadoem = $resultado['criado_em'] : '';

        return $obj;
    }
}
