<?php

defined('BASEPATH') or exit('No direct script access allowed');
class Auth extends MY_Controller
{
    // === INSCRIPTIONS ===
    // Mettre à true pour désactiver les inscriptions, false pour les réactiver
    private $registration_disabled = false;
    
    public function __construct()
    {
        parent::__construct();

        if ($this->session->logged) {
            redirect('/');
        }
    }

    public function smtp_config($email = null)
    {
        return  array(
            'protocol' => 'smtp',
            'smtp_host' => 'smtp.resend.com',
            'smtp_port' => 587,
            'smtp_user' => 'resend',
            'smtp_pass' => 're_R9K79zd1_EZwHghQpDc6TvJkjxjcXJ9gB',
            'smtp_crypto' => 'tls',
            'mailtype' => 'text',
            'from_email' => 'noreply@p2p-tracker.com', 
            'from_name' => 'YggTorrent',
            'newline' => "\\r\
",
            'crlf' => "\\r\
",
            'wordwrap' => TRUE
        );
    }

    public function send_reset_email($email, $token)
    {
        $config = $this->smtp_config($email);
        $this->load->library('email', $config);
        $this->email->from($config['from_email'], $config['from_name']);
        $this->email->subject('Réinitialisation de votre mot de passe - YggTorrent');
        $this->email->to($email);
        
        $url = 'https://www.yggtorrent.top/user/reset_password?action=proceed&token=' . $token;
        
        $msg = "Réinitialisation de votre mot de passe\
";
        $msg .= "=====================================\
\
";
        $msg .= "Pour réinitialiser votre mot de passe, copiez et collez ce lien dans votre navigateur :\
\
";
        $msg .= $url . "\
\
";
        $msg .= "Ce lien est valable 30 minutes.\
\
";
        $msg .= "Si vous n'êtes pas à l'origine de cette demande, ignorez cet email.\
\
";
        $msg .= "---\
";
        $msg .= "Ceci est un email automatique, merci de ne pas y répondre.\
";
        $msg .= "YggTorrent";

        $this->email->message($msg);
        $this->email->send();
    }

    public function send_confirmation_email($mail, $token, $nickname)
    {
        $config = $this->smtp_config($mail);
        $this->load->library('email', $config);
        $this->email->from($config['from_email'], $config['from_name']);
        $this->email->to($mail);
        $this->email->subject('Activation de votre compte - YggTorrent');
        
        $url = 'https://www.yggtorrent.top/user/confirm_account?token=' . $token;

        $msg = "Bienvenue sur YggTorrent !\
";
        $msg .= "==========================\
\
";
        $msg .= "Bonjour " . $nickname . ",\
\
";
        $msg .= "Pour activer votre compte, copiez et collez ce lien dans votre navigateur :\
\
";
        $msg .= $url . "\
\
";
        $msg .= "Si vous n'êtes pas à l'origine de cette inscription, ignorez cet email.\
\
";
        $msg .= "---\
";
        $msg .= "Ceci est un email automatique, merci de ne pas y répondre.\
";
        $msg .= "YggTorrent";

        $this->email->message($msg);
        $this->email->send();
    }

    public function login()
    {
        $this->load->view('auth/login.php');
    }

    public function restricted()
    {
        $this->load->view('auth/register_restricted.php');
    }

    public function register()
    {
        // Vérifier si les inscriptions sont désactivées
        if ($this->registration_disabled) {
            redirect('/auth/restricted');
            return;
        }

        $this->load->helper('cookie');
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        $hash = hash('md5', $ip . $this->config->item('salt_ip'));
        $nums = $this->db->where('ih', $hash)->get('sessions')->num_rows();
        $nums = 0;

        if (($nums > 0 || !is_null(get_cookie('account_created'))) && is_null(get_cookie('account_authority'))) {
            redirect('/auth/restricted');
            return;
        }

        $data['captcha_error'] = '';
        $data['hide_form'] = false;
        $this->form_validation->set_rules('email', '<strong>email</strong>', 'required|valid_email|trim|xss_clean');
        $this->form_validation->set_rules('nickname', '<strong>pseudo</strong>', 'required|trim|min_length[3]|max_length[30]|alpha_dash|xss_clean');
        $this->form_validation->set_rules('pass', '<strong>mot de passe</strong>', 'required|trim|min_length[5]|max_length[40]|xss_clean');
        $this->form_validation->set_rules('passconfirm', '<strong>confirmation mdp</strong>', 'required|trim|min_length[5]|max_length[40]|matches[pass]|xss_clean');

        if ($this->form_validation->run()) {
            $hcaptcha_data = array(
                'secret' => '0x2B8C9E0705c3b48501Eb3d817d39D3C95A9AE0aA',
                'response' => $_POST['h-captcha-response']
            );
            $verify = curl_init();
            curl_setopt($verify, CURLOPT_URL, 'https://hcaptcha.com/siteverify');
            curl_setopt($verify, CURLOPT_POST, true);
            curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($hcaptcha_data));
            curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
            $response_hcaptcha = curl_exec($verify);
            $responseData = json_decode($response_hcaptcha);
            if (!$responseData->success) {
                $data['message'] = '<div class="alert alert-danger">Le captcha est invalide</div>';
            } else {
                $data_account['email'] = strtolower($this->input->post('email'));
                $data_account['nickname'] = ucfirst($this->input->post('nickname'));
                $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));
                $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');

                $data_account['pass'] = hash('sha512', $to_hash);
                $data_account['join_date'] = now();
                $data_account['torrent_pass'] = generatePasskey();
                //$data_account['uploaded'] = (32212238220 / 2);
                $data_account['uploaded'] = (1073741274 * 10);
                $data_account['download_multiplier'] = 1;
                $data_account['downloaded'] = 1073741274;
                $data_account['settings'] = '{"pm":{"enable":true,"condition_sender_age":"2weeks"},"enable_at_content":false}';

                $data_account['token_validation'] = bin2hex(openssl_random_pseudo_bytes(16));
                $domain = strtolower(substr(strrchr($data_account['email'], '@'), 1));
                
                // Liste blanche des domaines email autorisés
                $allowed_domains = [
                    // Google
                    'gmail.com',
                    // Microsoft
                    'outlook.com', 'outlook.fr', 'hotmail.com', 'hotmail.fr', 'live.com', 'live.fr', 'msn.com',
                    // Yahoo
                    'yahoo.com', 'yahoo.fr', 'ymail.com',
                    // Apple
                    'icloud.com', 'me.com', 'mac.com',
                    // Autres
                    'gmx.com', 'gmx.fr', 'aol.com', 'zoho.com'
                ];

                if (strpos($data_account['email'], '+') !== false) {
                    $data['message'] = '<div class="alert alert-danger">Impossible d\\'utiliser cette adresse e-mail pour s\\'inscrire</div>';
                } elseif (!in_array($domain, $allowed_domains)) {
                    $data['message'] = '<div class="alert alert-danger">Veuillez utiliser une adresse e-mail d\\'un fournisseur connu (Gmail, Outlook, Yahoo, etc.)</div>';
                } else {
                    if (!$this->db->insert('users', $data_account)) {
                        $error = $this->db->error();

                        if (strpos($error['message'], 'nickname') !== false) {
                            $data['message'] = '<div class="alert alert-danger">Le pseudo que vous avez renseigné a déjà été utilisé</div>';
                        } else {
                            $data['message'] = '<div class="alert alert-danger">L\\'adresse e-mail que vous avez renseigné a déjà été utilisée</div>';
                        }
                    } else {
                        $user_id = $this->db->insert_id();

                        if (isset($_POST['session_id']) && trim($_POST['session_id']) != '') {
                            $fp_data = array(
                                'user_id' => $user_id,
                                'fp' => $this->input->post('session_id'),
                                'date' => now()
                            );
                            $this->db->insert('users_fp', $fp_data);
                        }

                        $data['message'] = '<div class="alert alert-success">Un e-mail de validation vous a été envoyé, merci d\\'activer votre compte pour profiter des services d\\'YggTorrrent. Pensez à vérifier votre boîte spam !</div>';
                        $data['hide_form'] = true;
                        $this->cache->redis->save('user:' . strtolower($data_account['nickname']), $user_id, 1200);
                        $this->send_confirmation_email($data_account['email'], $data_account['token_validation'], $data_account['nickname']);
                    }
                }
            }
        }

        $error_validation = array_values($this->form_validation->error_array())[0];
        if (!empty($error_validation)) {
            $data['message'] = '<div class="alert alert-danger">' . $error_validation . '</div>';
        }

        $this->load->view('auth/register.php', $data);
    }

    public function reset_pass()
    {
        $this->form_validation->set_error_delimiters('<span style="color:red">', '</span>');
        $this->form_validation->set_rules('email', '"email"', 'required|trim|valid_email|xss_clean');

        $this->load->library('recaptcha');

        $data['msg'] = '';
        $data['hide_form'] = false;

        if ($this->form_validation->run()) {
            $hcaptcha_data = array(
                'secret' => '0x2B8C9E0705c3b48501Eb3d817d39D3C95A9AE0aA',
                'response' => $_POST['h-captcha-response']
            );
            $verify = curl_init();
            curl_setopt($verify, CURLOPT_URL, 'https://hcaptcha.com/siteverify');
            curl_setopt($verify, CURLOPT_POST, true);
            curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($hcaptcha_data));
            curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
            $response_hcaptcha = curl_exec($verify);
            $responseData = json_decode($response_hcaptcha);

            if (!$responseData->success) {
                $data['msg'] = '<div class="alert alert-danger">Captcha invalide</div>';
            } else {
                $email = $this->input->post('email');
                $user_data = $this->users->get_spe_userdata($email, 'id', 'email');

                if (empty($user_data->id)) {
                    $data['msg'] = '<div class="alert alert-danger">Aucun utilisateur enregistré avec cet email.</div>';
                } else {
                    $token = random_string('alnum', 45);
                    $this->cache->redis->save('token_reset:' . $token, $user_data->id, 1800);
                    $this->send_reset_email($email, $token);
                    $data['msg'] = '<div class="alert alert-success">Un email contenant un lien de réinitialisation <u><strong>valable 30 minutes</strong></u> a été envoyé à votre adresse email <strong> (Vérifiez aussi votre dossier Spam)</strong></div>';
                    $data['hide_form'] = true;
                }

            }

        }


        $this->load->view('auth/reset_pass.php', $data);
    }

    public function process_login()
    {
        $data['message'] = '';
        $this->form_validation->set_rules('id', 'login', 'required|trim|xss_clean');
        $this->form_validation->set_rules('pass', 'mdp', 'required|trim|xss_clean');

        if ($this->form_validation->run()) {
            $this->session->unset_userdata('upgrade_security');

            $userdata = $this->users->get_spe_userdata($this->input->post('id'), '*', 'nickname');
            $authorized = false;

            // Le username spécifié n'existe pas
            if (empty($userdata)) {
                $this->output->set_content_type('application/json')
                    ->set_status_header(401)
                    ->set_output(json_encode(array('result' => false, 'message' => 'User not found.')));
            }
            // On check le MDP si format MD5 - utilisé pour les comptes avec reset du mot de passe
            else if (empty($userdata->salt)) {
                $authorized = $userdata->pass == md5($this->input->post('pass'));
                $this->session->upgrade_security = true;
            }
            // Classic checking - SHA512 + Salt
            else {
                $to_hash = $userdata->salt . $this->input->post('pass') . $this->config->item('secret_key');
                $authorized = $userdata->pass == hash('sha512', $to_hash);
            }


            if (!$authorized) {
                $this->output->set_content_type('application/json')
                    ->set_status_header(401)
                    ->set_output(json_encode(array('result' => false, 'message' => 'Bad credentials.')));
            } else {
                $sanctions = (array) json_decode($userdata->sanctions);
                if ($sanctions['sanction_5'] > now() || $sanctions['sanction_5'] == 'oo') {
                    if ($sanctions['sanction_5'] == 'oo') {
                        $response['duration'] = 'Jamais';
                    } else {
                        $diff = $sanctions['sanction_5'] - now();
                        $dtF = new \\DateTime('@0');
                        $dtT = new \\DateTime("@$diff");
                        $response = array();
                        $response['duration'] = $dtF->diff($dtT)->format('%a jours, %h heures, %i minutes et %s secondes');
                    }
                    $response['reason_key'] = $this->encrypt($userdata->id);

                    $this->output->set_status_header(403);
                    $this->output->set_content_type('application/json')->set_output(json_encode($response));
                } else {
                    if ($userdata->is_valid == 1) {
                            $ips_ranges = ['41.102', '41.103', '197.206'];
                            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                            $ip_x = explode('.', $ip);
                            foreach ($ips_ranges as $range) {
                                $x = explode('.', $range);
                                if ($ip_x[0] == $x[0] && $ip_x[1] == $x[1]) {
                                    $data = [
                                        'ip' => $ip,
                                        'user_id' => $userdata->id,
                                        'timestamp' => now()
                                    ];
                                    $this->db->insert('flagged_users', $data);
                                    break;
                                }
                            }

                            if (in_array($userdata->rank, array(1, 2, 3)) && $userdata->download_multiplier == 1) {
                                $this->db->where('id', $userdata->id)->set('download_multiplier', 0)->update('users');
                                $userdata->download_multiplier = 0;
                            }

                            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                            $hash = hash('md5', $ip . $this->config->item('salt_ip'));
                            $qdata = ['ih' => $hash, 'event' => 'login', 'date' => now()];
                            $this->db->insert('sessions', $qdata);

                            $sessiondata = array
                            (
                                'nickname' => $userdata->nickname,
                                'email' => $userdata->email,
                                'can_leech' => $userdata->can_leech,
                                'notifications' => $userdata->notifications,
                                'end_freeleech' => $userdata->end_freeleech,
                                'notified' => $userdata->notified,
                                'passkey' => $userdata->torrent_pass,
                                'rank' => $userdata->rank,
                                'uploaded' => $userdata->uploaded,
                                'downloaded' => $userdata->downloaded,
                                'download_multiplier' => $userdata->download_multiplier,
                                'id' => $userdata->id,
                                'avatar' => $userdata->avatar,
                                'allow_porn' => $userdata->allow_porn,
                                'logged' => true,
                            );
                            $this->session->set_userdata($sessiondata);

                        if ($this->session->upgrade_security) {
                            $this->output->set_content_type('application/json')
                                ->set_output(json_encode(array('target_url' => base_url() . 'user/upgrade_security')));
                        } else if ($this->session->can_leech == 0) {
                            $this->output->set_content_type('application/json')
                                ->set_output(json_encode(array('target_url' => base_url() . 'donation/bonus/disabled')));
                        }
                    } else {
                        $this->output->set_status_header(403);
                    }

                }
            }

        }

    }

    public function checkmail($email)
    {
        $result = '0';
        $domain = substr(strrchr($email, '@'), 1);

        if (function_exists('curl_init')) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://www.block-trashmail.space/api/' . $domain);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
            $result = curl_exec($ch);
            curl_close($ch);
        } else {
            $result = file_get_contents('https://www.block-trashmail.space/api/' . $domain);
        }

        return false;
        if ($result == '1') {
            return true;
        }
        return false;
    }

}