<?php

declare(strict_types=1);

use App\Models\Coupon;
use App\Models\Plan;
use App\Models\User;
use Database\Seeders\RoleAndPermissionSeeder;

beforeEach(function (): void {
    $this->seed(RoleAndPermissionSeeder::class);
    $this->accountUrl = 'http://'.config('app.domains.account');
});

it('displays the checkout page for an active plan', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'active']);

    $this->actingAs($user)
        ->get($this->accountUrl.'/checkout/'.$plan->id)
        ->assertOk()
        ->assertInertia(fn ($page) => $page
            ->component('Checkout/Show')
            ->has('plan')
            ->where('plan.id', $plan->id)
        );
});

it('returns 404 for unavailable plan checkout', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'inactive']);

    $this->actingAs($user)
        ->get($this->accountUrl.'/checkout/'.$plan->id)
        ->assertNotFound();
});

it('returns 404 for out of stock plan checkout', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'active', 'stock_quantity' => 0]);

    $this->actingAs($user)
        ->get($this->accountUrl.'/checkout/'.$plan->id)
        ->assertNotFound();
});

it('validates a valid coupon code', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'active', 'price' => 100.00]);
    $coupon = Coupon::factory()->create([
        'code' => 'SAVE20',
        'type' => 'percentage',
        'value' => 20.00,
        'max_uses' => 100,
        'times_used' => 0,
        'expires_at' => now()->addMonth(),
    ]);

    $this->actingAs($user)
        ->postJson($this->accountUrl.'/checkout/apply-coupon', [
            'code' => 'SAVE20',
            'plan_id' => $plan->id,
        ])
        ->assertOk()
        ->assertJson([
            'valid' => true,
            'discount' => 20.00,
            'new_total' => 80.00,
            'coupon_type' => 'percentage',
            'coupon_value' => '20.00',
        ]);
});

it('rejects an expired coupon', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'active']);
    Coupon::factory()->create([
        'code' => 'EXPIRED',
        'expires_at' => now()->subDay(),
    ]);

    $this->actingAs($user)
        ->postJson($this->accountUrl.'/checkout/apply-coupon', [
            'code' => 'EXPIRED',
            'plan_id' => $plan->id,
        ])
        ->assertUnprocessable()
        ->assertJson(['valid' => false]);
});

it('rejects a maxed-out coupon', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'active']);
    Coupon::factory()->create([
        'code' => 'MAXED',
        'max_uses' => 5,
        'times_used' => 5,
        'expires_at' => now()->addMonth(),
    ]);

    $this->actingAs($user)
        ->postJson($this->accountUrl.'/checkout/apply-coupon', [
            'code' => 'MAXED',
            'plan_id' => $plan->id,
        ])
        ->assertUnprocessable()
        ->assertJson(['valid' => false]);
});

it('validates checkout form requires gateway', function (): void {
    $user = User::factory()->create();
    $plan = Plan::factory()->create(['status' => 'active']);

    $this->actingAs($user)
        ->post($this->accountUrl.'/checkout/'.$plan->id, [])
        ->assertSessionHasErrors('gateway');
});
