<?php

namespace App\Classes\Modules\Exports\Services;


use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\KVPKey;
use App\Classes\ValueObjects\Constants\RemarkRefundReason;
use App\Models\KeyValuePair;
use App\Models\Transaction;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class ExportsARCreditNoteReport implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
    use Exportable;

    protected $startDate;
    protected $endDate;

    public function __construct($startDate = null, $endDate = null) {
        $this->startDate = $startDate ? Carbon::parse($startDate)->startOfDay() : Carbon::now()->subMonths(1);
        $this->endDate = $endDate ? Carbon::parse($endDate)->endOfDay() : Carbon::now();
    }

    public function headings(): array
    {
        return [
            'DocNo',
            'DocDate',
            'DebtorCode',
            'Ref',
            'Description',
            'Reason',
            'DeptNo',
            'Amount',
            'AccNo',
            'submiteinvoice',
            'ConsolidatedEinvoice',
            'KnockOffDocType',
            'KnockOffDocNo',
            'KnockOffAmt',
        ];
    }

    /**
     * @return \Illuminate\Support\Collection|mixed
     */
    public function query()
    {
        $type = TransactionType::CREDIT_NOTE;
        $query = Transaction::query();

        $query->where('type', $type);
        // $query->where('owner_type', Wallet::class);
        $query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
        $query->whereBetween('created_at', [$this->startDate, $this->endDate]);

        return $query;
    }

    /**
     * @param Transaction $transaction
     * @return array
     */
    public function map($transaction): array
    {
        $booking  = null;
        $autoCountSalesInvoiceId = null;
        $formattedDocumentDate = null;
        $refundRemarkGroup  = null;
        $refundRemarkGroupAccNo  = null;
        $company = $transaction->owner->owner;
        $kvps = KeyValuePair::where('value', $transaction->id)
            ->where('key', KVPKey::TRANSACTION_MODEL_CLASS)
            ->orderByDesc('created_at')
            ->get();

        foreach ($kvps as $kvp) {
            if ($kvp && $kvp->owner && $kvp->owner->owner && $kvp->owner->owner->type === 1) {
                $refundTransaction = $kvp->owner;
                $refundRemark = $refundTransaction->remarks && $refundTransaction->remarks->first() ? $refundTransaction->remarks->first()->content : null;
                if($refundRemark){
                    $refundRemarkGroup = RemarkRefundReason::REFUND_REASONS[$refundRemark] ?? null;
                    if($refundRemarkGroup){
                        $refundRemarkGroupAccNo = RemarkRefundReason::REFUND_REASONS_GROUP[$refundRemarkGroup] ?? null;
                    }
                    $refundRemarkGroup = strtoupper($refundRemarkGroup);
                }
                $booking = $refundTransaction->owner->booking;
                if($booking){
                    $metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first();
                    if($metadata){
                        $autoCountSalesInvoiceId = $metadata->value;
                    }
                    break;
                }
            }
        }

        $documentDate = $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){
            $documentDate = Carbon::parse($metadata->value);
        }
        if($company->e_invoice === 1){
            $documentDate = $documentDate->copy()->endOfMonth();
        }
        $formattedDocumentDate = Carbon::parse($documentDate)->format('m/d/Y');

        $docNo = '<<New>>';
        if($transaction){
            $transactionKVP = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_CREDIT_NOTE)->first();
            if($transactionKVP){
                $docNo = $transactionKVP->value;
            }
            else if($booking){
                $bookingKVP = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_CREDIT_NOTE)->first();
                $docNo = $bookingKVP ? $bookingKVP->value :'<<New>>';
            }
        }

        return [
            $docNo,                                 //DocNo
            $formattedDocumentDate,                 //DocDate
            $company->debtor,                       //DebtorCode
            $transaction->bill_no ?? '',            //Ref
            $refundRemarkGroup ?? '',               //Description
            $refundRemarkGroup ?? '',               //Reason
            'C',                                    //DeptNo
            number_format($transaction->amount, 2), //Amount
            $refundRemarkGroupAccNo ?? '',          //AccNo
            'T',                                    //submiteinvoice
            $company->e_invoice ? 'F' : 'T',        //ConsolidatedEinvoice
            'RI',                                   //KnockOffDocType
            $autoCountSalesInvoiceId ?? '',         //KnockOffDocNo
            number_format($transaction->amount, 2), //KnockOffAmt
        ];
    }
}
