<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Admin\VendorIntegrationController;
use App\Http\Requests\LoginRequest;
use App\Slack;
use App\User;
use App\UserPermissions;
use Carbon\Carbon;
use Hashids\Hashids;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;

class LoginController extends Controller
{
    private $fullLists = [];
    private $index = 0;
    private $lists;
    /**
     * @var Request
     */
    private $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function getLogin()
    {
        if (Auth::check()) {
            return redirect()->to('admin');
        } else {
            return view('login');
        }
    }

    public function postLogin(LoginRequest $request)
    {
        // Temporarily removed password based login basis event on 18/09/24
//        return Socialite::driver('google')->redirect();
//        if(env('APP_CONNECTION')) {
////            (new Slack(new Request(['title' => 'Error 3', 'fields' => ['c' => 1], 'group' => Slack::$STAGE_TESTING])))->send();
//            return Socialite::driver('google')->redirect();
//        }else{
            return $this->postLogin1($request);
//        }
    }

    public function sessionBabyReadyAppKeys(){
        $client_id = base64_encode(json_encode(Auth::user()));
        $client_secret = env('APP_KEY');
        return '?client_id='.$client_id.'&client_secret='.$client_secret;
    }

    public function loadPermissions($sessions = true){

        $_d_sidebar = Config::get('constants.sidebar');
        $_d_permissions = Config::get('constants.permissions');
        $_d_sub_permissions = Config::get('constants.sub_permissions');
        $_d_exception = Config::get('constants.exception');
        $user = Auth::user();

        $postData = UserPermissions::where('user_type_id',$user->user_type)->first(['permissions']);
        if (!$postData)
            return false;
        $fullLink = [];

        if (isset($postData->permissions)) {
            $postData = json_decode($postData->permissions, 1);
            Session::put('permissions', $postData);
            Session::put('baby_ready_secret', $this->sessionBabyReadyAppKeys());
            array_map(function($item) use ($_d_permissions, $_d_sub_permissions){
                Session::put($item, true);
                $_key = explode('|-',$item)[0];

                $_key = isset($_d_permissions[$_key]) ? $_key : str_replace('_',' ',$_key);

                if(isset($_d_permissions[$_key]) && !empty($_d_permissions[$_key])){
                    foreach ($_d_permissions[$_key] as $_link_i) {
                        $this->lists[$_link_i] = $item;
                    }
                }
                
                // Handle sub_permissions
                foreach ($_d_sub_permissions as $sub_permission_group => $sub_permission_items) {
                    foreach ($sub_permission_items as $sub_permission_name => $sub_permission_links) {
                        $sub_permission_key = str_replace(' ', '_', $sub_permission_name);
                        if ($_key == $sub_permission_key || str_replace('_', ' ', $_key) == $sub_permission_name) {
                            if (!empty($sub_permission_links)) {
                                foreach ($sub_permission_links as $_link_i) {
                                    $this->lists[$_link_i] = $item;
                                }
                            }
                        }
                    }
                }
                
                $this->index++;
            },$postData);
        }

        foreach ($_d_permissions as $d_permission) {
            foreach ($d_permission as $s_permission) {
                $this->loadLinks(['link' => $s_permission]);
            }
        }
        
        // Load links for sub_permissions
        foreach ($_d_sub_permissions as $sub_permission_group => $sub_permission_items) {
            foreach ($sub_permission_items as $sub_permission_name => $sub_permission_links) {
                if (!empty($sub_permission_links)) {
                    foreach ($sub_permission_links as $s_permission) {
                        $this->loadLinks(['link' => $s_permission]);
                    }
                }
            }
        }

        foreach ($_d_exception as $d_exception) {
            $this->lists[$d_exception] = '';
            $this->loadLinks(['link' => $d_exception]);
        }

        $lists = $this->lists;

        if ($postData) {
            //$main_module = 0;
            foreach ($_d_sidebar as $_d_name => $_d_bar) {
                $main_module = $_d_bar['id'];
                $module_id = 0;
                foreach ($_d_bar['list'] as $_d_item_name => $_d_item) {
                    if (isset($_d_item['permission'])) {

                        foreach ($_d_item['permission'] as $action_id => $_d_item_m) {
                            $unique_input_string = $_d_item_name . '_' . $_d_item_m['name'] . '|' . $main_module . '-' . $module_id . '-' . $action_id;
                            $unique_input_string = str_replace(' ', '_', $unique_input_string);
                            if (isset($_d_item_m['link']) && in_array($unique_input_string, $postData)) {
                                if (is_array($_d_item_m['link'])) {
                                    foreach ($_d_item_m['link'] as $link) {
                                        $lists[$link] = $unique_input_string;
                                    }
                                } else {
                                    $lists[$_d_item_m['link']] = $unique_input_string;
                                }
                            }
                            if (isset($_d_item_m['link']))
                                $this->loadLinks($_d_item_m);
                        }

                        if (isset($_d_item['sub-module'])) {
                            foreach ($_d_item['sub-module'] as $sub_module_id => $_d_item_m) {
                                foreach ($_d_item_m['permission'] as $action_ms_id => $_d_item_ms) {
                                    if(isset($_d_item_ms['link'])) {
                                        $unique_input_string = $_d_item_name . '_' . $_d_item_m['name'] . '_' . $_d_item_ms['name'] . '|' . $main_module . '-' . $module_id . '-' . $sub_module_id . '-' . $action_ms_id;
                                        $unique_input_string = str_replace(' ', '_', $unique_input_string);
                                        $unique_input_string = str_replace(' ', '_', $unique_input_string);
                                        if (in_array($unique_input_string, $postData)) {
                                            if (is_array($_d_item_ms['link'])) {
                                                foreach ($_d_item_ms['link'] as $link) {
                                                    $lists[$link] = $unique_input_string;
                                                }
                                            } else {
                                                $lists[$_d_item_ms['link']] = $unique_input_string;
                                            }
                                        }
                                        if(isset($_d_item_ms['link']))
                                            $this->loadLinks($_d_item_ms);
                                    }
                                }
                            }
                        }
                    }
                    $module_id++;
                }
                $main_module++;
            }
            
            // Process sub_permissions
            $_sub_permission_group_index = 0;
            foreach ($_d_sub_permissions as $sub_permission_group => $sub_permission_items) {
                $_sub_permission_index = 0;
                foreach ($sub_permission_items as $sub_permission_name => $sub_permission_links) {
                    $unique_input_string = str_replace(' ', '_', $sub_permission_name) . '|-' . $_sub_permission_group_index . '-' . $_sub_permission_index;
                    if (in_array($unique_input_string, $postData)) {
                        Session::put($unique_input_string, true);
                        if (!empty($sub_permission_links)) {
                            foreach ($sub_permission_links as $link) {
                                $lists[$link] = $unique_input_string;
                            }
                        }
                    }
                    $_sub_permission_index++;
                }
                $_sub_permission_group_index++;
            }
        }

        if (isset($lists) && $sessions) {
            $routeCollection = Route::getRoutes();
            $links = [];
            foreach ($routeCollection as $value) {
                if (!in_array('POST', $value->methods()) && !in_array($value->uri(), $this->fullLists)) {
                    $links[$value->uri()] = isset($lists[0]) ? $lists[0] : '';
                }
            }
            if ($links){
                $lists = array_merge($lists, $links);
            }
            Session::put('permissionsLinks', $lists);
        }
        if (isset($lists) && !$sessions)
            return $lists;

        return true;
    }

    public function loadLinks($item){
        if (is_array($item['link'])) {
            foreach ($item['link'] as $link) {
                $this->fullLists[] = $link;
            }
        } else {
            $this->fullLists[] = $item['link'];
        }
    }

    /**
     * Obtain the user information from GitHub.
     *
     * @return \Illuminate\Http\Response
     */
    public function handleProviderCallback()
    {
        try {

            $user = Socialite::driver('google')->user();
            if ($user && $user->getEmail()) {
                $email = $user->getEmail();
                //$authEmailArray = ['Sharmabhaskar21@gmail.com','Poojaaagarwal1998@gmail.com'];
                if (strpos($email, '@creditfair.in') !== false || strpos($email, '@kmglobal.in') !== false || strpos($email, '@babyready.app') !== false) {
                    $userData = User::where('email', $user->getEmail())->where('user_type', '>=', 5)->whereNull('deleted_at')->first(['id']);

                    if (isset($userData->id)) {
                        $userUpdate = User::find($userData->id);
                        $userUpdate->google_token = isset($user->token) ? $user->token : '';
                        $userUpdate->save();
                        //$refreshToken = $user->refreshToken; // not always provided
                        //$expiresIn = $user->expiresIn;

                        //$token = $user->token;
                        //$tokenSecret = $user->tokenSecret;
                        Session::put(['gData' => [
                                'id' => $user->getId(),
                                'nick_name' => $user->getNickname(),
                                'name' => $user->getName(),
                                'avatar' => $user->getAvatar()]]
                        );

                        if (Auth::loginUsingId($userData->id)) {
                            $this->rememberSession($userData);
                            if ($this->loadPermissions()) {
                                $data = Session::get('permissionsLinks');
                                if(!isset($data['admin'])){
                                    foreach ($data as $key => $item){
                                        if($item && !(strpos($key, '}') !== false)){
                                            return redirect()->to($key);
                                        }
                                    }
                                }else{
                                    return redirect()->intended('admin');
                                }
                            }
                        } else {
                            Session::flash('error', 'Incorrect username or password. Please try again...');
                            return redirect()->to('admin\login')->withInput();
                        }
                    }
                }
            }
        }catch (\Exception $e){
            $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
            return Redirect::to(str_replace('https://','https://www.',$url));
        }
        Session::flash('error','Incorrect username or password. Please try again.');
        return redirect()->to('admin\login')->withInput();
        //$user = Socialite::driver('google')->userFromToken($token);
    }

    public function loginWithOTP($userData){

        if (isset($userData->id)) {

            if (Auth::loginUsingId($userData->id)) {
                $this->rememberSession($userData);
                if ($this->loadPermissions()) {
                    $data = Session::get('permissionsLinks');
                    if(!isset($data['admin'])){
                        foreach ($data as $key => $item){
                            if($item && !(strpos($key, '}') !== false)){
                                return redirect()->to($key);
                            }
                        }
                    }else{
                        return redirect()->intended('admin');
                    }
                }
            } else {
                Session::flash('error', 'Incorrect username or password. Please try again...');
                return redirect()->to('admin\login')->withInput();
            }
        }
    }

    public function checkStatusLoginAuthenticate(Request $request){
        if($request->get('cknt') == csrf_token() && $request->input('ckn')) {
            $hashids = new Hashids('Creditfair by CS', 20);
            $deli = explode('|', $request->input('ckn'));
            $id = $hashids->decode($deli[0]);
            $time = $hashids->decode($deli[1]);
            $id = $id[0];
            $time = $time[0];
            if($time > time() && $id) {
                $user = User::where('id', $id)->first(['id']);
                return $this->loginWithOTP($user);
            }else{
                Session::flash('error', 'Incorrect mobile or otp. Please try again...');
                return redirect()->to('admin\login')->withInput();
            }
        }
    }

    public function authenticating_user(){

        $ckn = Session::get('ckn');

        $tkn = '/admin/otp/login/?cknt=' . csrf_token() . '&ckn=' . $ckn;

        return view('login_m', ['cknt' => csrf_token(), 'ckn'=> $ckn, 'tkn' => $tkn]);
    }

    public function postLogin1(LoginRequest $request)
    {
        $credentials = $request->only('username', 'password');
        $remember_me = false;
        if ($request->has('remember')) {
            $remember_me = true;
        }

        if (Auth::attempt($credentials, $remember_me)) {
            $this->rememberSession(Auth::user());
//            (new Slack(new Request(['title' => 'Error 9', 'fields' => ['c' => 1], 'group' => Slack::$STAGE_TESTING])))->send();
            if ($this->loadPermissions()) {
//                (new Slack(new Request(['title' => 'Error 5', 'fields' => ['c' => 1], 'group' => Slack::$STAGE_TESTING])))->send();
                return redirect()->intended('admin');
            }
        }

        Session::flash('error','Incorrect username or password. Please try again..');
        return redirect()->back()->withInput();
    }

    public function getLogout(Request $request)
    {
        if (Auth::check()) {
        	Auth::logout();
            $request->session()->forget('permissionsLinks');
            $request->session()->forget('permissions');
            $request->session()->flush();
            return redirect()->to('admin/login');
        } else {
            return redirect()->to('admin/login');
        }
    }

    public function rememberSession($userData)
    {
        $remember_token = Str::random(60);
        User::where('id', $userData->id)->update(['remember_token' => $remember_token]);
        $this->request->session()->put('remember_token', $remember_token);
    }
}
