<?php

namespace Tests\Feature;

use App\Models\Branch;
use App\Models\Category;
use App\Models\Customer;
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 MasterDataCrudTest extends TestCase
{
    use RefreshDatabase;

    public function test_owner_can_create_update_and_disable_product_with_initial_stock(): void
    {
        [$owner, $branch, $category] = $this->fixtures();

        $this->actingAs($owner)
            ->get(route('master.index', 'products'))
            ->assertOk()
            ->assertSee('Master Produk / Layanan');

        $this->actingAs($owner)->post(route('master.store', 'products'), [
            'category_id' => $category->id,
            'name' => 'Deterjen Retail',
            'sku' => 'RTL-DET',
            'type' => 'retail',
            'unit' => 'pcs',
            'price' => 15000,
            'cost_price' => 9000,
            'track_stock' => 1,
            'minimum_stock' => 3,
            'bonus_type' => 'none',
            'bonus_value' => 0,
            'is_active' => 1,
            'initial_branch_id' => $branch->id,
            'initial_stock' => 12,
        ])->assertRedirect();

        $product = Product::query()->where('sku', 'RTL-DET')->firstOrFail();
        $this->assertTrue($product->track_stock);
        $this->assertSame(12.0, (float) ProductStock::query()->where('product_id', $product->id)->first()->quantity);

        $this->actingAs($owner)->put(route('master.update', ['products', $product->id]), [
            'category_id' => $category->id,
            'name' => 'Deterjen Retail Premium',
            'sku' => 'RTL-DET',
            'type' => 'retail',
            'unit' => 'pcs',
            'price' => 18000,
            'cost_price' => 10000,
            'track_stock' => 1,
            'minimum_stock' => 4,
            'bonus_type' => 'none',
            'bonus_value' => 0,
            'is_active' => 1,
        ])->assertRedirect(route('master.index', 'products'));

        $this->assertSame('Deterjen Retail Premium', $product->refresh()->name);

        $this->actingAs($owner)->delete(route('master.destroy', ['products', $product->id]))->assertRedirect();
        $this->assertFalse($product->refresh()->is_active);
    }

    public function test_customer_pin_can_be_reset_from_master_data(): void
    {
        [$owner, $branch] = $this->fixtures();
        $customer = Customer::query()->create([
            'branch_id' => $branch->id,
            'name' => 'Siti',
            'phone' => '62815550000',
            'pin' => Hash::make('123456'),
        ]);

        $this->actingAs($owner)
            ->post(route('master.customers.reset-pin', $customer))
            ->assertRedirect();

        $this->assertTrue(Hash::check('000000', $customer->refresh()->pin));
    }

    private function fixtures(): array
    {
        $branch = Branch::query()->create(['name' => 'Cabang Master', 'code' => 'MST']);
        $owner = User::query()->create([
            'branch_id' => $branch->id,
            'name' => 'Owner',
            'email' => 'owner-master@example.test',
            'role' => 'owner',
            'password' => Hash::make('password'),
        ]);
        $category = Category::query()->create(['name' => 'Retail', 'type' => 'retail']);

        return [$owner, $branch, $category];
    }
}
