<?php

namespace App\Listeners\Admin;

use Illuminate\Contracts\Queue\ShouldQueue;
use App\Events\Admin\ChangeCompanyServiceChargeEvent;
use App\Models\Company;
use App\Models\Worker;
use App\Models\CompanyUser;
use App\Models\Search;
use App\Traits\CalculateBillableRateTrait;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class UpdateSearchByCompanyServiceChargeListener implements ShouldQueue
{
	use CalculateBillableRateTrait;
    public $connection = 'jobs_loan_borrow_lists'; //queue channel/connection
    public $queue = 'updatesearch';  //nanme of the dispatched queue
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  object  $event
     * @return void
     */
    public function handle(ChangeCompanyServiceChargeEvent $event)
    {
        Log::channel('background')->info('ChangeCompanyServiceChargeEvent triggered');

        $companyID = $event->company_id;

        $listOfWorkers = $this->fetchWorkers($companyID);

        foreach($listOfWorkers as $worker){

            $workerID = $worker->worker_id;
            $billableData = $this->fetchBillableData($workerID);

            if($billableData){
                if((int) $billableData->original_rate > 0 && $billableData->worker_company_id){ //should have rate and company_worker_id
                    $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,
                    ];
    
                    $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
                    );
        
                    $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); disabled create search, in instance where worker is not yet fully signed up
                    }
                }
                
            }
        }
    }

    public function fetchCompanyData($companyID){
        return  Company::where('id', $companyID)->first();
    }

    public function fetchWorkers($companyID){
        $workerRoleID = 5;

        return CompanyUser::where('company_id', $companyID)
        ->where('role_id', $workerRoleID)
        ->get();
    }

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