<?php

namespace App\Listeners\Company;

use App\Events\Company\CreateSearchWorkerEvent;
use App\Models\Search;
use App\Models\Worker;
use App\Models\CompanyUser;
use Carbon\Carbon;
use App\Traits\CalculateBillableRateTrait;
use Illuminate\Support\Facades\Log;

class CreateSearchWorkerListener
{
    use CalculateBillableRateTrait;

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  object  $event
     * @return void
     */
    public function handle(CreateSearchWorkerEvent $event)
    {

        $companyUser = (object) $event->companyUser;

        $billableData = $this->fetchBillableData($companyUser->worker_id);
        $isWorker = $this->isWorker($companyUser->worker_id);

        // Log::channel('background')->info($billableData);

        //wprker should have billable data, worker expriemce, burden rate
        if($isWorker && $billableData){ 

             $prepareDataForCalculation = (object)[
                'hourly_rate' => $billableData->original_rate,
                'burden_rate' => $billableData->burden_rate,
                'burden_rate_type' => $billableData->burden_rate_type,
                'overheadAmount' => $billableData->overhead_amount,
                'overheadType' => $billableData->overhead_type,
                'service_charge' => $billableData->service_charge,
            ];

            //compute new rates 
            $computationTransaction = $this->newComputationOfBillableRate($prepareDataForCalculation);

            $updateWorkerRates = array(
                'flat_rate' => $computationTransaction->originalRate,
                'rate' => $computationTransaction->billableRate, 
                'overhead_charge' => $computationTransaction->overHeadAmount,
                'overhead_type' => $computationTransaction->overHeadType,
            );

            Worker::where('id', $companyUser->worker_id)->update($updateWorkerRates);

            $searchData = array(
                'original_rate' => $computationTransaction->originalRate,
                'hourly_rate' => $computationTransaction->searchRate, //serve as search rate, rate to be paid by loaner
                'zip_code' => $billableData->zipcode, //serve as search rate, rate to be paid by loaner
            );

            $workerID = $companyUser->worker_id;
            $hasSearchData = $this->fetchSearchData($workerID);

            if($hasSearchData){
                Search::where('worker_id', $workerID)->update($searchData); //update search
                Log::channel('background')->info('Update Search data on CreateSearchWorkerEvent');
            }else{

                $dateHired = $billableData->date_hired ?: Carbon::now();
                $searchData = array(
                    'worker_company_id' => $billableData->worker_company_id,
                    'worker_id' => $workerID,
                    'zip_code' => $billableData->zipcode,
                    'hourly_rate' => $computationTransaction->searchRate, //newly computed search rate
                    'original_rate' => $computationTransaction->originalRate,
                    'date_from' => $dateHired,
                    'date_to' => Carbon::create($dateHired)->addYears(10),
                    'status' => 'Available',
                );
                Search::create($searchData);
                Log::channel('background')->info('Create Search data on CreateSearchWorkerEvent');
            }
        }
    }

    public function fetchBillableData($workerID){
        return Worker::select(
            'workers.id as worker_id',
            'workers.flat_rate as original_rate',
            'workers.overhead_charge as overhead_amount',
            'workers.worker_id as worker_company_id',
            'workers.overhead_type',
            'workers.zipcode',
            'workers.date_hired',
            'companies.service_charge',
            'company_burden_rate.burden_rate',
            'company_burden_rate.burden_rate_type',

        )
            ->join('worker_experiences', 'worker_experiences.worker_id', 'workers.id')
            ->join('company_burden_rate', 'company_burden_rate.id', 'worker_experiences.burden_rate_id')
            ->join('company_users', 'company_users.worker_id', 'workers.id')
            ->join('companies', 'companies.id', 'company_users.company_id')
            ->where('company_users.worker_id', $workerID)
            ->first();
    }

    public function fetchSearchData($workerID){
        return Search::where('worker_id', $workerID)->first();
    }

    public function isWorker($workerID){
        $roles = CompanyUser::where('worker_id', $workerID)->get();
        foreach($roles as $role){
            if($role->role_id == 5){
                return true;
            }
        }
        return false;
    }
}
