<?php

namespace Tests\Feature;

use App\Models\Branch;
use App\Models\Category;
use App\Models\Product;
use App\Models\ProductStock;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;

class StockTransferTest extends TestCase
{
    use RefreshDatabase;

    public function test_owner_can_create_and_approve_stock_transfer(): void
    {
        [$owner, $from, $to, $product] = $this->fixtures();

        $this->actingAs($owner)
            ->get(route('stock-transfers.index'))
            ->assertOk()
            ->assertSee('Buat Transfer Stok');

        $this->actingAs($owner)->post(route('stock-transfers.store'), [
            'from_branch_id' => $from->id,
            'to_branch_id' => $to->id,
            'items' => [
                ['product_id' => $product->id, 'quantity' => 4],
            ],
            'note' => 'Kirim stok',
        ])->assertRedirect();

        $this->assertDatabaseHas('stock_transfers', [
            'from_branch_id' => $from->id,
            'to_branch_id' => $to->id,
            'status' => 'pending',
        ]);

        $transfer = \App\Models\StockTransfer::query()->firstOrFail();

        $this->actingAs($owner)->post(route('stock-transfers.approve', $transfer))->assertRedirect();

        $this->assertSame('approved', $transfer->refresh()->status);
        $this->assertSame(6.0, (float) ProductStock::query()->where('branch_id', $from->id)->where('product_id', $product->id)->first()->quantity);
        $this->assertSame(4.0, (float) ProductStock::query()->where('branch_id', $to->id)->where('product_id', $product->id)->first()->quantity);
        $this->assertDatabaseHas('stock_mutations', ['source_type' => 'stock_transfer_out', 'quantity_change' => -4]);
        $this->assertDatabaseHas('stock_mutations', ['source_type' => 'stock_transfer_in', 'quantity_change' => 4]);
    }

    public function test_transfer_create_rejects_insufficient_origin_stock(): void
    {
        [$owner, $from, $to, $product] = $this->fixtures();

        $this->actingAs($owner)->post(route('stock-transfers.store'), [
            'from_branch_id' => $from->id,
            'to_branch_id' => $to->id,
            'items' => [
                ['product_id' => $product->id, 'quantity' => 99],
            ],
        ])->assertSessionHasErrors('stock');
    }

    private function fixtures(): array
    {
        $from = Branch::query()->create(['name' => 'Cabang Asal', 'code' => 'ASL']);
        $to = Branch::query()->create(['name' => 'Cabang Tujuan', 'code' => 'TJN']);
        $owner = User::query()->create([
            'branch_id' => $from->id,
            'name' => 'Owner',
            'email' => 'owner-transfer@example.test',
            'role' => 'owner',
            'password' => Hash::make('password'),
        ]);
        $category = Category::query()->create(['name' => 'Retail', 'type' => 'retail']);
        $product = Product::query()->create([
            'category_id' => $category->id,
            'name' => 'Plastik Laundry',
            'sku' => 'RTL-TRANSFER',
            'type' => 'retail',
            'unit' => 'pcs',
            'price' => 10000,
            'track_stock' => true,
            'minimum_stock' => 2,
        ]);

        ProductStock::query()->create(['branch_id' => $from->id, 'product_id' => $product->id, 'quantity' => 10]);

        return [$owner, $from, $to, $product];
    }
}
