<?php

namespace Tests\Unit\Purchase;

use App\Domains\Catalog\Models\StockReservation;
use App\Domains\Purchase\Models\Purchase;
use App\Domains\Purchase\Resources\PurchaseResource;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class PurchaseResourceTest extends TestCase
{
    public function test_it_exposes_the_remaining_checkout_time_using_the_server_clock(): void
    {
        $now = now()->startOfSecond();
        $this->travelTo($now);
        $expiresAt = $now->copy()->addMinutes(12);

        $resource = $this->resourceFor(Purchase::STATUS_PENDING_PAYMENT, $expiresAt);

        $this->assertTrue($expiresAt->equalTo($resource['expires_at']));
        $this->assertSame(720, $resource['expires_in_seconds']);
        $this->assertTrue($now->equalTo($resource['server_time']));

        $this->travelBack();
    }

    public function test_it_clamps_an_overdue_checkout_to_zero_seconds(): void
    {
        $now = now()->startOfSecond();
        $this->travelTo($now);

        $resource = $this->resourceFor(
            Purchase::STATUS_CREATED,
            $now->copy()->subSecond(),
        );

        $this->assertSame(0, $resource['expires_in_seconds']);

        $this->travelBack();
    }

    public function test_it_exposes_null_expiration_after_the_purchase_enters_review(): void
    {
        $resource = $this->resourceFor(
            Purchase::STATUS_IN_REVIEW,
            null,
        );

        $this->assertNull($resource['expires_at']);
        $this->assertNull($resource['expires_in_seconds']);
    }

    /** @return array<string, mixed> */
    private function resourceFor(string $status, ?Carbon $expiresAt): array
    {
        $purchase = (new Purchase)->forceFill([
            'status' => $status,
            'total' => '0.00',
        ]);
        $purchase->setRelation('stockReservation', (new StockReservation)->forceFill([
            'status' => StockReservation::STATUS_ACTIVE,
            'expires_at' => $expiresAt,
        ]));

        return (new PurchaseResource($purchase))->toArray(Request::create('/'));
    }
}
