<?php

namespace App\Services;

use App\Models\Order;
use App\Models\PaymentLog;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

class PaymentService
{
    public function recordPayment(Order $order, float $amount, string $method, ?User $user = null, ?string $reference = null, ?string $note = null): Order
    {
        if ($amount <= 0) {
            throw ValidationException::withMessages(['amount' => 'Nominal pembayaran harus lebih dari nol.']);
        }

        return DB::transaction(function () use ($order, $amount, $method, $user, $reference, $note): Order {
            $order = Order::query()->lockForUpdate()->findOrFail($order->id);

            if ((float) $order->balance_due <= 0) {
                throw ValidationException::withMessages(['amount' => 'Order sudah lunas.']);
            }

            PaymentLog::query()->create([
                'order_id' => $order->id,
                'user_id' => $user?->id,
                'amount' => $amount,
                'method' => $method,
                'reference' => $reference,
                'note' => $note,
            ]);

            $paid = min((float) $order->grand_total, (float) $order->paid_total + $amount);
            $balance = max(0, (float) $order->grand_total - $paid);

            $order->update([
                'paid_total' => $paid,
                'balance_due' => $balance,
                'payment_status' => $balance <= 0 ? 'lunas' : 'dp',
            ]);

            return $order->refresh();
        });
    }
}
