<?php

namespace App\Http\Controllers\Web;


use App\Helpers\Sms;
use App\User;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Lang;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use function response;

class UserController extends Controller
{

    use ThrottlesLogins;

    /**
     * The maximum number of attempts to allow.
     *
     * @return int
     */
    protected $maxAttempts = 3;


    /**
     * The number of minutes to throttle for.
     *
     * @return int
     */
    protected $decayMinutes = 1;


    /**
     * The field name throttle trait will use for.
     *
     * @return string
     */
    public function username() : string
    {
        return 'username';
    }

    protected $view = 'web.users.';

    /**
     * Check verify code attempt and if it's correct or not
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function verifyCode(Request $request)
    {

        $code = implode('',  array_reverse($request->code));

        if (mb_strlen($code) < 4){
            return $this->checkAttemptCount($request) ?? response()->json(['errors' => __('members.enter_full_code')]);
        }

        $user = User::where('phone', $request->phone)
            ->where('email', $request->email)
            ->where('verify_code', $code)->first();

        if (!$user){
            return $this->checkAttemptCount($request) ?? response()->json(['errors' => __('members.invalid_verification_code')]);
        }


        // Check the number of attempts to check the code
        if ($user->code_verify_attempt >= 6 && strtotime($user->last_attempt_date) == strtotime(date('Y-m-d')) ) {
            return $this->checkAttemptCount($request) ?? response()->json(['errors' => __('members.verification_tries_exceed')]);
        }

        // Check if date less then today
        if ($user->last_attempt_date && strtotime($user->last_attempt_date) < strtotime(date('Y-m-d'))){
            $user->update(['code_verify_attempt' => 0, 'last_attempt_date' => date('Y-m-d')]);
        }

        // The user entered the wrong code and the number of attempts increased
        if (strtotime($user->last_attempt_date) == strtotime(date('Y-m-d')) && $user->verify_code != $code){
            $user->update(['code_verify_attempt' => $user->code_verify_attempt+1]);
            return $this->checkAttemptCount($request) ?? response()->json(['errors' => __('members.invalid_verification_code')]);
        }

        $user->update(['verify_code' => null]);

        return response()->json(['message' => __('members.correct_code')]);
    }

    /**
     * check attempt try and generate code
     * @param $user
     * @return array
     */
    private function generateVerifyCode($user)
    {

        /**
         * It's commented for test only and after test
         * delete comment
         */

        if ($user->attempt_send_code >= 6 && strtotime($user->last_attempt_date) == strtotime(date('Y-m-d')) ) {
            return ['errors' => __('members.verification_code_exceed')];
        }

        if ($user->last_attempt_date && strtotime($user->last_attempt_date) < strtotime(date('Y-m-d'))){
            $user->update(['code_verify_attempt' => 0, 'attempt_send_code' => 0,'last_attempt_date' => date('Y-m-d')]);
        }

        $attempt_send_code = $user->attempt_send_code + 1;
        $last_attempt_date = date('Y-m-d');
        $code = rand(1000,9999);

//        session()->put(['verify_code' => $code]);

//        $phone = explode('0', $user->phone, 2);
        $phone = $user->phone;

        // This line is temporary and will be deleted later
        $code = in_array($phone, ['581524713', '543605073', '500000000']) ? '1234' : $code;

//        try{
//            $message = __('members.sms_message');
//            $message = str_replace('@@', $code, $message);
//            Sms::send($phone, $message);
//        } catch (Exception $exception){
//            return ['errors' => __('members.sms_error')];
//        }

        /**
         * $data = [
        'user' => $user->name,
        'email' => $user->email,
        'code' => $code,
        ];
        CodeVerificationJob::dispatch($data, 'web.members.emails.verification_email');
         */

        $user->update(
            [
                'verify_code' => $code,
                'attempt_send_code' => $attempt_send_code,
                'last_attempt_date' => $last_attempt_date,
            ]
        );

        return ['errors' => false, 'code' => $code];
    }


    /**
     * Resend code for register and login
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function sendCode(Request $request)
    {
        if ($request->ajax()){
            $phonePattern = '/^(5){1}([0-9]{8})$/';
            $validation = Validator::make($request->all(), [
                'phone' => ['required','regex:'.$phonePattern],
            ], [], ['phone' => __('reservations.phone')]);
            if ($validation->fails()){
                return response()->json([
                    'errors' => $validation->errors()->first(),
                ]);
            }

            $user = User::orWhere('phone', $request->phone)->orWhere('email', $request->email)->first();

            if (!$user){
                $user = User::create([
                    'name' => $request->name,
                    'email' => $request->email,
                    'phone' => $request->phone,
                    'role' => 'user',
                ]);
//                return $this->checkAttemptCount($request) ?? response()->json(['errors' => __('members.invalid_verification_code')]);
            } else {
                $user->update(['email' => $request->email, 'phone' => $request->phone]);
            }

            if ($this->checkAttemptCount($request)){
                return $this->checkAttemptCount($request);
            }

            $generateVerifyCode = $this->generateVerifyCode($user);

            if ($generateVerifyCode['errors']){
                return $this->checkAttemptCount($request) ?? response()->json($generateVerifyCode);
            }

            return response()->json([
                'errors' => false,
                'success' => true,
                'message' => __('members.code_send_to_phone'),
                'code' => $generateVerifyCode['code']
            ]);
        }
    }


    /**
     * Check user attempts count
     * @param $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function checkAttemptCount($request)
    {
        if (method_exists($this, 'hasTooManyLoginAttempts') &&
            $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return $this->sendLockoutResponse($request);
        }
        $this->incrementLoginAttempts($request);

    }

    /**
     * Override parent sendLockoutResponse to handle it
     * to return json response
     * @param Request $request
     * @return JsonResponse
     */
    protected function sendLockoutResponse(Request $request)
    {
        $seconds = $this->limiter()->availableIn(
            $this->throttleKey($request)
        );
        return response()->json(['errors' => Lang::get('auth.throttle', [
            'seconds' => $seconds,
            'minutes' => ceil($seconds / 60),
        ])]);
    }


    public function storeDeviceToken(Request $request)
    {
        if ($request->ajax() && !$request->isMethod('GET')){
            $token = $request->device_token;
            $data = [
                'token' => $token,
                'platform' => 'web'
            ];
            $user = Auth::user();
            $user->update([
                'device_token' => $data
            ]);

            return ['status' => true];
        }
    }





}
