<?php

namespace App\Classes\Jobs\Commands\V2;

use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\Modules\Transactions\ControllersLogic\UpdateGroupLogic;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\BillGroup;
use App\Models\Group;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Route as FacadesRoute;

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


    public function handle()
    {
        Log::info(Carbon::now() . ': Start job - Update bill group and group to include transfer fee calculation.');
        $start   = new Carbon();

        // update group to include transfer fee
        $groups = Group::where('created_at', '>=', '2024-06-01')->get();

        foreach ($groups as $group) {
            $group_transfer_fee = 0;

            $morph_transaction = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first();

            if ($morph_transaction) {
                $group_transfer_fee = $morph_transaction->original_amount;
            }


            $originalTransferFees = (float)Transaction::where('type', TransactionType::TRANSFER_FEE)->whereIn('owner_id', $group->transactions->pluck('id'))->sum('service_charge');
            $correctOriginalAmount = $group->transactions()->sum('original_amount');
            $correctOriginalAmount = $correctOriginalAmount + $originalTransferFees + $group_transfer_fee;
            $correctAmount = $group->transactions()->sum('amount');
            $transferFees = $originalTransferFees / $group->currency_rate;
            $correctAmount = $correctAmount + $transferFees + ($group_transfer_fee / $group->currency_rate) + $group->service_charge;

            if ($group->original_amount != $correctOriginalAmount || $group->amount != $correctAmount) {
                $group->original_amount = $correctOriginalAmount;
                $group->amount = $correctAmount;
                $group->save();

                Log::info("updated group id: {$group->id}, added transfer fee CNY {$correctOriginalAmount}");
            }
        }

        // update group calculation to include individual group transfer fee
        // $groups = Group::whereHas('morphTransactions', function ($q) {
        //     $q->where('type', TransactionType::TRANSFER_FEE);
        // })->get();

        // foreach ($groups as $group) {
        //     $route = FacadesRoute::getRoutes()->getByName('api.transaction.group.update');
        //     $request = Request::create(route('api.transaction.group.update', $group->id));
        //     $uri = $route->uri;
        //     $request->setRouteResolver(function () use ($request, $uri) {
        //         // Associate Route to request so we can access route parameters.
        //         return (new Route('PUT', $uri, []))->bind($request);
        //     });

        //     $request['rate'] = $group->currency_rate;
        //     $request['supplier_id'] = $group->issuer;
        //     $this->updateGroupLogic->execute($request);

        //     $group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first();
        //     Log::info("updated group id: {$group->id}, added transfer fee to individual white form CNY {$group_transfer_fee->original_amount}");
        // }

        // update bill group calculation to include individual group transfer fee
        $billGroups = BillGroup::all();

        foreach ($billGroups as $billGroup) {
            // ignore those has bill group refund
            if ($billGroup->billRefunds()->count() > 0) {
                continue;
            }

            $totalOriginal = round($billGroup->groups()->sum('original_amount'), 2);
            $total = round($billGroup->groups()->sum('amount') + $billGroup->service_charge, 2);

            // update bill group payment transaction amount if there is only 1 payment transaction
            $payment_transactions = $billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();

            if ($payment_transactions->count() === 1) {
                $payment_transaction = $payment_transactions->first();

                if ($payment_transaction->amount - ($billGroup->amount + $billGroup->service_charge) < 0.01) {
                    $payment_transaction->original_amount = $total;
                    $payment_transaction->amount = $total;
                    $payment_transaction->save();
                    Log::info("updated bill group payment transaction id: {$payment_transaction->id}, update original amount to CNY {$totalOriginal}");
                }
            }

            // update bill group amount and original amount
            $billGroup->original_amount = $totalOriginal;
            $billGroup->amount = $total;
            $billGroup->save();

            Log::info("updated bill group id: {$billGroup->id}, added transfer fee, final original amount is CNY {$totalOriginal}");
        }

        $end = new Carbon();
        $elapsedTime = $start->diff($end)->format('%H:%I:%S');
        Log::info(Carbon::now() . ': End job - Update bill group and group to include transfer fee calculation. ElapsedTime: ' . $elapsedTime . '.');
    }
}
