<?php

namespace App\Classes\Jobs;

use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMInvoiceProcessor;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoicePayment;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMInvoice;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMProject;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMInvoice;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMInvoiceStatus;
use App\Models\Transaction;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use App\Classes\General\Helper;

class UpdatePerfexCRMInvoice implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /** @var UpdatePerfexCRMInvoiceObject */
    private $updatePerfexCRMInvoiceObject;

    /**
     * CreatePerfexCRMSingleTask constructor.
     * @param UpdatePerfexCRMInvoiceObject $updatePerfexCRMInvoiceObject
     */
    public function __construct(UpdatePerfexCRMInvoiceObject $updatePerfexCRMInvoiceObject)
    {
        $this->updatePerfexCRMInvoiceObject = $updatePerfexCRMInvoiceObject;
    }

    public function handle()
    {
        //get the client id
        $customer = (App()->make(FetchesPerfexCRMCustomer::class))->execute($this->updatePerfexCRMInvoiceObject->getEmail());
        $transaction = $this->updatePerfexCRMInvoiceObject->getTransaction();

        //get the invoice id
        $invoiceId = 0;
        $invoiceStatus = 0;

        $number = $transaction->bill_no;

        $prefix = "INV-";
        //This will remove the prefix if prefix already exist in the string
        if (substr($number, 0, strlen($prefix)) == $prefix) {
            $number = substr($number, strlen($prefix));
        }

        $number = 'EXC-'.$number;
        $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $number);
        Log::channel('perfex_crm')->info(json_encode('UpdatePerfexCRMInvoice debug $number: '.$number));

        if(is_null($invoice)){
            $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction);
            if ($result) {
                $invoiceId = $result->payload['id'];
            } else {
                $log['message'] = 'UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed';
                Log::channel('perfex_crm')->info($log);
            }
        }
        else{
            $invoiceId = $invoice->id;
            $invoiceStatus = $invoice->status;

            //This only run when invoice already exist and the invoice does not have a PAID status
            if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){
                Log::channel('perfex_crm')->info('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId());

                //update invoice
                (App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $this->updatePerfexCRMInvoiceObject->getProjectId());
            }
        }

        //create invoice payment
        if($invoiceId != 0 && $invoiceStatus != PerfexCRMInvoiceStatus::PAID){

            $date = Carbon::parse($transaction->created_at)->format('Y-m-d');

            $invoicePaymentPerfexCRMObject = new InvoicePaymentPerfexCRMObject(
                $invoiceId,
                "$transaction->amount",
                $date,
                1,
                "",
                ""
            );
            (App()->make(CreatesPerfexCRMInvoicePayment::class))->execute($invoicePaymentPerfexCRMObject);
        }
    }
}
