<?php

class REV_model extends CI_Model {

    /**
     * Insere um registro no histórico.
     *
     * @param array $dados Dados a serem inseridos no histórico.
     * @return bool Retorna true se a inserção for bem-sucedida, caso contrário, false.
     */
    public function insertHist($dados) {
        date_default_timezone_set('America/Sao_Paulo');
        $this->db->insert('historico', $dados);
        return true;
    }

    /**
     * Adiciona saldo a um usuário.
     *
     * @param int $usuario_id ID do usuário.
     * @param float $valor_adicionar Valor a ser adicionado ao saldo.
     * @return bool Retorna true se o saldo for atualizado com sucesso, caso contrário, false.
     */
    public function adicionarSaldo($usuario_id, $valor_adicionar) {
        $query = $this->db->get_where('afiliado', array('usuario' => $usuario_id))->result();

        if (!empty($query)) {
            $saldo_atual = $query[0]->saldo;
            $novo_saldo = $saldo_atual + $valor_adicionar;

            $this->db->where('usuario', $usuario_id);
            $this->db->update('afiliado', array('saldo' => $novo_saldo));

            return true;
        } else {
            return false;
        }
    }

    /**
     * Verifica se um usuário possui um pai afiliado.
     *
     * @param int $id ID do usuário.
     * @return mixed Retorna os dados do usuário se tiver um pai afiliado, caso contrário, false.
     */
    public function checkIsHaveDad($id) {
        $this->db->where('id', $id);
        $query = $this->db->get('usuarios')->result();
        
        if (!empty($query) && isset($query[0]->afiliado)) {
            return $query;
        } else {
            return false;
        }
    }

    /**
     * Obtém o pai de um usuário.
     *
     * @param int $id ID do usuário.
     * @return int Retorna o ID do pai do usuário.
     */
        public function getDad($id) {
            $this->db->where('id', $id);
            $query = $this->db->get('usuarios')->result();
        
            // Verifica se $query[0]->afiliado é diferente de null
            if ($query[0]->afiliado !== null) {
                $this->db->where('usuario', $query[0]->afiliado);
                $dad = $this->db->get('usuarios')->result();
        
                // Verifica se $dad não está vazio antes de acessar $dad[0]->id
                if (!empty($dad)) {
                    return $dad[0]->id;
                } else {
                    // Retorna algum valor padrão ou gera um erro, dependendo do seu caso
                    return false;
                }
            } else {
                // Retorna algum valor padrão ou gera um erro, dependendo do seu caso
                return false;
            }
        }

    /**
     * Verifica se um usuário é afiliado.
     *
     * @param int $id ID do usuário.
     * @return bool Retorna true se o usuário for afiliado, caso contrário, false.
     */
    public function checkIsAfiliado($id) {
        $query = $this->db->get_where('usuarios', array('id' => $id, 'tipo' => 'afiliado'));
        return ($query->num_rows() > 0);
    }

    /**
     * Verifica se um usuário possui configurações personalizadas de REV.
     *
     * @param int $id ID do usuário.
     * @return mixed Retorna os dados de configuração personalizada se existirem, caso contrário, false.
     */
    public function checkAfiliadoCustomREV($id) {
        $this->db->where('usuario', $id);
        $query = $this->db->get('afiliado')->result();
        
        if (!empty($query) && isset($query[0]->revShareLvl1)) {
            return $query;
        } else {
            return false;
        }
    }

    /**
     * Obtém as configurações gerais de REV.
     *
     * @return mixed Retorna os dados de configuração geral se existirem, caso contrário, false.
     */
    public function geralREV() {
        $query = $this->db->get('afiliados_config', array('id' => 0))->result();
        
        if (!empty($query)) {
            return $query;
        } else {
            return false;
        }
    }

    /**
     * Obtém transações específicas de um usuário.
     *
     * @param int $user ID do usuário.
     * @param string $trans ID da transação.
     * @return mixed Retorna as transações se existirem, caso contrário, false.
     */
    public function pegaTrans($user, $trans) {
        $this->db->where(array('transacao_id' => $trans, 'usuario' => $user, 'status' => 'pago'));
        $query = $this->db->get('transacoes')->result();
        
        if (!empty($query)) {
            return $query;
        } else {
            return false;
        }
    }

        /**
     * Obtém o nivel do usuário.
     *
     * @param int $id ID do usuário.
     */
    public function obterNivel($id) {
        $this->db->where('id', $id);
        $user = $this->db->get('usuarios')->result();
    
        if (!empty($user)) {
            $this->db->select('afiliado.usuario AS afiliado, usuario.usuario AS usuario, usuario.id AS id_usuario');
            $this->db->select('CASE 
                                WHEN afiliado.usuario IS NULL THEN "lv1" 
                                WHEN EXISTS (SELECT 1 FROM usuarios AS neto WHERE neto.afiliado = usuario.usuario) THEN "lv2" 
                                ELSE "lv2" 
                            END AS nivel', FALSE);
            $this->db->from('usuarios AS usuario');
            $this->db->join('usuarios AS afiliado', 'usuario.afiliado = afiliado.usuario', 'left');
            $this->db->where('afiliado.usuario', $user[0]->usuario);
            $this->db->or_where('usuario.usuario', $user[0]->usuario);
    
            $query = $this->db->get();
            $result = $query->result();
    
            // Verifica se $result não está vazio antes de retornar
            if (!empty($result)) {
                return $result;
            } else {
                // Retorna algum valor padrão ou gera um erro, dependendo do seu caso
                return false;
            }
        } else {
            // Retorna algum valor padrão ou gera um erro, dependendo do seu caso
            return false;
        }
    }
    

    /**
     * Processa o crédito de REV para um usuário.
     *
     * @param int $id ID do usuário.
     * @param float $deposito Valor do depósito.
     * @param float $rev Percentual de REV.
     * @param int $hist ID do histórico.
     * @return bool Retorna true se o processamento for bem-sucedido, caso contrário, false.
     */
    private function processaREV($id, $deposito, $rev, $hist) {
        $valor = $this->engine->calcularPorcentagem($deposito, $rev);

        $insertHist = array(
            'historico_id' => $hist,
            'credito' => 'R$ ' . number_format($valor, 2),
            'usuario' => $id,
            'pagina' => 'Crédito REV',
            'ip' => $this->input->ip_address(),
            'data_hora' => date('d/m/Y H:i:s'),
        );

        $existe_registro = $this->db->get_where('historico', array('historico_id' => $hist))->row();
        
        if (!$existe_registro) {
            $this->insertHist($insertHist);
            $this->adicionarSaldo($id, $valor);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Verifica e processa o crédito de REV para um usuário.
     *
     * @param int $id ID do usuário.
     * @param float $valor Valor do crédito de REV.
     * @param int $hist ID do histórico.
     * @return void
     */
    public function checaRev($id, $valor, $hist) {
        date_default_timezone_set('America/Sao_Paulo');
    
        $afiliado = $this->checkIsAfiliado($id);
        $customREV = $this->checkAfiliadoCustomREV($id);
        $geralREV = $this->geralREV();
        $check = $this->checkIsHaveDad($id);
    
        if (!$check == false) {
            $dad = $this->getDad($id);
    
            $this->db->where('usuario', $id);
            $query = $this->db->get('afiliado')->result();
            
                $niveis = $this->obterNivel($dad);
    
                if (!empty($niveis)) { // Verifica se $niveis não está vazio
                    foreach ($niveis as $nvs) {
                        if ($nvs->nivel == 'lv1') {
                            if ($query[0]->revShareLvl1 >= 1) {
                                $this->processaREV($dad, $valor, $query[0]->revShareLvl1, $hist);
                            } else {
                                $this->processaREV($dad, $valor, $geralREV[0]->revShareLvl1, $hist);
                            }
                        } elseif ($nvs->nivel == 'lv2') {
                            if ($query[0]->revShareLvl2 >= 1) {
                                $this->processaREV($nvs->id_usuario, $valor, $query[0]->revShareLvl2, $hist);
                            } else {
                                $this->processaREV($nvs->id_usuario, $valor, $geralREV[0]->revShareLvl2, $hist);
                            }
                        } elseif ($nvs->nivel == 'lv3') {
                            if ($query[0]->revShareLvl3 >= 1) {
                                $this->processaREV($nvs->id_usuario, $valor, $query[0]->revShareLvl3, $hist);
                            } else {
                                $this->processaREV($nvs->id_usuario, $valor, $geralREV[0]->revShareLvl3, $hist);
                            }
                        }
                    }
                }
            
        }
    }
    
}
