<?php

namespace App\Console\Commands;

use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Http;

class SuccessUpdatePaymentStatusButFailedCallback extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'fix-invoice-status';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Success Updated Payment Status But Inoie stat';

    protected $output = null;

    protected $outputArray = [];

    /** @var GetBillplzBill */
    private $getBillplzBill;

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

    /** @var UpdatesTransactionStatus */
    private $updatesTransactionStatus;

    /** @var UpdateDoFromVTPortalProcessor */
    private $updateDoFromVTPortalProcessor;

    /** @var UpdateDoFromYDPortalProcessor */
    private $updateDoFromYDPortalProcessor ;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor)
    {
        parent::__construct();
        $this->getBillplzBill = $getBillplzBill;
        $this->fetchesTransaction = $fetchesTransaction;
        $this->updatesTransactionStatus = $updatesTransactionStatus;
        $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
        $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        ini_set('memory_limit', '-1'); 

        $this->info(Carbon::now() . ' : Billplz Failled Callback cron started.');
        $this->outputArray = []; 
        $start   = new Carbon();

        $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;

        $transactions = Transaction::where('type', TransactionType::PAYMENT)
        ->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)
        ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
        ->get();

        foreach ($transactions as $payment) {
            $invoice = $payment->owner ?? null;
            if (!$invoice) {
                $this->info('Payment has no owner. Payment ID: ' . $payment->id);
                continue;
            }

            $packingList = $invoice->owner ?? null;
            if (!$packingList) {
                $this->info('Invoice has no owner. Invoice ID: ' . $invoice->id);
                continue;
            }

            $order = $packingList->owner;
            if (!$invoice) {
                $this->info('PackingList has no owner. PackingList ID: ' . $packingList->id);
                continue;
            }
            
            if ($invoice->status == ApprovalStatus::APPROVED) {

                $totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
    
                if(($invoice->amount - $totalPaidAmount) < 0.01) {
                    $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
        
                    $packingList->status = ApprovalStatus::APPROVED;
                    $packingList->save();
        
                    if(app()->environment('production')){
                        $this->updateDoFromVTPortalProcessor->execute($packingList);
                        $this->updateDoFromYDPortalProcessor->execute($packingList);
                    }
    
                    dump('Updated invoice ' . $invoice->id . '. Order: '. $order->reference);
                } else {
                    $this->info('Failed Update invoice ' . $invoice->id . ' because payment not enough. Invoice Amount: ' . $invoice->amount . ' . Paid Amount: ' . $totalPaidAmount . ' . Order: '. $order->reference);
                }
            } 
        }

        $end = new Carbon();
        $elapsedTime = $start->diff($end)->format('%H:%I:%S');

        $this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime );
    }
}
