<?php

namespace App\Domains\Purchase\Services;

use App\Domains\Cart\Models\Cart;
use App\Domains\Purchase\Exceptions\PurchaseExpiredException;
use App\Domains\Purchase\Models\Purchase;
use Illuminate\Validation\ValidationException;

class PurchaseStateGuard
{
    public function assertNotExpired(Purchase $purchase): void
    {
        $hasExpiredStatus = $purchase->status === Purchase::STATUS_EXPIRED;
        $hasExpiredByTime = in_array($purchase->status, [
            Purchase::STATUS_CREATED,
            Purchase::STATUS_PENDING_PAYMENT,
        ], true)
            && $purchase->expires_at !== null
            && $purchase->expires_at->isPast();

        if ($hasExpiredStatus || $hasExpiredByTime) {
            throw new PurchaseExpiredException;
        }
    }

    public function lockCurrentCart(Purchase $purchase): Cart
    {
        /** @var Cart|null $cart */
        $cart = $purchase->cart()->withTrashed()->lockForUpdate()->first();

        if ($cart === null || $cart->current_purchase_id !== $purchase->getKey()) {
            throw ValidationException::withMessages([
                'purchase' => __('api.purchase.not_current'),
            ]);
        }

        return $cart;
    }
}
