<?php

namespace App\Http\Controllers\Auth;

// Laravel Specifics
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Hash;

// Creatia Specifics
use App\Http\Controllers\BaseController;
use App\Models\CodeUserReset;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Carbon\Carbon;

// TO DO - Better logging on account setup

class TokenController extends BaseController
{
    /*
    |--------------------------------------------------------------------------
    | Token Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles any email-token based requests that come in.
    | - Signups
    | - Resets
    |
    */

    /**
     * Where to redirect users after the password has been set.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

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

    public function check(Request $_request, $_type, $_token) {
        $valid_token = false;

        if($_type === 'reset') {
            $valid_token = CodeUserReset::where([
                ['token', '=', hash('sha256', $_token)],
                ['expiry_at', '>', Carbon::now()]
            ])->count();
        }
        else {
            $valid_token = User::where('signup_token', '=', $_token)->count();
        }
        
        if($valid_token) {
            return response()->json(['detail' => 'Valid Token'], 200);
        }

        return response()->json(['detail' => 'Invalid Token'], 400);
    }

    public static function valid_password($_password) {
        return !Validator::make([ 'password' => $_password ], [
            'password' => [
                'required',            // Has to exist
                'min:8',               // Atleast eight characters
                'regex:/[a-z]/',       // Has a lowercase letter
                'regex:/[A-Z]/',       // Has a uppercase letter
                'regex:/[0-9]/',       // Has a number
                'regex:/[^a-zA-Z\d]/', // Has a special character
            ]
        ])->fails();
    }

    public function setup(Request $_request, $_token) {
        // Pull out password.
        $password = $_request->input('password');

        // Check whether the password is even valid.
        if(self::valid_password($password)) {
            // Check whether the token is at all valid.
            $valid_token_user = User::where('signup_token', '=', $_token)->first();

            if($valid_token_user) {
                $valid_token_user->fill([
                    'password'      => Hash::make($password),
                    'signup_token'  => null
                ]);
    
                $valid_token_user->save();

                return response()->json(['detail' => 'Account Setup Successful'], 200);
            }
        }

        return response()->json(['detail' => 'Account Setup Failed'], 500);
    }

    public function reset(Request $_request, $_token) {
        // Pull out password.
        $password = $_request->input('password');

        // Check whether the password is even valid.
        if(self::valid_password($password)) {

            $valid_token = CodeUserReset::where([
                ['token', '=', hash('sha256', $_token)],
                ['expiry_at', '>', Carbon::now()]
            ])->first() ?? false;


            if($valid_token) {
                $user = User::find($valid_token->user_id) ?? null;

                if($user) {
                    $user->password = Hash::make($password);

                    if($user->save()) {
                        $valid_token->delete();

                        CodeUserReset::where('user_id', '=', $user->id)->delete();
                 
                        return response()->json(['detail' => 'Password Reset Successful'], 200);
                    }
                }
            }
        }

        return response()->json(['detail' => 'Password Reset Failed'], 500);
    }
}
