<?php

namespace App\Modules\Jobseeker;

use App\Models\Role;
use App\Models\Worker;
use App\Models\AccessRole;
use App\Models\CompanyUser;
use App\Models\WorkerFile;
use App\Models\JobseekerSubscription;
use App\Models\JobSeekerSubscriptionFreeTrial;
use App\Modules\RemoteStorage\GoogleBucketGateway;
use App\Jobs\Jobseeker\ProcessSendEmailForNewJobseeker;
use App\Traits\ValidatorTraits;
use App\Traits\GoogleBucket;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class Register
{
    use ValidatorTraits, GoogleBucket;
    public $googleBucket;

    public function __construct(GoogleBucketGateway $googleBucket)
    {
        $this->googleBucket = $googleBucket;
    }

    public function register($payload)
    {
        $rules = array(
            'email' => 'required|unique:workers,email_address|max:191',
            'first_name' => 'required|max:50',
            'last_name' => 'required|max:50',
            // 'date_end' => 'required',
            'date_start' => 'required',
            'password' => 'required|min:8',
            'file' => 'required|mimes:pdf|max:10240',
            'fileName' => 'required|max:200',
        );

        $validate = $this->validateRequest($payload, $rules);
        
        if ($validate) {
            return $validate;
        }

        DB::beginTransaction();

        /* Process Job Seeeker datas */
        $token = Str::random(60);

        /* Saving Files */
        $location = $this->file_location();
        $file = $payload->file->store($location);
        $emailAddress = strtolower($payload->email);

        $data = array(
            'email_address' => $emailAddress,
            'password' => Hash::make($payload->password),
            'first_name' => ucfirst(strtolower($payload->first_name)),
            'last_name' => ucfirst(strtolower($payload->last_name)),
            'availability_start_date' => Carbon::create($payload->date_start),
            'email_verification_code' => $token,
        );

        $jobseeker = $this->create_jobseeker($data);
    
        if($jobseeker){
            $extension = $payload->file('file')->extension();
            $filePayloadName = 'file'; //input name of the file on the payload
            $fileName = $payload->fileName; //input name of the file on the payload
            $resumeFilePathName = $this->createUniqueJobseekerFileName($jobseeker->id, $extension);

            $this->uploadNewFile($payload, $resumeFilePathName, $filePayloadName, $this->googleBucket);
            $newCertificate = array(
                'worker_id' => $jobseeker->id,
                'name' => str_replace ( '.'.$extension, '', $fileName), //remove the extension '.pdf'
                'location' => $resumeFilePathName
            );
            WorkerFile::create($newCertificate);
        }
        

        /* Process Job Seeeker subscription plan */
        $freeDays = $this->getFreeDays();
        if ($freeDays > 0) {
            $subscription_data = array(
                'worker_id' => $jobseeker->id,
                'rate_id' => 0,
                'duration' => Carbon::now()->addDay($freeDays),
                'status' => 'trial',
            );
            $jobseeker_subscription = $this->create_jobseeker_subscription($subscription_data);

        } else {
            $jobseeker_subscription = true;
        }

        /* Process Job Seeeker company user */
        $role = Role::select('id')->where('name', 'Job Seeker')->first()->id;
        $company_user = array(
            'worker_id' => $jobseeker->id,
            'role_id' => $role,
        );
        $jobseeker_companyUser = $this->create_company_user($company_user);

        /* Process Job Seeeker access and role */
        // $access = Access::select('id')->where('page', 'Job Seekers')->first()->id;
        // $access_role = array (
        //     'role_id' => $role,
        //     'access_id' => $access,
        // );
        // $jobseeker_accessRole = $this->create_jobseeker_accessRole($access_role);

        $user_data = [
            'email_address' => $jobseeker->email_address,
            'first_name' => $jobseeker->first_name,
            'last_name' => $jobseeker->last_name,
            'email_token' => $token,
            'role' => 'jobseeker',
        ];
        $email_address = $jobseeker->email_address;

        if (!$jobseeker || !$jobseeker_subscription || !$jobseeker_companyUser) {
            DB::rollBack();
            return response()->json(['error' => 'Server error.']);
        } else {
            DB::commit();
            $this->sendEmailVerification($email_address, $user_data);
            $response = [
                'success' => 'Job Seeker successfully created!',
                'jobseeker' => $jobseeker,
            ];
            return response()->json($response);
        }
    }

    public function sendEmailVerification($email_address, $user_data)
    {
        return ProcessSendEmailForNewJobseeker::dispatch($email_address, $user_data)->onConnection('jobs_emails')->onQueue('sendemail');
    }

    public function file_location()
    {
        switch (now()->format('M')) {
            case 'Jan':
                return '01';
                break;
            case 'Feb':
                return '02';
                break;
            case 'Mar':
                return '03';
                break;
            case 'Apr':
                return '04';
                break;
            case 'May':
                return '05';
                break;
            case 'Jun':
                return '06';
                break;
            case 'Jul':
                return '07';
                break;
            case 'Aug':
                return '08';
                break;
            case 'Sep':
                return '09';
                break;
            case 'Oct':
                return '10';
                break;
            case 'Nov':
                return '11';
                break;
            default:
                return "12";
        }
    }

    public function getFreeDays()
    {
        $days = JobSeekerSubscriptionFreeTrial::where('id', 1)->first();
        if ($days) {
            return $days->days;
        } else {
            return 0;
        }
    }

    public function create_jobseeker($data)
    {
        return Worker::create($data);
    }

    public function create_jobseeker_subscription($data)
    {
        return JobseekerSubscription::create($data);
    }

    public function create_jobseeker_accessRole($data)
    {
        return AccessRole::create($data);
    }

    public function create_company_user($data)
    {
        return CompanyUser::create($data);
    }

    public function emailVerify($payload){
        $token = $payload->token;
        $jobseeker = Worker::where('email_verification_code', $token)->update(['email_verified_at' => Carbon::now(), 'email_verification_code' => null]);
        return ($jobseeker) ? 'Verified' : 'Not Verified';
    }
}
