<?php

namespace App\Classes\Modules\Bookings\Processors;


use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
use App\Classes\Modules\Documents\Services\DeletesDocument;
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor; //deprecated
use Illuminate\Support\Str;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Transaction;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;

/**
 * @deprecated This class is deprecated and should not be used.
 * Use `RegenerateInvoiceBookingV2Processor` instead
 */
class RegenerateInvoiceBookingProcessor
{
    /** @var DeletesTransaction */
    private $deletesTransaction;

    /** @var UpdatesBookingStatus */
    private $updatesBookingStatus;

    /** @var DeletesDocument */
    private $deletesDocument;

    /** @var CreateInvoiceTransactionProcessor */ //deprecated
    private $createInvoiceTransactionProcessor;

    /**
     * RegenerateInvoiceBookingProcessor constructor.
     * @param DeletesTransaction $deletesTransaction
     * @param UpdatesBookingStatus $updatesBookingStatus
     * @param DeletesDocument $deletesDocument
     * @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor //deprecated
     */
    public function __construct(
        DeletesTransaction $deletesTransaction,
        UpdatesBookingStatus $updatesBookingStatus,
        DeletesDocument $deletesDocument,
        CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
    ) {
        $this->deletesTransaction = $deletesTransaction;
        $this->updatesBookingStatus = $updatesBookingStatus;
        $this->deletesDocument = $deletesDocument;
        $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
    }

    public function execute(Booking $booking, bool $isAllowNormalInvoice = false)
    {
        $this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED);

        $firstInvoice = $booking->transactions()
            ->whereIn('type', [TransactionType::INVOICE])
            ->withTrashed()
            ->orderBy('created_at', 'asc')
            ->first();

        Log::info('RegenerateInvoiceBookingProcessor booking: ' . json_encode($booking->marking));

        // get the first bill_no
        if($firstInvoice){
            $firstBillNo = $firstInvoice->bill_no;
            if (strpos($firstBillNo, '-deleted') !== false) {
                $firstBillNo = substr($firstBillNo, 0, strpos($firstBillNo, '-deleted'));
            }

            // update currentInvoice bill_no to '-deleted-'
            $currentInvoice = $booking->transactions()->where('type', TransactionType::INVOICE)->first();
            if($currentInvoice){
                $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp);
                $currentInvoice->save();
            }

            $transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->withTrashed()->get();
            if ($transactionWithSameBillNo) {
                foreach ($transactionWithSameBillNo as $transaction) {
                    $transaction->bill_no = $transaction->bill_no . "-deleted-" . Str::random(10);
                    $transaction->save();
                }
            }

            $transaction = $booking->transactions()->whereIn('type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->get();
            foreach ($transaction as $key => $row) {
                $this->deletesTransaction->execute($row);
            }

            $document = $booking->documents()->whereIn('document_type', [DocumentType::PURCHASE_ORDER, DocumentType::INVOICE, DocumentType::DELIVER_ORDER, DocumentType::SUPPLIER_DELIVER_ORDER])->get();
            foreach ($document as $key => $row) {
                $this->deletesDocument->execute($row);
            }

            $kvpCopies = $currentInvoice->attributesKVP->map(function ($kvp) {
                return $kvp->replicate();
            });

            $this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, $kvpCopies, true, $isAllowNormalInvoice);
        }
        else {
            $this->createInvoiceTransactionProcessor->execute($booking, "", null, false, $isAllowNormalInvoice);
        }
    }
}
