<?php


namespace App\Classes\Modules\Transactions\ControllersLogic;

use Illuminate\Http\Request;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\General\AWSS3Helper;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\KVPKey;
use App\Models\KeyValuePair;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class GenerateCreditNotePdfV2Logic
{

    /** @var FetchesTransaction */
    private $fetchesTransaction;

    /** @var FetchesCompany */
    private $fetchesCompany;

    /**
     * GenerateCreditNotePdfV2Logic constructor.
     * @param FetchesTransaction $fetchesTransaction
     * @param FetchesCompany $fetchesCompany
     */
    public function __construct(FetchesTransaction $fetchesTransaction, FetchesCompany $fetchesCompany)
    {
        $this->fetchesTransaction = $fetchesTransaction;
        $this->fetchesCompany = $fetchesCompany;
    }

    /**
     * @param Request $request
     * @return string|\Symfony\Component\HttpFoundation\Response
     * @throws \App\Classes\Exceptions\MalformedRequestException
     */
    public function execute(Request $request)
    {
        $pdfTemplateName = 'pages.pdfs.credit_note_v2'; //default since e-invoice implementation
        $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
        $autoCountInvoiceId = '';
        $autoCountEInvoiceValidationLink = 'CIEF';
        $kvpCreditNoteNormalOptInOverride = $transaction->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE)->latest()->first(); //transaction type 6

        if($transaction->type === TransactionType::REFUND){
            //Retrieve TransactionType::CREDIT_NOTE
            $booking = $transaction->owner->booking;
            $kvp = $transaction->attributesKVP()->where('key', KVPKey::TRANSACTION_MODEL_CLASS)->latest()->first();
            if($kvp){
                if($kvp->key === KVPKey::TRANSACTION_MODEL_CLASS){
                    $transaction = $this->fetchesTransaction->execute(['id' => $kvp->value ]);
                }
            }
        }
        else{
            //For Old Cases
            $booking = $transaction->booking;
            $pdfTemplateName = 'pages.pdfs.credit_note'; //default

            //For New Cases with e-invoice: Retrieve the refund transaction for this credit note
            $kvp = KeyValuePair::where('key', KVPKey::TRANSACTION_MODEL_CLASS)->where('value', $transaction->id)->first();
            if($kvp){
                $kvpOwner = $kvp->owner;
                if($kvpOwner && $kvpOwner instanceof Transaction && $kvpOwner->type === TransactionType::REFUND){
                    $kvpCreditNoteNormalOptInOverride = $kvpOwner->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE)->latest()->first(); //transaction type 6
                    $booking = $kvpOwner->owner->booking;
                }
            }
        }

        $date = $transaction->created_at; //NEW 2025: default in case there is no approval date
        $metadata = $transaction->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_APPROVAL_DATE)->latest('created_at')->first();
        if($metadata){
            $date = Carbon::parse($metadata->value);
        }

        $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
        // $brn = $supplier->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first(); //wrong
        $brn = $supplier->documents()->where('document_type', DocumentType::SSM_REGISTRATION)->latest()->first();

        $eInvoiceStarted = false;
        $eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
        $bookingCreatedDate = Carbon::parse($booking->created_at);

        if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) {
            $eInvoiceStarted = true;
        }

        if($eInvoiceStarted) {
            $eInvoiceStarted = false; //reset to re-evaluate second time

            //OLD BUSINESS LOGIC
            // $kvp = KeyValuePair::where('key', KVPKey::TRANSACTION_MODEL_CLASS)->where('value', $transaction->id)->first();
            // $refundTransaction = $kvp ? $kvp->owner : null;
            // if($refundTransaction && $refundTransaction->type === TransactionType::REFUND){
            //     $metadata = $refundTransaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_CREDIT_NOTE)->first();
            //     if($metadata){
            //         $autoCountInvoiceId = $metadata->value;
            //     }
            //     $metadata = $refundTransaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_EINVOICE_VALIDATION_LINK_CREDIT_NOTE)->first();
            //     if($metadata){
            //         $autoCountEInvoiceValidationLink = $metadata->value;
            //     }

            //     if($autoCountInvoiceId && $autoCountEInvoiceValidationLink){
            //         $eInvoiceStarted = true;
            //     }
            // }
            if($transaction && $transaction->type === TransactionType::CREDIT_NOTE){
                $metadata = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_CREDIT_NOTE)->first();
                if($metadata){
                    $autoCountInvoiceId = $metadata->value;
                    $metadata = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_EINVOICE_VALIDATION_LINK_CREDIT_NOTE)->first();
                    if($metadata){
                        $autoCountEInvoiceValidationLink = $metadata->value;
                    }

                    if($autoCountInvoiceId && $autoCountEInvoiceValidationLink){
                        $eInvoiceStarted = true;
                    }
                }
                else{

                }
            }
        }
        Log::info('AUTOCOUNT_DOCNO_CREDIT_NOTE: ' . $autoCountInvoiceId);
        Log::info('AUTOCOUNT_EINVOICE_VALIDATION_LINK_CREDIT_NOTE: ' . $autoCountEInvoiceValidationLink);

        if($eInvoiceStarted)
        {
            if($supplier->e_invoice === 1){
                Log::info('Based on booking created date, E-Credit Note started and company wants e-invoice ' . json_encode($booking));
                $date = $date->copy()->endOfMonth();
                $pdfTemplateName = 'pages.pdfs.e_credit_note';
            }
            else{
                Log::info('Based on booking created date, E-Credit Note started and company do not wants e-invoice');
                $pdfTemplateName = 'pages.pdfs.credit_note_v2';
            }

            if($kvpCreditNoteNormalOptInOverride && $kvpCreditNoteNormalOptInOverride->value == 1){
                $pdfTemplateName = 'pages.pdfs.credit_note_v2';
            }
        }
        else{
            Log::info('Based on booking created date, E-Credit Note not yet started. / Not Yet Ready.');
        }

        $pdf = LaravelMpdf::loadView($pdfTemplateName, [
            'transaction' => $transaction,
            'booking' => $booking,
            'supplier' => $supplier,
            'date' => $date,
            'brn' => $brn,
            'autocountId' => $autoCountInvoiceId,
            'autocountEInvoiceValidationLink' => $autoCountEInvoiceValidationLink,
        ]);

        $exportFileName = 'CreditNote.pdf';
        $filesystemDriver = Storage::getDefaultDriver();
        if($filesystemDriver === 's3'){
            $pdfContent = $pdf->output();
            return response([ 'src' =>  AWSS3Helper::S3PDF($exportFileName, $pdfContent) ]);
        }
        else{
            return $pdf->stream($exportFileName);
        }
    }
}
