<?php

namespace App\Domains\Purchase\Services;

use App\Domains\Catalog\Services\StockReservationService;
use App\Domains\Purchase\Models\Purchase;
use App\Domains\Purchase\Services\Checkout\CompleteCheckoutService;
use App\Domains\Purchase\Services\Checkout\EditCheckoutService;
use App\Domains\Purchase\Services\Checkout\ReleaseCheckoutService;
use App\Domains\Purchase\Services\Checkout\StartCheckoutService;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Support\Facades\DB;

/**
 * Stable checkout API used by controllers, commands and integrations.
 *
 * Workflow details live in focused services under Services/Checkout.
 */
class CheckoutService
{
    public function __construct(
        private readonly StartCheckoutService $starter,
        private readonly EditCheckoutService $editor,
        private readonly CompleteCheckoutService $completer,
        private readonly ReleaseCheckoutService $releaser,
        private readonly StockReservationService $reservations,
    ) {}

    /** @param array<string, mixed> $purchaseData */
    public function startCheckout(Tenant $tenant, int $userId, array $purchaseData): Purchase
    {
        return $this->starter->start($tenant, $userId, $purchaseData);
    }

    public function completePurchase(Purchase $purchase): Purchase
    {
        return $this->completer->complete($purchase);
    }

    public function submitForReview(Purchase $purchase): Purchase
    {
        return $this->completer->submitForReview($purchase);
    }

    /** @param array<string, string> $customerData */
    public function updateCustomerData(Purchase $purchase, array $customerData): Purchase
    {
        return $this->editor->updateCustomer($purchase, $customerData);
    }

    public function confirmPurchase(Purchase $purchase): void
    {
        $this->completer->confirm($purchase);
    }

    public function confirmPaidPurchase(Purchase $purchase): Purchase
    {
        return DB::transaction(function () use ($purchase): Purchase {
            $this->completer->confirm($purchase);
            $purchase->markAsPaid();

            return $purchase->refresh()->load(['items.imageAttachment']);
        });
    }

    public function cancelPurchase(Purchase $purchase): Purchase
    {
        return $this->releaser->cancel($purchase);
    }

    public function cancelPurchaseFromAdmin(Purchase $purchase): Purchase
    {
        return $this->releaser->cancelFromAdmin($purchase);
    }

    public function expirePurchase(Purchase $purchase): Purchase
    {
        return $this->releaser->expire($purchase);
    }

    public function expireOverduePurchases(): int
    {
        return $this->releaser->expireOverdue();
    }

    public function syncReservationExpiration(Purchase $purchase): void
    {
        $this->reservations->syncPurchaseExpiration($purchase);
    }
}
