<?php

namespace Tests\Unit\Models;

use App\Models\Inventory;
use App\Models\ProductVariant;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class InventoryTest extends TestCase
{
    use RefreshDatabase;

    public function test_available_quantity_subtracts_reserved_from_on_hand(): void
    {
        $variant = ProductVariant::factory()->create();
        $variant->inventory()->update(['quantity' => 10, 'reserved_quantity' => 3]);

        $this->assertSame(7, $variant->inventory->fresh()->available_quantity);
    }

    public function test_available_quantity_never_goes_negative(): void
    {
        $variant = ProductVariant::factory()->create();
        $variant->inventory()->update(['quantity' => 5, 'reserved_quantity' => 10]);

        $this->assertSame(0, $variant->inventory->fresh()->available_quantity);
    }

    public function test_is_out_of_stock_and_is_low_stock_are_mutually_exclusive(): void
    {
        $out = ProductVariant::factory()->withStock(0)->create();
        $low = ProductVariant::factory()->withStock(3, 5)->create();
        $healthy = ProductVariant::factory()->withStock(50, 5)->create();

        $this->assertTrue($out->inventory->is_out_of_stock);
        $this->assertFalse($out->inventory->is_low_stock);

        $this->assertFalse($low->inventory->is_out_of_stock);
        $this->assertTrue($low->inventory->is_low_stock);

        $this->assertFalse($healthy->inventory->is_out_of_stock);
        $this->assertFalse($healthy->inventory->is_low_stock);
    }

    public function test_scope_low_stock_and_out_of_stock_match_the_accessors(): void
    {
        $out = ProductVariant::factory()->withStock(0)->create();
        $low = ProductVariant::factory()->withStock(2, 5)->create();
        $healthy = ProductVariant::factory()->withStock(50, 5)->create();

        $lowStockIds = Inventory::lowStock()->pluck('id');
        $outOfStockIds = Inventory::outOfStock()->pluck('id');

        $this->assertTrue($lowStockIds->contains($low->inventory->id));
        $this->assertFalse($lowStockIds->contains($out->inventory->id));
        $this->assertFalse($lowStockIds->contains($healthy->inventory->id));

        $this->assertTrue($outOfStockIds->contains($out->inventory->id));
        $this->assertFalse($outOfStockIds->contains($low->inventory->id));
    }
}
