<?php

namespace App\Listeners\Admin;
use App\Events\Admin\NotifyTransactedCompanyOfBlockedCompanyEvent;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

use App\Models\Company;
use App\Models\LoanApproved;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;


class NotifyTransactedCompanyOfBlockedCompanyListener implements ShouldQueue
{
    public $connection = 'jobs_emails'; //queue channel/connection
    public $queue = 'sendemail';  //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(NotifyTransactedCompanyOfBlockedCompanyEvent $event)
    {

        $companyID = $event->companyID;

        $dateToSearch = Carbon::now()->format('Y-m-d');

        $activeTransaction = LoanApproved::select(
                'loan_approved_histories.loaner_company_id',
                'loan_approved_histories.borrower_company_id',
                'loan_approved_histories.date_from',
                'loan_approved_histories.date_to',
                'loan_approved_histories.worker_id',
                'workers.worker_id as company_worker_id',
                DB::raw('CONCAT(workers.first_name, " ", workers.last_name) as worker_name'),
            )
            ->join('workers', 'workers.id', '=', 'loan_approved_histories.worker_id')
            ->where('loan_approved_histories.date_to', '>=', $dateToSearch)
            ->whereRaw("(loan_approved_histories.loaner_company_id = " . $companyID . " or loan_approved_histories.borrower_company_id = ". $companyID . ")")  //used whereRaw because orWhere has a bugs
            ->distinct()
            ->get();

        $companyIDAsLoaner = [];
        $companyIDAsBorrower = [];
        $workerDataToBeFiltered = []; //hold the worker data and company id to be filtered on next process


        // First process, get the Company ID of the transacted by the current company, and the workers data
        foreach($activeTransaction as $company){
            if($companyID == $company->loaner_company_id){

                if(!in_array($company->borrower_company_id, $companyIDAsLoaner)){
                    array_push($companyIDAsLoaner, $company->borrower_company_id); //saved the company who loaned on current company
                }

                array_push($workerDataToBeFiltered, array(
                    'company_id' => $company->borrower_company_id,
                    'worker_id' => $company->worker_id,
                    'company_worker_id' => $company->company_worker_id,
                    'worker_name' => $company->worker_name,
                ));

            }elseif($companyID == $company->borrower_company_id){

                if(!in_array($company->loaner_company_id, $companyIDAsBorrower)){
                    array_push($companyIDAsBorrower, $company->loaner_company_id); //saved the company who borrowed on current company/
                }

                array_push($workerDataToBeFiltered, array(
                    'company_id' => $company->loaner_company_id,
                    'worker_id' => $company->worker_id,
                    'company_worker_id' => $company->company_worker_id,
                    'worker_name' => $company->worker_name,
                ));
            }

            
        }

        $workerInTheEmails = [];

        // Handle the company where the current company act as loaner, select all the worker transacted to be emailed 
        foreach($companyIDAsLoaner as $loaner){
            // Filter  all the companies worker
            $workerDataFound = array_filter($workerDataToBeFiltered, function($data) use ($loaner){
                return $data['company_id'] == $loaner;

            }, ARRAY_FILTER_USE_BOTH); // ARRAY_FILTER_USE_BOTH OR ARRAY_FILTER_USE_KEY  

            $listOfCompanyWorker =  [];
            foreach($workerDataFound as $worker){
                array_push($listOfCompanyWorker, $worker['worker_name']);
            }

            if(count($listOfCompanyWorker) > 1){
                $lastEmployee = array_pop($listOfCompanyWorker);
                $listOfCompanyWorker = join(", ", $listOfCompanyWorker) . " and ". $lastEmployee;
            }else{
                $listOfCompanyWorker = implode(" ", $listOfCompanyWorker);
            }
            array_push($workerInTheEmails, $listOfCompanyWorker ); //list of worker loaned by the current company 

            // Email here
            $emailsAddresses = $this->getCompanyOwnerEmail($loaner); //owner and company emails of the borrowing company
            $emailData = [
                'on' => 'borrowed',
                'workerNames' => (string)  $listOfCompanyWorker,
            ];

            $this->processEmail($emailsAddresses, $emailData);
            $workerDataFound = [];
            $workerDataFound = [];
        }   

        
        // Handle the company where the current company act as borrower
        foreach($companyIDAsBorrower as $borrower){

            // Filter  all the companies worker
            $workerDataFound = array_filter($workerDataToBeFiltered, function($data) use ($borrower){
                return $data['company_id'] == $borrower;

            }, ARRAY_FILTER_USE_BOTH); // ARRAY_FILTER_USE_BOTH OR ARRAY_FILTER_USE_KEY  

            $listOfCompanyWorker =  [];
            foreach($workerDataFound as $worker){
                array_push($listOfCompanyWorker, $worker['worker_name']); 
            }

            if(count($listOfCompanyWorker) > 1){
                $lastEmployee = array_pop($listOfCompanyWorker);
                $listOfCompanyWorker = join(", ", $listOfCompanyWorker) . " and ". $lastEmployee;
            }else{
                $listOfCompanyWorker = implode(" ", $listOfCompanyWorker);
            }
            array_push($workerInTheEmails, $listOfCompanyWorker); //list of worker borrowed by the current company 

            // Email here
            $emailsAddresses = $this->getCompanyOwnerEmail($borrower); //owner and company emails of the loaning company
            $emailData = [
                'on' => 'loaned',
                'workerNames' => (string) $listOfCompanyWorker,
            ];
            $this->processEmail($emailsAddresses, $emailData);
            $workerDataFound = [];
        }   
    }

    public function getCompanyOwnerEmail($companyID){
        $emailsAddresses = Company::select(
            'companies.email_address as company_email', 
            'workers.email_address as owner_email'
        )
        ->join('company_users', 'company_users.company_id', 'companies.id')
        ->join('workers', 'workers.id', 'company_users.worker_id')
        ->where('companies.id', $companyID)
        ->where('company_users.role_id' , 1)
        ->first();

        if($emailsAddresses->company_email == $emailsAddresses->owner_email){
            return $emailsAddresses->company_email;
        }
        
        return array(
            $emailsAddresses->company_email,
            $emailsAddresses->owner_email,
        );
    }

    public function processEmail($emailAddresses, $emailData){
        Mail::to($emailAddresses)->send(new \App\Mail\Admin\NotifyTransactedCompanyOfBlockedCompany($emailData));
    }
}
