<?php

use App\Livewire\Studio\Manage\Restock\Create;
use App\Models\Bottle;
use App\Models\Perfume;
use App\Models\Product;
use App\Models\Warehouse;
use Livewire\Livewire;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

beforeEach(function () {
    $this->setupUser();
    $this->outlet = $this->user->outlets->first();

    // Create permissions
    $permissions = [
        'view restock',
        'create restock',
    ];

    foreach ($permissions as $permission) {
        Permission::firstOrCreate(['name' => $permission]);
    }

    $role = Role::create(['name' => 'Owner']);
    $role->givePermissionTo($permissions);
    $this->user->assignRole($role);
});

it('renders the restock create page', function () {
    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->assertStatus(200);
});

it('can add items to restock cart', function () {
    $warehouse = Warehouse::factory()->create();
    $perfume = Perfume::factory()->create(['name' => 'Test Perfume']);

    // Add stock to warehouse
    $warehouse->perfumes()->attach($perfume->id, ['stock' => 100]);

    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.warehouse_id', $warehouse->id)
        ->set('form.outlet_id', $this->outlet->id)
        ->set('form.perfume_id', $perfume->id)
        ->set('form.quantity_perfume', 10)
        ->call('addItem', 'parfum')
        ->assertSee('Test Perfume')
        ->assertSee(10);
});

it('can store a restock and transfer stock', function () {
    $warehouse = Warehouse::factory()->create();
    $perfume = Perfume::factory()->create();
    $product = Product::factory()->create();
    $bottle = Bottle::factory()->create();

    // Seed initial stock
    $warehouse->perfumes()->attach($perfume->id, ['stock' => 100]);
    $warehouse->products()->attach($product->id, ['stock' => 100]);
    $warehouse->bottles()->attach($bottle->id, ['stock' => 100]);

    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.warehouse_id', $warehouse->id)
        ->set('form.outlet_id', $this->outlet->id)
        ->set('form.restock_date', now()->format('Y-m-d'))
        ->set('form.note', 'Test Restock')

        // Add items
        ->set('form.perfume_id', $perfume->id)
        ->set('form.quantity_perfume', 10)
        ->call('addItem', 'parfum')

        ->set('form.product_id', $product->id)
        ->set('form.quantity_product', 5)
        ->call('addItem', 'produk')

        ->set('form.bottle_id', $bottle->id)
        ->set('form.quantity_bottle', 20)
        ->call('addItem', 'botol')

        ->call('save')
        ->assertRedirect(route('studio.manage.restock.index', ['notification' => 'Restock berhasil diproses.']));

    // Verify DB records
    $this->assertDatabaseHas('restocks', [
        'warehouse_id' => $warehouse->id,
        'outlet_id' => $this->outlet->id,
        'note' => 'Test Restock',
    ]);

    // Verify Warehouse Stock Decreased
    $this->assertEquals(90, $warehouse->perfumes()->find($perfume->id)->pivot->stock);
    $this->assertEquals(95, $warehouse->products()->find($product->id)->pivot->stock);
    $this->assertEquals(80, $warehouse->bottles()->find($bottle->id)->pivot->stock);

    // Verify Outlet Stock Increased
    $this->assertEquals(10, $this->outlet->perfumes()->find($perfume->id)->pivot->stock);
    $this->assertEquals(5, $this->outlet->products()->find($product->id)->pivot->stock);
    $this->assertEquals(20, $this->outlet->bottles()->find($bottle->id)->pivot->stock);
});

it('cannot restock more than available warehouse stock', function () {
    $warehouse = Warehouse::factory()->create();
    $perfume = Perfume::factory()->create();
    $warehouse->perfumes()->attach($perfume->id, ['stock' => 10]);

    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.warehouse_id', $warehouse->id)
        ->set('form.outlet_id', $this->outlet->id)
        ->set('form.restock_date', now()->format('Y-m-d'))
        ->set('form.perfume_id', $perfume->id)
        ->set('form.quantity_perfume', 20) // Requesting more than 10
        ->call('addItem', 'parfum');

    // Assert that the item was NOT added to the cart
    $this->assertDatabaseMissing('restock_items', [
        'restockable_id' => $perfume->id,
        'quantity' => 20,
    ]);
});

it('validates restock input', function () {
    $warehouse = Warehouse::factory()->create();
    $perfume = Perfume::factory()->create();
    $warehouse->perfumes()->attach($perfume->id, ['stock' => 100]);

    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.warehouse_id', $warehouse->id)
        ->set('form.outlet_id', $this->outlet->id)
        ->set('form.perfume_id', $perfume->id)
        ->set('form.quantity_perfume', 10)
        ->call('addItem', 'parfum')

        // Reset required fields
        ->set('form.restock_date', '')
        ->set('form.outlet_id', '') // Warehouse ID is needed for item adding, but outlet ID is validated on save

        ->call('save')
        ->assertHasErrors(['form.restock_date', 'form.outlet_id']);
});
