<?php

namespace MicroweberPackages\User\Http\Controllers;

use App\Http\Resources\User\UserResource;
use Illuminate\Auth\Events\Login;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Illuminate\Routing\Pipeline;
use Illuminate\Support\Facades\Auth;
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
use Laravel\Fortify\Contracts\LoginResponse;
use Laravel\Fortify\Features;
use Laravel\Fortify\Fortify;
use MicroweberPackages\Event\Event;
use MicroweberPackages\Option\Facades\Option;
use MicroweberPackages\User\Http\Requests\LoginRequest;
use MicroweberPackages\User\Models\User;
use Illuminate\Support\Facades\Session;

class UserLoginController extends Controller
{
    public $middleware = [
        [
            'middleware' => 'xss',
            'options' => []
        ]
    ];

    public function __construct()
    {
        event_trigger('mw.init');
    }

    /**
     * Display a listing of Role.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {

        if (Auth::check() && Auth::user()->is_admin == 1) {
            return redirect(admin_url());
        }

        $parsed = view('user::admin.auth.index');

        return app()->parser->process($parsed);
    }

    public function loginForm()
    {
        $parsed = view('user::admin.auth.index');

        return app()->parser->process($parsed);
    }

    public function loginWithTwoFactory($request)
    {
        $response = $this->loginPipeline($request)->then(function ($request) {
            return app(LoginResponse::class);
        });

        if (method_exists($response, 'getData')) {
            if (isset($response->getData()->two_factor)) {
                return [
                    'success'=>true,
                    'redirect'=>route('two-factor.login')
                ];
            }
        }

        return $response;
    }

    /**
     * login api
     *
     * @param \MicroweberPackages\User\Http\Requests\LoginRequest $request
     */
    public function login(LoginRequest $request)
    {
        $requestLang = $request->post('lang');
		$redirectParams = $request->only('http_redirect', 'redirect', 'where_to');

		if (!empty($requestLang)) {
            mw()->lang_helper->set_current_lang($requestLang);
            \Cookie::queue('lang', $requestLang, 86400 * 30);
        }
        $is_logged_out = false;
        if (Auth::check()) {
            $user = Auth::user();

            if ($user and isset($user->is_active) and intval($user->is_active) == 0) {
                // logout user if its set inactive in database
                Auth::logout();
                $is_logged_out = true;
            }

            // This will be used for whmcs login redirect
			if (isset($redirectParams['http_redirect'])) {
                if (!$is_logged_out and intval($user->is_admin) == 1 && (isset($redirectParams['where_to']) && $redirectParams['where_to'] == 'admin_content')) {
                    return redirect(admin_url());
                } else {
                    return redirect(site_url());
                }
            }

            $message = [];
//            if (!$is_logged_out and Auth::user()->is_admin == 1) {
//                //"message": "SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO) (SQL: select exists(select * from `oauth_personal_access_clients`) as `exists`)",
//              //  $message['token'] = auth()->user()->createToken('authToken');
//            }

            if(!$is_logged_out and $user and isset($user->is_active) and intval($user->is_active) == 0){
                $message['data'] = [];
                $message['error'] = 'Your account is disabled';
                return response()->json($message, 200);
            } else {
                $message['data'] = auth()->user();
                $message['success'] = 'You are logged in';
                return response()->json($message, 200);
            }

        }

        if (!isset($request['email']) and isset($request['username'])) {
            $userId = detect_user_id_from_params($request);

            if($userId){
                $userFind = User::where('id',$userId)->first();
                if(!empty($userFind->email)){
                    $request->merge(['email' => $userFind->email]);
                    $request->offsetUnset('username');
                }
                if(!empty($userFind->username)){
                    $request->merge(['username' => $userFind->username]);
                    $request->offsetUnset('email');
                }
            }
        }

         Session::flash('old_sid', Session::getId());
         $loginData = $this->loginFields($request->only('username', 'email', 'password'));

         if (isset($loginData['username']) || isset($loginData['email'])) {
             $checkAuthField = false;
             if (isset($loginData['username'])) {
                $checkAuthField = $loginData['username'];
             }
             if (isset($loginData['email'])) {
                $checkAuthField = $loginData['email'];
             }
             if ($checkAuthField) {
                 $checkUser = User::select('email', 'username', 'two_factor_secret')
                     ->where('email', $checkAuthField)
                     ->orWhere('username', $checkAuthField)
                     ->first();

                 if (!empty($checkUser)) {
                     if (!empty($checkUser->two_factor_secret)) {
                         $response = $this->loginWithTwoFactory($request);
                         if (!empty($response)) {
                             return $response;
                         }
                     }
                 }
             }
         }

        $login = Auth::attempt($loginData,$remember = true);
        if ($login) {

            $isApprovalRequired = Option::getValue('registration_approval_required', 'users');
            $isVerfiedEmailRequired = Option::getValue('register_email_verify', 'users');

            $userData = auth()->user();

            if (Auth::user()->is_admin == 0) {

                if ($isVerfiedEmailRequired) {

                    if (!$userData->hasVerifiedEmail()) {
                        $message = [];
                        $message['error'] = 'Please verify your email address. Please check your inbox for your account activation email';
                        Auth::logout();
                        return response()->json($message, 200);
                    }
                }

                 if ($isApprovalRequired) {
                    if (!$userData->is_active) {
                        $message = [];
                        $message['error'] = 'Your account is awaiting approval';
                        Auth::logout();
                        return response()->json($message, 200);
                    }
                }
            }

//            if (Auth::user()->is_admin == 1) {
//                //"message": "SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO) (SQL: select exists(select * from `oauth_personal_access_clients`) as `exists`)",
//
//                //   $userData->token = auth()->user()->createToken('authToken');
//            }

            if ($userData and !$userData->is_active) {
                $message = [];
                $message['error'] = 'Your account is disabled';
                Auth::logout();
                return response()->json($message, 200);
            }


            $response['success'] = _e('You are logged in', 1);
            app()->user_manager->login_set_success_attempt($request);

            if (isset($redirectParams['where_to']) and $redirectParams['where_to']) {
                if (Auth::user()->is_admin == 1 && (isset($redirectParams['where_to']) && $redirectParams['where_to'] == 'admin_content')) {
                    $redirectParams['redirect'] = admin_url();
                } else {
                    $redirectParams['redirect'] = site_url();
                }
            }

            if (isset($redirectParams['http_redirect'])) {
                if (Auth::user()->is_admin == 1 && (isset($redirectParams['where_to']) && $redirectParams['where_to'] == 'admin_content')) {
                    return redirect(admin_url());
                }  if (Auth::user()->is_admin == 1 && (isset($redirectParams['where_to']) && $redirectParams['where_to'] == 'live_edit')) {
                    return redirect(site_url().'?editmode=y');
                }else {
                    return redirect(site_url());
                }
            }

            if (isset($redirectParams['redirect'])) {
                $response['redirect'] = $redirectParams['redirect'];
            }

            $response['data'] = auth()->user();

            return new  JsonResource($response);
        }

        app()->user_manager->login_set_failed_attempt($request);

        return response()->json(['error' =>_e( 'Wrong username or password.',true)], 401);
    }

    protected function loginPipeline(LoginRequest $request)
    {
        if (Fortify::$authenticateThroughCallback) {
            return (new Pipeline(app()))->send($request)->through(array_filter(
                call_user_func(Fortify::$authenticateThroughCallback, $request)
            ));
        }

        if (is_array(config('fortify.pipelines.login'))) {
            return (new Pipeline(app()))->send($request)->through(array_filter(
                config('fortify.pipelines.login')
            ));
        }

        return (new Pipeline(app()))->send($request)->through(array_filter([
            config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
            Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
            AttemptToAuthenticate::class,
            PrepareAuthenticatedSession::class,
        ]));
    }

    public function loginFields($request)
    {
        if (!isset($request['username']) and isset($request['username_encoded']) and $request['username_encoded']) {

            $decodedUsername = @base64_decode($request['username_encoded']);
            if (!empty($decodedUsername)) {
                $request['username'] = $decodedUsername;
            } else {
                $request['username'] = @base62_decode($request['username_encoded']);
            }
        }

        if (!isset($request['email']) and isset($request['email_encoded']) and $request['email_encoded']) {
            $decodedEmail = @base64_decode($request['email_encoded']);
            if (!empty($decodedEmail)) {
                $request['email'] = $decodedEmail;
            } else {
                $request['email'] = @base62_decode($request['email_encoded']);
            }
        }

        if (!isset($params['password']) and isset($request['password_encoded']) and $request['password_encoded']) {
            $decodedPassword = @base64_decode($request['password_encoded']);
            if (!empty($decodedPassword)) {
                $request['password'] = $decodedPassword;
            } else {
                $request['password'] = @base62_decode($request['password_encoded']);
            }
        }

        if (isset($request['username']) && $request['username'] != false and filter_var($request['username'], FILTER_VALIDATE_EMAIL)) {
            $request['email'] = $request['username'];
            unset($request['username']);
        }

        return $request;
    }

    public function logout()
    {
        return Auth::logout();
    }

    private function _isApprovalRequired()
    {


        // return false;
// @todo

//        $register_email_verify = get_option('register_email_verify', 'users');
//        $registration_approval_required = get_option('registration_approval_required', 'users');
//
//
//        $found = false;
//        $inputs = $this->all();
//        if ($inputs and isset($inputs['username']) and $inputs['username']) {
//            $found = User::where('username', $inputs['username'])->first();
//        } else if ($inputs and isset($inputs['email']) and $inputs['email']) {
//            $found = User::where('email', $inputs['username'])->first();
//        }

        //  throw new AuthorizationException('This action is unauthorized.');


        //   $user =


//            if ($user_data['is_active'] == 0) {
//
//                $registration_approval_required = get_option('registration_approval_required', 'users');
//                $register_email_verify = get_option('register_email_verify', 'users');
//                if ($registration_approval_required == 'y') {
//                    return array('error' => 'Your account is awaiting approval');
//                } elseif ($user_data['is_verified'] != 1 && $register_email_verify == 'y') {
//                    return array('error' => 'Please verify your email address. Please check your inbox for your account activation email');
//                } else {
//                    return array('error' => 'Your account has been disabled');
//                }
//            }

    }
}
