<?php

namespace App\Listeners\Company;

use App\Events\Company\WorkerRateUpdatedEvent;
use App\Models\Worker;
use App\Models\Search;
use App\Models\CompanyUser;
use App\Traits\CalculateBillableRateTrait;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
class UpdateSearchByWorkerRateUpdateListener
{
    use CalculateBillableRateTrait;
    

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

    /**
     * Handle the event.
     *
     * @param  object  $event
     * @return void
     */
    public function handle(WorkerRateUpdatedEvent $event)
    {
        //
        $workerID = $event->worker_id;

        $billableData = $this->fetchBillableData($workerID);
        $isWorker = $this->isWorker($workerID);

        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', $workerID)->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
                'status' => 'Available', //serve as search rate, rate to be paid by loaner
            );

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

            if($hasSearchData){
                Search::where('worker_id', $workerID)->update($searchData); //update search
            }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);
            }

        }else{
            Log::channel('background')->info('Not a worker or no billable data on WorkerRateUpdatedEvent');
        }
    }

    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;
    }
}
