<?php
/*
 * Copyright (c) 2023.
 *
 * A.Сапаргалиев
 * ТОО "Дизайн лаборатория А7"
 * Астана
 */

namespace App\Modules\Auth\Http\Controllers;

use A7kz\Platform\Http\Controllers\Controller;
use A7kz\Platform\Models\UniModel;
use A7kz\Platform\Modules\Platform\Acl\Facades\Acl;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function hasTooManyLoginAttempts($request){
        $tries = (int)Cache::get('LOGINATTEMP_'.$request->get("username").$request->get("email"));
        if($tries > 5 ){
            return true;
        }
        return false;
    }

    public function setAttemp($request){
        $tries = (int)Cache::get('LOGINATTEMP_'.$request->get("username").$request->get("email"));
        $tries++;
        Cache::put('LOGINATTEMP_'.$request->get("username").$request->get("email"), $tries, 900);
    }

    public function resetAttempt($request){
        Cache::delete('LOGINATTEMP_'.$request->get("username").$request->get("email"));
    }

    public function login(Request $request)
    {
        $this->validateLogin($request);

        $user = UniModel::model('core_users')->where('email', $request->email)
            ->orWhere('username', $request->email)->first();

        if (!$user) {
            return view('platform.auth::login', ['error' => ['email' => trans('auth.email')]]);
        }

        if (!Hash::check($request->password, $user->password)) {
            return view('platform.auth::login', ['error' => ['password' => trans('auth.password')]]);
        }

        if (method_exists($this, 'hasTooManyLoginAttempts') &&
            $this->hasTooManyLoginAttempts($request)) {
            return view('platform.auth::login', ['error'=>['email'=>trans('Превышено допустимое количество попыток, попробуйте через 15 минут')]]);
        }

        if ($this->attemptLogin($request)) {
            if ($request->hasSession()) {
                $companyId = Acl::getLastActiveCompany(Auth::id()) ? Acl::getLastActiveCompany(Auth::id()) : Acl::getDefaultCompanyId(Auth::id());
                $request->session()->put('auth.password_confirmed_at', time());
                $request->session()->put('user.company_id', $companyId);
                $request->session()->put('user.rights', Acl::getUserRights(Auth::id(),Acl::company_id()));
                $request->session()->put('user.segment', Acl::getSegment(Acl::company_id()));
                $request->session()->put('user.name',  Auth::user()->name);

                $this->resetAttempt($request);
            }
            return $this->sendLoginResponse($request);
        }

        $this->setAttemp($request);

//        $this->sendFailedLoginResponse($request);

        return view('platform.auth::login', ['error'=>['email'=>trans('auth.failed')]]);
    }

    public function username()
    {
        $validator = Validator::make(['email' => request()->email], [
            'email'=>'required|email'
        ]);
        $field = ($validator->fails()) ? 'username' : 'email';

        request()->merge([$field => request()->email]);
        return $field;
    }

    /**
     * Show the application's login form.
     *
     * @return \Illuminate\View\View
     */
    public function showLoginForm()
    {
        return view('platform.auth::login');
    }

    /**
     * Log the user out of the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    public function logout(Request $request)
    {
        $this->guard()->logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        if ($response = $this->loggedOut($request)) {
            return $response;
        }

        return $request->wantsJson()
            ? new JsonResponse([], 204)
            : redirect(lurl("/"));
    }

    /**
     * Send the response after the user was authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendLoginResponse(Request $request)
    {
        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        if ($response = $this->authenticated($request, $this->guard()->user())) {
            return $response;
        }

        return $request->wantsJson()
            ? new JsonResponse([], 204)
            : redirect()->intended(lurl($this->redirectPath()));
    }
}
