<?php

namespace App\Modules\Mobile\Authentication;

use App\Models\Worker;
use Carbon\Carbon;
use Illuminate\Support\Facades\Validator;
use App\Traits\GenerateCodeTraits;
use App\Jobs\ProcessSendSMS;
use App\Traits\MobileNumberValidatorTraits as TWilioUSNumberValidator;

class TwoFactorAuthentication{

    use GenerateCodeTraits, TWilioUSNumberValidator;

    public function sendVerificationCode($payload){

        $emailAddress = $payload->email_address;
        $userData = $this->fetchWorkerPhoneNumberData($emailAddress);

        if(!$userData){
            return response()->json(['errors'=> 'These credentials do not match our records.'], 201); 
        }

        $validate = $this->validatePhoneNumber($userData->phone_num);
        if ($validate) {
            return $validate;
        }

        $verificationCode = strtoupper($this->generateRandomSixDigitCode());
        $messageContent = '[ConX] Verification Code: '.$verificationCode;
        $phoneNumber = $userData->phone_num;

        $updateWorkerDataTransaction = $this->updateWorker($emailAddress, ['mobile_code' => $verificationCode] );
        
        if($updateWorkerDataTransaction){
            ProcessSendSMS::dispatch($phoneNumber, $messageContent)->onQueue('sendemail')->onConnection('jobs_emails'); //used the email cron job 
            return response()->json(['success'=>'Successfully sent'], 201);
        }else{
            return response()->json(['errors'=>'Please try again later'], 201);
        }
        
    }

    public function fetchWorkerPhoneNumberData($emailAddress){
        return Worker::select('phone_num')->where('email_address', $emailAddress)->first();
    }

    public function updateWorker($emailAddress, $data){
        return Worker::where('email_address', $emailAddress)->update($data);
    }

    public function verify2faCode($payload){

        $inputtedCode = $payload->inputtedCode;
        $emailAddress = $payload->email_address;

        $rules = array(
            'email_address' =>'required|max:255',
            'inputtedCode' =>'required|max:8',
        );
    
        $error = Validator::make($payload->all(), $rules);
        if ($error->fails()){
            return response()->json(['errors' => $error->errors()->all()]);
        }

        $validateCode = $this->validateInputtedCode($emailAddress, $inputtedCode);

        if(!$validateCode){
            return response()->json(['errors'=>'You have inputted invalid code'], 201);
        }

        $updateWorkerData = $this->updateWorker($emailAddress, [
            'mobile_code' => null,
            'mobile_code_expiration' => Carbon::now()->addHour(), //1 hour session
        ]);

        if(!$updateWorkerData){
            return response()->json(['errors'=>'Something went wrong. Please try again later.'], 201);
        }

        return response()->json(['success'=>'Successfully verrified'], 201);

    }

    public function validateInputtedCode($emailAddress, $inputtedCode){
        return Worker::where('email_address', $emailAddress)
            ->where('mobile_code', $inputtedCode)
            ->first();
    }
}
