<?php

namespace Tests\Unit\Models;

use App\Enums\Status;
use App\Models\Coupon;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CouponTest extends TestCase
{
    use RefreshDatabase;

    public function test_fixed_discount_never_exceeds_the_subtotal(): void
    {
        $coupon = Coupon::factory()->create(['value' => 500]);

        $this->assertSame(500.0, $coupon->calculateDiscount(1000));
        $this->assertSame(300.0, $coupon->calculateDiscount(300)); // can't discount more than the order is worth
    }

    public function test_percentage_discount_is_capped_by_max_discount_amount(): void
    {
        $coupon = Coupon::factory()->percentage(20, maxDiscount: 500)->create();

        $this->assertSame(500.0, $coupon->calculateDiscount(5000)); // 20% of 5000 = 1000, capped at 500
        $this->assertSame(100.0, $coupon->calculateDiscount(500)); // 20% of 500 = 100, under the cap
    }

    public function test_percentage_discount_without_a_cap_is_uncapped(): void
    {
        $coupon = Coupon::factory()->percentage(10)->create();

        $this->assertSame(1000.0, $coupon->calculateDiscount(10000));
    }

    public function test_is_currently_valid_respects_status(): void
    {
        $inactive = Coupon::factory()->create(['status' => Status::Inactive]);

        $this->assertFalse($inactive->isCurrentlyValid());
    }

    public function test_is_currently_valid_respects_schedule_window(): void
    {
        $notStarted = Coupon::factory()->create(['starts_at' => now()->addDay()]);
        $expired = Coupon::factory()->expired()->create();
        $active = Coupon::factory()->create(['starts_at' => now()->subDay(), 'expires_at' => now()->addDay()]);

        $this->assertFalse($notStarted->isCurrentlyValid());
        $this->assertFalse($expired->isCurrentlyValid());
        $this->assertTrue($active->isCurrentlyValid());
    }

    public function test_is_currently_valid_respects_global_usage_limit(): void
    {
        $exhausted = Coupon::factory()->create(['usage_limit' => 5, 'used_count' => 5]);
        $available = Coupon::factory()->create(['usage_limit' => 5, 'used_count' => 4]);

        $this->assertFalse($exhausted->isCurrentlyValid());
        $this->assertTrue($available->isCurrentlyValid());
    }
}
