<?php

namespace App\Controllers\Auth;

use CodeIgniter\Controller;
use App\Controllers\BaseController;

class Login extends BaseController
{
    public function initController($request, $response, $logger)
    {
        parent::initController($request, $response, $logger);
    }
     
    public function index()
    { 
        $this->data['title'] = 'Login';
        return view('auth/login', $this->data);
    }

    public function userEmailLogin()
    {
        $this->data['title'] = 'Sign in';

        //Param
        $this->data['sessionid'] = $this->GUID();
        $email = \Config\Services::email();
        $otp = rand(100000, 999999);

        $rules = [
            'email'      => ['label' => 'Username', 'rules' => 'required|valid_email'], 
        ];

        $throttler = \Config\Services::throttler();
        $regulate = $throttler->check('logins', 3, MINUTE);

        //Rate limit login
        if(!$regulate){
            $this->session->setFlashdata('error', 'You reached the <strong>maximum</strong> login attempts.', 3);
			return redirect()->to('signin');
        }

        if(!$this->validate($rules)){
            session()->setFlashdata('error', 'Email can not be empty', 3);
            return redirect()->to('signin');
        }

        $clientEmail    = $this->request->getPost('email');
        $password       = $this->request->getPost('password');
        $getUser        = $this->usersModel->where('email', $clientEmail)->first($clientEmail);
        //Verify Email
        if(!$getUser  || $getUser['active'] != 1){
            session()->setTempdata('error', 'Incorrect login credentials', 3);
            return redirect()->to('signin');
        }
        
        //User send OTP and later create session.
        $browser = $this->getBrowser();
        $ip = $this->request->getIPAddress();
        $otp = rand(100000, 999999); // 6-digit OTP

        $this->userauthotpModel->saveOtp($getUser['id'], $otp, $browser, $ip);
        $this->sendOtpEmail($clientEmail, $otp);
        session()->setTempdata('success', "Welcome back <strong>".$getUser['first_name']."</strong>! Enter OTP to continue", 3);
        return redirect()->to('verify-otp/'.$getUser['id']);
    }

    //ADMINISTRATOR LOGIN - Email
    /**public function adminLogin()
    { 
        $this->data['title'] = 'Login';
        return view('auth/login-admin', $this->data);
    }**/
    public function login()
    {
        $this->data['title'] = 'Login';

        //Param
        $this->data['sessionid'] = $this->GUID();
        $email = \Config\Services::email();
        $otp = rand(100000, 999999);

        $rules = [
            'email'      => ['label' => 'Username', 'rules' => 'required'],
            'password'		 => ['label' => 'Password', 'rules' => 'required'], 
        ];

        $throttler = \Config\Services::throttler();
        $regulate = $throttler->check('logins', 3, MINUTE);

        //Rate limit login
        if(!$regulate){
            $this->session->setTempdata('error', 'You reached the <strong>maximum</strong> login attempts.', 3);
			return redirect()->to('account/login');
        }

        if(!$this->validate($rules)){
            session()->setTempdata('error', 'Email or Password can not be Empty', 3);
            return redirect()->to('account/login');
        }

        $clientEmail    = $this->request->getPost('email');
        $password       = $this->request->getPost('password');
        $getUser        = $this->usersModel->where('email', $clientEmail)->first($clientEmail);
        //Verify Email
        if(!$getUser || !password_verify($password, $getUser['password'])  || $getUser['status'] != 'active'){
            session()->setTempdata('error', 'Incorrect Email or Password', 3);
            return redirect()->to('account/login');
        }
        
        //User send OTP and later create session.
        $browser = $this->getBrowser();
        $ip = $this->request->getIPAddress();
        $otp = rand(100000, 999999); // 6-digit OTP
        $phone = $getUser['mobile'];

        $this->userauthotpModel->saveOtp($getUser['id'], $otp, $browser, $ip);
        //$this->sendWhatsappToken($phone, $otp);
        $this->sendOtpEmail($clientEmail, $otp);
        session()->setTempdata('success', "Welcome back <strong>".$getUser['first_name']."</strong>! Enter OTP to continue", 3);
        return redirect()->to('verify-otp/'.$getUser['id']);
    }

    //VERIFY OTP
    public function verifyOtp($id)
    {
        $this->data['title'] = 'Verify OTP';
        $this->data['userID'] = $id;
        
        $browser        = $this->getBrowser();
        $ip             = $this->request->getIPAddress();
        $sessionid      = $this->GUID();
        $admins         =$this->usersModel->getAdminUsers();
        
        if($this->request->getMethod() == 'POST')
        {
            $enteredOtp     = $this->request->getPost('otp');
            $checkUser 	    = $this->usersModel->where('id', $id)->first($id);
            $result         = $this->userauthgroupModel->where('user_id', $id)->first($id);

            if ($this->userauthotpModel->checkOtp($id, $enteredOtp)) {
                session()->set('logged_user', $sessionid);
                session()->set('loggedIn', true);
                //Session Table saved fields
                $sesndata = [
                    'user_id'       => $id,
                    'identifier'    => $checkUser['email'],
                    'ip'            => $this->request->getIPAddress(),
                    'id_type'       => $sessionid,
                    'user_agent'    => $this->getBrowser(),
                ];
                        
                //Notification
                $browser = $this->getBrowser();
                $ip = $this->request->getIPAddress();
                $message = "User ".$checkUser['email']."  has logged in ";
                $notification_type = 'security';
                $this->sendAdminNotifications($message, $notification_type, $id);

                if($result)
                {
                    if($result['group_id'] == 1 || $result['group_id'] == 2 || $result['group_id'] == 3){
                        $this->authloginModel->save($sesndata);
                        $this->session->setTempdata('success', "Welcome back, <strong>".$checkUser['first_name'] ."</strong>!", 3);
                        $this->successfulLogin($id, $browser, $ip);
                        return redirect()->to('administrator');
                        exit();
                    }elseif($result['group_id'] == 4){
                        $this->authloginModel->save($sesndata);
                        $this->session->setTempdata('success', "Welcome back, <strong>".$checkUser['first_name'] ."</strong>!", 3);
                        $this->successfulLogin($id, $browser, $ip);
                        return redirect()->to('seller/page');
                        exit();
                    }else{
                        $this->session->setTempdata('error', 'Sorry! Your account is either <strong>suspended</strong> or Not existing. Contact Support', 3);
                        return redirect()->to('signin');
                    }
                }else{
                    session()->setTempdata('error', 'Sorry! Your account is <strong>suspended</strong>. Contact Support', 3);
                    return redirect()->to('administrator/secure-lognin');
                }
                
            } else {
                session()->setTempdata('error', 'Invalid OTP', 3);
            }
        }
        
        return view('auth/verify_otp', $this->data);
    }


   //Forgot Password
    public function forgotPassword()
    { 
       $this->data['title'] = 'Forgot Password?';

        $hash = bin2hex(random_bytes(24));
        $ptoken = bin2hex(random_bytes(24));
        $validation =  \Config\Services::validation();
        $email = \Config\Services::email();
        $expiryTime = date('Y-m-d H:i:s', strtotime('+30 minutes'));

        $rules = [
            'email' => ['label'=>'Email', 'rules'=>'required']
        ];
        $userEmail = $this->request->getPost('email');

        if($this->request->getMethod() == 'POST')
        {
            if($this->validate($rules))
            {
                $checkUser = $this->usersModel->where('email', $userEmail)->first($userEmail);
                if($checkUser)
                {
                    $tokenData = [
                        'hashed_token'  => $hash,
                        'user_id'       => $checkUser['id'],
                        'ip_address'    => $this->request->getIPAddress(),
                        'expires'       => $expiryTime,
                    ];
                    if($this->userauthtokenModel->save($tokenData))
                    {
                        $clientName =  $checkUser['first_name'].' '.$checkUser['last_name'];
                        $clientEmail    = $userEmail;
                        $resetLink      = base_url()."reset-password=".$hash;


                        //Sending Email to Client
                        $emailTemplate = view('email_templates/reset_password_link_template', [
                            'clientName'      => $clientName,
                            'token'           => $hash,
                            'clientEmail'     => $clientEmail,
                            'resetLink'       => $resetLink,
                        ]);
                        $email->setMailType('html');
                        $email->setFrom('no-reply@lwegatechcms.info', 'REDD+ Administrator');
                        $email->setTo($clientEmail);
                        $email->setSubject( 'Password Request - REDD+ Administrator');
                        $email->setMessage($emailTemplate); 
                        if($email->send())
                        {
                            //Log this request for password reset.
                            $message = $clientEmail."  made a password reset request at ".date('Y-m-d H:i:s');
                            $notificationType = 'security';
                            $this->sendAdminNotifications($message, $notificationType, $checkUser['id']);
                            session()->setFlashdata('info', 'Password reset Email sent');
                            return redirect()->to('forgot-password=response-'.$ptoken);
                        }
                    }
                }else{
                    return redirect()->to('forgot-password=response-'.$ptoken);
                }
            }else{
                $this->data['errors'] = $this->validator->getErrors();
            }
        }
        return view('auth/forgot', $this->data);
    }
    
    
    //Reset Password
    public function resetPassword($token)
    { 
        $this->data['title'] = 'Reset Password';
        $checkToken = $this->userauthtokenModel->verifyToken($token);
        $getUser = $this->usersModel->where('id', $checkToken->user_id)->first($checkToken->user_id);
        if($token)
        {
            if(!empty($checkToken))
            {
               // Save password resets times for a user
               $resetTimes = [
                    'email'         => $getUser['email'],
                    'token'         => $token,
                    'ip_address'    => $this->request->getIPAddress(),
                    'user_agent'    => $this->getBrowser(),
                ];
                $this->userresetsattemptsModel->save($resetTimes);

                //Check for token Expiry
                $expired = (time() > strtotime($checkToken->expires));
                if(!$expired)
                {
                    $this->data['checkToken'] = $this->userauthtokenModel->verifyToken($token);
                    session()->setTempdata('success', 'You go ahead! Reset Password', 3);
                    return view('auth/reset_password', $this->data);
                }else
                {
                    session()->setTempdata('error', 'Sorry! Reset Password Token Expired or does not Exist', 3);
                    return redirect()->to('forgot-password');
                }
            }else
            {
                session()->setTempdata('error', 'Sorry! Reset Password Token Expired or does not Exist', 3);
                return redirect()->to('forgot-password');
            }
        }else
        {
            session()->setTempdata('error', 'Sorry! Reset Password Token Expired or does not Exist', 3);
            return redirect()->to('account/login');
        }
        
    }

    //update password
    public function updatePassword()
    {
        $this->data['title'] = 'Enter New Password';
        $this->data['checkToken'] = $this->userauthtokenModel->verifyToken($this->request->getPost('token'));
        $checkToken = $this->userauthtokenModel->verifyToken($this->request->getPost('token'));
        $email = \Config\Services::email();

        if($this->request->getMethod() == 'POST')
        {
            $checkUser = $this->usersModel->where('id', $checkToken->user_id)->first($checkToken->user_id);
            $rules = [
                'password'		 	 	 => ['label' => 'Password', 'rules' => 'required|min_length[8]|max_length[18]|alpha_numeric_punct'],
                'cpass'				 	 => ['label' => 'Confirm Password', 'rules' => 'required|min_length[8]|max_length[20]|matches[password]'],
            ];
            if(!$this->validate($rules))
            {
                $this->data['errors'] = $this->validator->getErrors();
                return view('auth/reset_password', $this->data);
            }else
            {
                $password = password_hash($this->request->getVar('password'), PASSWORD_DEFAULT);
                $newPwd = [
                    'password' => $password,
                ];
                if($this->usersModel->update_password($checkToken->user_id, $password))
                {
                    //Need to update User Auth Token table - updated time.
                    $this->userauthtokenModel->updateOnToken($checkToken->id);

                    //Notification
                    $browser = $this->getBrowser();
                    $ip = $this->request->getIPAddress();
                    $client  = $checkUser['first_name'].' '.$checkUser['last_name'];
                    $message = $client."  successfully updated password.";
                    $notificationType = 'security';
                    
                    //Sending Email to Client
                    $emailTemplate = view('email_templates/password_update_notification_template', [
                        'clientName'    => $client,
                        'ip'            => $ip,
                        'browser'       => $browser,
                        'clientEmail'   => $checkUser['email'],
                    ]);
                    $email->setMailType('html');
                    $email->setFrom('no-reply@lwegatechcms.info', 'REDD+ Administrator');
                    $email->setTo($checkUser['email']);
                    $email->setSubject( 'Your password has been updated - REDD+ Administrator');
                    $email->setMessage($emailTemplate); 
                    if($email->send())
                    {
                        //Log this request for password reset.
                        $this->sendAdminNotifications($message, $notificationType, $checkToken->user_id);
                        session()->setTempdata('success', 'Password updated successfully', 3);
                        return redirect()->to('account/login');
                    }
                }else
                {
                    session()->setTempdata('error', 'Sorry!, Unable to Change your password, Try again.', 3);
                    return redirect()->to(previous_url());
                }
            }
        }
        return view('auth/reset_password', $this->data);
    }

    //Message received on sending password recovery email.
	public function forgotPasswordResponse($code)
    {
        $this->data['code'] = bin2hex(random_bytes(24));
        $this->data['title'] = 'Check Email';
        return view('auth/forgot-password-page', $this->data);
    }

    public function multipleLogins()
    { 
        return view('auth/multiple_logins');
    }

    //Check Member Email Availability
    public function checkEmail()
    {
        // Only respond to AJAX requests
        if (!$this->request->isAJAX()) {
            return $this->response->setStatusCode(403)->setJSON(['error' => 'Forbidden']);
        }

        $email = $this->request->getPost('email');
        
        if (empty($email)) {
            return $this->response->setJSON(['available' => false]);
        }

        // Check email in both tables
        $existsInMembers = $this->clientsModel->where('email', $email)->countAllResults() > 0;
        $existsInUsers = $this->usersModel->where('email', $email)->countAllResults() > 0;
        
        // Email is available only if it doesn't exist in either table
        return $this->response->setJSON([
            'available' => !($existsInMembers || $existsInUsers),
            'exists_in' => [
                'members' => $existsInMembers,
                'users' => $existsInUsers
            ]
        ]);

        return $this->response->setJSON(['available' => !$exists]);
    }

}
