<?php

namespace Tests\Feature;

use App\Models\{Category, Product, User};
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ProductTest extends TestCase
{
    use RefreshDatabase;

    protected User $admin;
    protected Category $category;

    protected function setUp(): void
    {
        parent::setUp();

        $this->admin = User::create([
            'name' => 'Admin', 'username' => 'admin',
            'email' => 'admin@test.com', 'password' => bcrypt('password'),
            'role' => 'admin', 'is_active' => true,
        ]);

        $this->category = Category::create([
            'name' => 'Minuman', 'slug' => 'minuman', 'color' => '#3b82f6',
        ]);
    }

    /** @test */
    public function admin_bisa_melihat_daftar_produk()
    {
        $this->actingAs($this->admin)
            ->get(route('products.index'))
            ->assertOk()
            ->assertViewIs('products.index');
    }

    /** @test */
    public function admin_bisa_membuat_produk_baru()
    {
        $this->actingAs($this->admin)
            ->post(route('products.store'), [
                'name'          => 'Aqua 600ml',
                'category_id'   => $this->category->id,
                'cost_price'    => 2500,
                'selling_price' => 4000,
                'unit'          => 'botol',
                'stock'         => 100,
                'min_stock'     => 10,
                'track_stock'   => true,
                'is_active'     => true,
            ])
            ->assertRedirect(route('products.index'));

        $this->assertDatabaseHas('products', [
            'name'          => 'Aqua 600ml',
            'selling_price' => 4000,
        ]);

        // SKU harus ter-generate otomatis
        $this->assertNotNull(Product::where('name', 'Aqua 600ml')->first()->sku);
    }

    /** @test */
    public function produk_tidak_bisa_dibuat_dengan_harga_negatif()
    {
        $this->actingAs($this->admin)
            ->post(route('products.store'), [
                'name'          => 'Produk Invalid',
                'cost_price'    => -1000,
                'selling_price' => -500,
                'unit'          => 'pcs',
                'stock'         => 0,
                'min_stock'     => 0,
            ])
            ->assertSessionHasErrors(['cost_price', 'selling_price']);
    }

    /** @test */
    public function admin_bisa_update_produk()
    {
        $product = Product::create([
            'name'          => 'Lama', 'sku' => 'OLD-001',
            'cost_price'    => 1000, 'selling_price' => 2000,
            'unit'          => 'pcs', 'stock' => 10, 'min_stock' => 2,
        ]);

        $this->actingAs($this->admin)
            ->put(route('products.update', $product), [
                'name'          => 'Nama Baru',
                'cost_price'    => 1500,
                'selling_price' => 3000,
                'unit'          => 'pcs',
                'min_stock'     => 5,
                'track_stock'   => true,
                'is_active'     => true,
            ])
            ->assertRedirect(route('products.index'));

        $this->assertEquals('Nama Baru', $product->fresh()->name);
        $this->assertEquals(3000, $product->fresh()->selling_price);
    }

    /** @test */
    public function admin_bisa_hapus_produk()
    {
        $product = Product::create([
            'name' => 'Hapus Ini', 'sku' => 'DEL-001',
            'cost_price' => 1000, 'selling_price' => 2000,
            'unit' => 'pcs', 'stock' => 0, 'min_stock' => 0,
        ]);

        $this->actingAs($this->admin)
            ->delete(route('products.destroy', $product))
            ->assertRedirect();

        $this->assertSoftDeleted('products', ['id' => $product->id]);
    }

    /** @test */
    public function kasir_tidak_bisa_akses_produk()
    {
        $kasir = User::create([
            'name' => 'Kasir', 'username' => 'kasir1',
            'email' => 'kasir@test.com', 'password' => bcrypt('password'),
            'role' => 'kasir', 'is_active' => true,
        ]);

        $this->actingAs($kasir)
            ->get(route('products.index'))
            ->assertStatus(403);
    }

    /** @test */
    public function penyesuaian_stok_manual_berfungsi()
    {
        $product = Product::create([
            'name' => 'Stok Test', 'sku' => 'STK-001',
            'cost_price' => 1000, 'selling_price' => 2000,
            'unit' => 'pcs', 'stock' => 20, 'min_stock' => 5,
            'track_stock' => true,
        ]);

        $this->actingAs($this->admin)
            ->post(route('products.adjust-stock', $product), [
                'type'     => 'in',
                'quantity' => 30,
                'reason'   => 'Terima dari supplier',
            ])
            ->assertRedirect();

        $this->assertEquals(50, $product->fresh()->stock);

        $this->assertDatabaseHas('stock_movements', [
            'product_id'      => $product->id,
            'type'            => 'in',
            'quantity_before' => 20,
            'quantity_change' => 30,
            'quantity_after'  => 50,
        ]);
    }
}
