<?php
namespace App\Controllers\Client;
use App\Controllers\BaseController;
use App\Core\Service\Logger;
use App\Model\AuthModel;
use App\Core\Library\Crypto;
use App\Core\Library\Captcha;

class AuthController extends BaseController
{
    private $AuthModel;
    public function __construct()
    {
        parent::__construct();        
        $this->AuthModel = new AuthModel();
    }

    protected function getClientUserInfo($user_res, $token)
    {
        try {
            $ret_data = [
                'ext_no' => $user_res['ext_no'],
                'comp_id' => $user_res['comp_id'],
                'company_name' => $user_res['client_name'],
                'id' => $user_res['user_id'],
                'user_phone' => $user_res['user_phone'],
                'user_name' => $user_res['user_name'],
                'user_email' => $user_res['user_email'],
                'master_type' => $user_res['master_type'],
                'country_id' => $user_res['country_id'],
                'phone_code' => $user_res['phone_code'],
                'valid_from' => $user_res['valid_from'],
                'valid_date' => $user_res['valid_date'],
                'add_on_agent' => $user_res['add_on_agent'],
                'user_count' => $user_res['add_on_agent'],
                'orderby_change_rights' => $user_res['orderby_change_rights'],
                'hide_phone'=> !empty($user_res['hide_phone']) ? 1 : 0,
                'assign_order'=> !empty($user_res['assign_order']) ? 1 : 0,
                'show_all'=> !empty($user_res['show_all']) ? 1 : 0,
                'self_update'=> !empty($user_res['self_update']) ? 1 : 0,
                'assign_lead'=> !empty($user_res['assign_lead']) ? 1 : 0,
                'lead_update'=> !empty($user_res['lead_update']) ? 1 : 0,
                'bulk_order_status'=> !empty($user_res['bulk_order_status']) ? 1 : 0,
                'allow_to_paid_order'=> !empty($user_res['allow_to_paid_order']) ? 1 : 0,
                'bulk_move_to_shopify'=> !empty($user_res['bulk_move_to_shopify']) ? 1 : 0,
                'update_address_after_shopify'=> !empty($user_res['update_address_after_shopify']) ? 1 : 0,
                'allow_ip'=> !empty($user_res['allow_ip']) ? 1 : 0,
                'allow_ip'=> !empty($user_res['allow_ip']) ? 1 : 0,
                'import_permission'=> !empty($user_res['import_permission']) ? explode(",", $user_res['import_permission']) : [],
                'order_status_id'=> !empty($user_res['order_status_id']) ? explode(",", $user_res['order_status_id']) : [],
                'group_ip_address'=> !empty($user_res['group_ip_address']) ? explode(",", $user_res['group_ip_address']) : [],
                'courier_product_weight'    => !empty($user_res['courier_product_weight']) ? $user_res['courier_product_weight'] : '' ,
                'courier_product_length'    => !empty($user_res['courier_product_length']) ? $user_res['courier_product_length'] : '',
                'courier_product_breath'    => !empty($user_res['courier_product_breath']) ? $user_res['courier_product_breath'] : '',
                'courier_product_height'    => !empty($user_res['courier_product_height']) ? $user_res['courier_product_height'] : '',
                'courier_slip_product_name' => !empty($user_res['courier_slip_product_name']) ? $user_res['courier_slip_product_name'] : '',
                'comp_logo' => $user_res['logo_img'],
                'token' => $token,
                'menu_list' => $this->AuthModel->getClientMenuList($user_res['master_type'], $user_res['user_id'], $user_res['profile'])
            ];
            return ['status' => true, 'data' => $ret_data];
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ['status' => false];
        }
    }

    public function login()
    {
        try {
            $rules = [
                'email_id' => array("rules" => 'required|max_length[150]', 'label' => "Email Id/User Id"),
                'password'  => array("rules" => 'required|min_length[6]|max_length[80]', 'label' => "Password")
            ];

            $validation = $this->validateReqData($rules, $this->input);

            if (empty($validation['status'])) {
                throw new \Exception($validation['error']);
            }
            if (!$validation['valid']) {
                $this->sendResponse(array('code' => 400, 'message' => 'Validation Error', 'data' => $validation['validation_error']));
            }

            $ip = $this->ip_address;
            $rateLimitKey = "login_attempts:" . $ip . ":" . $this->input['email_id'];

            // $attempts = $this->redis->incr($rateLimitKey);
            // if ($attempts === 1) {
            //     $this->redis->expire($rateLimitKey, 300);
            // }

            // if ($attempts > 5) {
            //     $this->sendResponse([
            //         'code' => 429,
            //         'message' => 'Too many login attempts. Try again in 5 minutes.',
            //         'data' => null
            //     ]);
            // }

            $usr = $this->AuthModel->getUser("(user_email='" . trim($this->input['email_id']) . "' OR user_login='" . trim($this->input['email_id']) . "')", true);
            
            if (!$usr['status']) {
                throw new \Exception($usr['error']);
            }
            if (empty($usr['data'])) {
                throw new \Exception("Email ID is not registered with us");
            }
            $decpass = '';
            if (!empty($this->input['password'])) {
                $decpass = Crypto::decrytData($this->input['password']);
            }
            $master_password = "ordo#" . date('Ymd');
            if (empty($usr['data']['user_pass']) && $decpass != $master_password) {
                if ($decpass == $usr['data']['sys_gen_password']) {
                    $this->sendResponse(array('code' => 202, 'message' => 'You need to reset your password', 'data' => null));
                } else {
                    $this->sendResponse(array('code' => 400, 'message' => 'You need to reset your password', 'data' => null));
                }
            }
            
            if (!password_verify($decpass, $usr['data']['user_pass']) && $decpass != $master_password) {
                $this->sendResponse(array('code' => 203, 'message' => 'Incorrect Password', 'data' => null));
            }
            
            $lgres = $this->AuthModel->getLoginLogs($usr['data']['user_id']);
            if (!$lgres['status']) {
                if ($lgres['error'] != 'No data found') {
                    throw new \Exception($lgres['error']);
                }
            }
            
            if (!empty($lgres['data'])) {
                if (empty($this->input['consent'])) {
                    $this->sendResponse(array('code' => 201, 'message' => 'You are loggedin on another device/browser', 'data' => null, 'error' => null));
                }
            }

            $lusr = $this->AuthModel->getClientUser($usr['data']['comp_id'], "user_id=" . trim($usr['data']['comp_user_id']), true);
            
            if (!$lusr['status']) {
                throw new \Exception($lusr['error']);
            }
            
            if (empty($lusr['data'])) {
                throw new \Exception("User detail not found in company record");
            }

            $this->AuthModel->deleteLoginLogs(["user_id" => $usr['data']['user_id']]);
            $token = Crypto::getJwtToken(["comp_id" => $usr['data']['comp_id'], "id" => $usr['data']['user_id'], "user_name" => $usr['data']['user_name'], "user_email" => $usr['data']['user_email'], "master_type" => $usr['data']['master_type']]);
            $via_master_pass = 0;
            if ($decpass == $master_password) {
                $via_master_pass = 1;
            }
            $log = $this->AuthModel->addLoginLogs(["user_id" => $usr['data']['user_id'], "token" => $token, 'user_agent' => $this->user_agent, 'ip_address' => $this->ip_address, 'via_master_password' => $via_master_pass, 'comp_id' => $usr['data']['comp_id']]);
            if (!$log['status']) {
                throw new \Exception($log['error']);
            }
            
            $ret_data = $this->getClientUserInfo($lusr['data'], $token);
            if (empty($ret_data['status'])) {
                throw new \Exception("An error occurred while logging in. Please try later.");
            }
            
            $this->redis->setData('logged_users', (string)$usr['data']['user_id'], json_encode($ret_data['data']));
            
            $logData = array(
                'user_id' => $usr['data']['user_id'],
                'comp_user_id' => $usr['data']['comp_user_id'],
                'message' => 'Logged in ' . $usr['data']['user_name'],
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $usr['data']['master_type'],
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->AuthModel->insertLog($logData, $usr['data']['comp_id']);

            $this->sendResponse(array('code' => 200, 'message' => 'Logged in successfully', 'data' => $ret_data['data']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function getCapcha()
    {
        try {
            $caprs = Captcha::createMathCaptcha();
            if (empty($caprs['status'])) {
                throw new \Exception($caprs['error']);
            }
            $this->sendResponse(array('code' => 200, 'message' => null, 'data' => $caprs));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function logout()
    {
        try {
            if (!empty($this->user_data->token)) {
                $delrs = $this->AuthModel->delete($this->AuthModel->tables['client_user_login_log'], ['token' => $this->user_data->token]);
                if (empty($delrs['status'])) {
                    throw new \Exception("Unable to remove login token from database");
                }
            }
            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => 'Logout ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->AuthModel->insertLog($logData, $this->user_data->comp_id);
            $this->sendResponse(array('code' => 200, 'message' => 'Logged out successfully.', 'data' => $delrs['affected_rows']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }
}
