<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreSupplierPaymentRequest;
use App\Models\Purchase;
use App\Models\PurchaseSupplier;
use App\Support\PurchaseCurrency;
use App\Support\SupplierAccountLedger;
use App\Support\SupplierPaymentMethod;
use App\Support\SupplierPaymentType;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class SupplierPaymentController extends Controller
{
    public function create(Request $request, PurchaseSupplier $purchaseSupplier): Response
    {
        $defaultType = $request->string('type')->toString();
        if (! in_array($defaultType, SupplierPaymentType::values(), true)) {
            $defaultType = SupplierPaymentType::PURCHASE;
        }

        $openPurchases = [];
        $openPurchasesByCurrency = [];

        foreach (PurchaseCurrency::values() as $currency) {
            $bills = SupplierAccountLedger::openPurchasesForSupplier(
                $purchaseSupplier,
                $currency,
                oldestFirst: true,
            )->all();
            $openPurchasesByCurrency[$currency] = $bills;
            foreach ($bills as $bill) {
                $openPurchases[] = [
                    ...$bill,
                    'currency' => $currency,
                ];
            }
        }

        usort($openPurchases, function (array $a, array $b): int {
            $dateCompare = strcmp((string) ($a['purchased_at'] ?? ''), (string) ($b['purchased_at'] ?? ''));

            return $dateCompare !== 0 ? $dateCompare : $a['id'] <=> $b['id'];
        });

        $summaries = SupplierAccountLedger::summaryByCurrency($purchaseSupplier);

        return Inertia::render('purchases/suppliers/payments/create', [
            'supplier' => [
                'id' => $purchaseSupplier->id,
                'name' => $purchaseSupplier->name,
            ],
            'summaries' => array_values($summaries),
            'defaultPaymentType' => $defaultType,
            'openPurchases' => $openPurchases,
            'openPurchasesByCurrency' => $openPurchasesByCurrency,
            'paymentMethods' => SupplierPaymentMethod::values(),
            'currencies' => PurchaseCurrency::values(),
            'paymentTypes' => SupplierPaymentType::values(),
        ]);
    }

    public function store(
        StoreSupplierPaymentRequest $request,
        PurchaseSupplier $purchaseSupplier,
    ): RedirectResponse {
        $validated = $request->validated();

        $paymentData = [
            'currency' => $validated['currency'],
            'amount' => $validated['amount'],
            'bill_payment_amount' => $validated['bill_payment_amount'] ?? null,
            'paid_at' => $validated['paid_at'],
            'payment_method' => $validated['payment_method'] ?? null,
            'reference' => $validated['reference'] ?? null,
            'notes' => $validated['notes'] ?? null,
            'exchange_rate' => $validated['exchange_rate'] ?? null,
        ];

        if ($validated['payment_type'] === SupplierPaymentType::PURCHASE) {
            /** @var Purchase $purchase */
            $purchase = Purchase::query()->findOrFail((int) $validated['purchase_id']);
            SupplierAccountLedger::recordPaymentForPurchase($purchase, $paymentData);
        } else {
            SupplierAccountLedger::recordOverallPayment($purchaseSupplier, [
                ...$paymentData,
                'bill_currency' => $validated['bill_currency'],
            ]);
        }

        return redirect()
            ->route('purchases.suppliers.account', $purchaseSupplier)
            ->with('status', __('Supplier payment recorded.'));
    }
}
