<?php

use App\Enums\OwnerVerificationAction;
use App\Enums\OwnerVerificationStatus;
use App\Enums\Permission as PermissionEnum;
use App\Models\Category;
use App\Models\OwnerVerificationRequest;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\User;
use Database\Seeders\RolePermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

uses(RefreshDatabase::class);

beforeEach(function () {
    $this->seed(RolePermissionSeeder::class);
    Storage::fake('public');
});

// ─── Helper ───────────────────────────────────────────────

function createProductUserWithPermission(PermissionEnum ...$permissions): User
{
    $user = User::factory()->create();

    $user->givePermissionTo(
        array_merge(
            [PermissionEnum::DASHBOARD_VIEW->value],
            array_map(fn (PermissionEnum $p) => $p->value, $permissions)
        )
    );

    $user->forgetCachedPermissions();

    return $user;
}

function createProductWithVariants(?Category $category = null): Product
{
    $category ??= Category::factory()->create();
    $product = Product::factory()->create();
    $product->categories()->attach($category->id);

    $variants = ProductVariant::factory()->count(2)->create(['product_id' => $product->id]);

    foreach ($variants as $variant) {
        $variant->addMedia(UploadedFile::fake()->image("{$variant->name}.jpg", 100, 100))
            ->toMediaCollection('images');
    }

    return $product;
}

function createProductVerifierUser(): User
{
    $user = User::factory()->create();

    $user->givePermissionTo([
        PermissionEnum::DASHBOARD_VIEW->value,
        PermissionEnum::OWNER_VERIFICATIONS_VIEW->value,
        PermissionEnum::OWNER_VERIFICATIONS_VERIFY->value,
        PermissionEnum::OWNER_VERIFICATIONS_REJECT->value,
    ]);

    $user->forgetCachedPermissions();

    return $user;
}

function variantWithImage(string $name = 'All Size', int $stock = 10): array
{
    return [
        'name' => $name,
        'stock' => $stock,
        'images' => [UploadedFile::fake()->image("{$name}.jpg", 100, 100)],
    ];
}

// ─── Index ────────────────────────────────────────────────

describe('Product Index', function () {
    test('authenticated user with permission can view product index', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        createProductWithVariants();

        $this->actingAs($user)
            ->get(route('admin.master.products.index'))
            ->assertOk();
    });

    test('guest is redirected to login', function () {
        $this->get(route('admin.master.products.index'))
            ->assertRedirect(route('login'));
    });

    test('user without permission is forbidden', function () {
        $user = User::factory()->create();

        $this->actingAs($user)
            ->get(route('admin.master.products.index'))
            ->assertForbidden();
    });

    test('index displays products with variants and categories', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        createProductWithVariants();
        createProductWithVariants();

        $this->actingAs($user)
            ->get(route('admin.master.products.index'))
            ->assertOk();
    });

    test('index can search products by name', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $category = Category::factory()->create();
        $product = Product::factory()->create(['name' => 'Batik Modern']);
        $product->categories()->attach($category->id);
        ProductVariant::factory()->create(['product_id' => $product->id]);

        $this->actingAs($user)
            ->get(route('admin.master.products.index', ['search' => 'Batik']))
            ->assertOk();
    });

    test('index can filter by active status', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        createProductWithVariants();

        $this->actingAs($user)
            ->get(route('admin.master.products.index', ['is_active' => '1']))
            ->assertOk();
    });

    test('index can filter by category', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $category = Category::factory()->create();
        createProductWithVariants($category);

        $this->actingAs($user)
            ->get(route('admin.master.products.index', ['category_id' => $category->id]))
            ->assertOk();
    });
});

// ─── Create ───────────────────────────────────────────────

describe('Product Create', function () {
    test('authenticated user with permission can view create form', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $this->actingAs($user)
            ->get(route('admin.master.products.create'))
            ->assertOk();
    });

    test('guest is redirected to login', function () {
        $this->get(route('admin.master.products.create'))
            ->assertRedirect(route('login'));
    });

    test('user without create permission is forbidden', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $this->actingAs($user)
            ->get(route('admin.master.products.create'))
            ->assertForbidden();
    });
});

// ─── Store ────────────────────────────────────────────────

describe('Product Store', function () {
    test('authenticated user with permission can submit product creation request', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'description' => 'Deskripsi produk',
                'category_ids' => [$category->id],
                'variants' => [
                    variantWithImage('All Size', 10),
                ],
            ])
            ->assertRedirect(route('admin.master.products.index'));

        $this->assertDatabaseHas('owner_verification_requests', [
            'subject_type' => Product::class,
            'action' => OwnerVerificationAction::CREATE->value,
            'status' => OwnerVerificationStatus::PENDING->value,
        ]);

        $this->assertDatabaseHas('products', [
            'name' => 'Produk Baru',
            'is_active' => false,
        ]);
    });

    test('guest cannot create a product', function () {
        $category = Category::factory()->create();

        $this->post(route('admin.master.products.store'), [
            'name' => 'Produk Baru',
            'category_ids' => [$category->id],
            'variants' => [variantWithImage()],
        ])->assertRedirect(route('login'));
    });

    test('user without create permission is forbidden', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [$category->id],
                'variants' => [variantWithImage()],
            ])
            ->assertForbidden();
    });

    test('name is required', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => '',
                'category_ids' => [$category->id],
                'variants' => [variantWithImage()],
            ])
            ->assertSessionHasErrors('name');
    });

    test('name must not exceed 200 characters', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => str_repeat('a', 201),
                'category_ids' => [$category->id],
                'variants' => [variantWithImage()],
            ])
            ->assertSessionHasErrors('name');
    });

    test('category_ids is required', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [],
                'variants' => [variantWithImage()],
            ])
            ->assertSessionHasErrors('category_ids');
    });

    test('category must exist', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [99999],
                'variants' => [variantWithImage()],
            ])
            ->assertSessionHasErrors('category_ids.0');
    });

    test('variants is required', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [$category->id],
                'variants' => [],
            ])
            ->assertSessionHasErrors('variants');
    });

    test('variant name is required', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [$category->id],
                'variants' => [variantWithImage('', 10)],
            ])
            ->assertSessionHasErrors('variants.0.name');
    });

    test('variant stock is required', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [$category->id],
                'variants' => [['name' => 'All Size', 'stock' => '', 'images' => [UploadedFile::fake()->image('test.jpg')]]],
            ])
            ->assertSessionHasErrors('variants.0.stock');
    });

    test('variant stock must be non-negative integer', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Baru',
                'category_ids' => [$category->id],
                'variants' => [variantWithImage('All Size', -5)],
            ])
            ->assertSessionHasErrors('variants.0.stock');
    });

    test('approving create request activates product with variants and categories', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);
        $verifier = createProductVerifierUser();

        $cat1 = Category::factory()->create();
        $cat2 = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Lengkap',
                'description' => 'Deskripsi lengkap',
                'category_ids' => [$cat1->id, $cat2->id],
                'variants' => [
                    variantWithImage('S', 5),
                    variantWithImage('M', 10),
                    variantWithImage('L', 15),
                ],
            ]);

        $product = Product::where('name', 'Produk Lengkap')->first();
        expect($product)->not->toBeNull();
        expect($product->is_active)->toBeFalse();
        expect($product->categories)->toHaveCount(2);
        expect($product->variants)->toHaveCount(3);

        approveLatestOwnerVerificationRequest($verifier);

        $product->refresh();
        expect($product->is_active)->toBeTrue();
    });

    test('approving create request auto-generates product slug', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);
        $verifier = createProductVerifierUser();

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Batik Modern Elegan',
                'category_ids' => [$category->id],
                'variants' => [variantWithImage()],
            ]);

        $this->assertDatabaseHas('products', [
            'name' => 'Batik Modern Elegan',
            'slug' => 'batik-modern-elegan',
            'is_active' => false,
        ]);

        approveLatestOwnerVerificationRequest($verifier);

        $this->assertDatabaseHas('products', [
            'name' => 'Batik Modern Elegan',
            'slug' => 'batik-modern-elegan',
            'is_active' => true,
        ]);
    });

    test('rejecting create request deletes product', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_CREATE);
        $verifier = createProductVerifierUser();

        $category = Category::factory()->create();

        $this->actingAs($user)
            ->post(route('admin.master.products.store'), [
                'name' => 'Produk Ditolak',
                'category_ids' => [$category->id],
                'variants' => [variantWithImage()],
            ]);

        $product = Product::where('name', 'Produk Ditolak')->first();
        expect($product)->not->toBeNull();

        $verificationRequest = OwnerVerificationRequest::query()->pending()->latest()->firstOrFail();

        $this->actingAs($verifier)
            ->post(route('admin.manage.owner_verifications.reject_request', $verificationRequest), [
                'reason' => 'Tidak sesuai standar',
            ])
            ->assertRedirect();

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

// ─── Edit ─────────────────────────────────────────────────

describe('Product Edit', function () {
    test('authenticated user with permission can view edit form', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);

        $product = createProductWithVariants();

        $this->actingAs($user)
            ->get(route('admin.master.products.edit', $product))
            ->assertOk();
    });

    test('guest is redirected to login', function () {
        $product = createProductWithVariants();

        $this->get(route('admin.master.products.edit', $product))
            ->assertRedirect(route('login'));
    });

    test('user without update permission is forbidden', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $product = createProductWithVariants();

        $this->actingAs($user)
            ->get(route('admin.master.products.edit', $product))
            ->assertForbidden();
    });

    test('edit is blocked when product has pending request', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);

        $product = createProductWithVariants();
        $category = $product->categories->first();
        $variant = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => 'Nama Diubah',
                'category_ids' => [$category->id],
                'variants' => [
                    ['id' => $variant->id, 'name' => $variant->name, 'stock' => $variant->stock],
                ],
            ]);

        $this->actingAs($user)
            ->get(route('admin.master.products.edit', $product))
            ->assertRedirect(route('admin.master.products.index'));
    });
});

// ─── Update ───────────────────────────────────────────────

describe('Product Update', function () {
    test('authenticated user with permission can submit product update request', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);

        $product = createProductWithVariants();
        $category = $product->categories->first();
        $variant = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => 'Nama Diubah',
                'description' => 'Deskripsi baru',
                'category_ids' => [$category->id],
                'variants' => [
                    ['id' => $variant->id, 'name' => 'New Variant', 'stock' => 20],
                ],
            ])
            ->assertRedirect(route('admin.master.products.index'));

        $this->assertDatabaseHas('owner_verification_requests', [
            'subject_id' => $product->id,
            'subject_type' => Product::class,
            'action' => OwnerVerificationAction::UPDATE->value,
            'status' => OwnerVerificationStatus::PENDING->value,
        ]);

        expect($product->fresh()->name)->not->toBe('Nama Diubah');
    });

    test('approving update request applies product changes', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);
        $verifier = createProductVerifierUser();

        $product = createProductWithVariants();
        $category = $product->categories->first();
        $variant = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => 'Nama Diubah',
                'description' => 'Deskripsi baru',
                'category_ids' => [$category->id],
                'variants' => [
                    ['id' => $variant->id, 'name' => 'New Variant', 'stock' => 20],
                ],
            ]);

        approveLatestOwnerVerificationRequest($verifier);

        expect($product->fresh()->name)->toBe('Nama Diubah');
        expect($variant->fresh()->name)->toBe('New Variant');
    });

    test('guest cannot update a product', function () {
        $product = createProductWithVariants();
        $variant = $product->variants->first();

        $this->put(route('admin.master.products.update', $product), [
            'name' => 'Nama Baru',
            'category_ids' => [$product->categories->first()->id],
            'variants' => [['id' => $variant->id, 'name' => $variant->name, 'stock' => $variant->stock]],
        ])->assertRedirect(route('login'));
    });

    test('user without update permission is forbidden', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $product = createProductWithVariants();
        $variant = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => 'Nama Baru',
                'category_ids' => [$product->categories->first()->id],
                'variants' => [['id' => $variant->id, 'name' => $variant->name, 'stock' => $variant->stock]],
            ])
            ->assertForbidden();
    });

    test('name is required on update', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);

        $product = createProductWithVariants();
        $category = $product->categories->first();
        $variant = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => '',
                'category_ids' => [$category->id],
                'variants' => [
                    ['id' => $variant->id, 'name' => $variant->name, 'stock' => $variant->stock],
                ],
            ])
            ->assertSessionHasErrors('name');
    });

    test('category_ids is required on update', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);

        $product = createProductWithVariants();
        $variant = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => 'Nama Produk',
                'category_ids' => [],
                'variants' => [
                    ['id' => $variant->id, 'name' => $variant->name, 'stock' => $variant->stock],
                ],
            ])
            ->assertSessionHasErrors('category_ids');
    });

    test('approving update request removes unsubmitted variants', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_UPDATE);
        $verifier = createProductVerifierUser();

        $product = createProductWithVariants();
        $category = $product->categories->first();
        $variantToKeep = $product->variants->first();

        $this->actingAs($user)
            ->put(route('admin.master.products.update', $product), [
                'name' => 'Updated Product',
                'category_ids' => [$category->id],
                'variants' => [
                    ['id' => $variantToKeep->id, 'name' => 'Kept Variant', 'stock' => 5],
                ],
            ]);

        approveLatestOwnerVerificationRequest($verifier);

        $product->refresh();
        expect($product->variants)->toHaveCount(1);
        expect($product->variants->first()->name)->toBe('Kept Variant');
    });
});

// ─── Toggle Status ────────────────────────────────────────

describe('Product Toggle Status', function () {
    test('authenticated user with permission can submit toggle status request', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_TOGGLE_STATUS);

        $product = createProductWithVariants();

        $this->actingAs($user)
            ->patch(route('admin.master.products.toggle_status', $product), [
                'is_active' => false,
            ])
            ->assertRedirect();

        $this->assertDatabaseHas('owner_verification_requests', [
            'subject_id' => $product->id,
            'subject_type' => Product::class,
            'action' => OwnerVerificationAction::TOGGLE_STATUS->value,
            'status' => OwnerVerificationStatus::PENDING->value,
        ]);

        expect($product->fresh()->is_active)->toBeTrue();
    });

    test('product index exposes display is active for pending toggle status request', function () {
        $user = createProductUserWithPermission(
            PermissionEnum::PRODUCTS_VIEW,
            PermissionEnum::PRODUCTS_TOGGLE_STATUS,
        );

        $product = createProductWithVariants();
        $product->update(['is_active' => true]);

        $this->actingAs($user)
            ->patch(route('admin.master.products.toggle_status', $product), [
                'is_active' => false,
            ])
            ->assertRedirect();

        $response = $this->actingAs($user)
            ->get(route('admin.master.products.index'));

        $response->assertOk();
        $response->assertInertia(fn ($page) => $page
            ->where('products.data.0.id', $product->id)
            ->where('products.data.0.is_active', true)
            ->where('products.data.0.display_is_active', false)
            ->where('products.data.0.has_pending_request', true)
            ->where('products.data.0.pending_request_action', OwnerVerificationAction::TOGGLE_STATUS->value)
        );
    });

    test('approving toggle status request updates product status', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_TOGGLE_STATUS);
        $verifier = createProductVerifierUser();

        $product = createProductWithVariants();

        $this->actingAs($user)
            ->patch(route('admin.master.products.toggle_status', $product), [
                'is_active' => false,
            ]);

        approveLatestOwnerVerificationRequest($verifier);

        expect($product->fresh()->is_active)->toBeFalse();
    });

    test('guest cannot toggle product status', function () {
        $product = createProductWithVariants();

        $this->patch(route('admin.master.products.toggle_status', $product), [
            'is_active' => false,
        ])->assertRedirect(route('login'));
    });

    test('user without toggle permission is forbidden', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $product = createProductWithVariants();

        $this->actingAs($user)
            ->patch(route('admin.master.products.toggle_status', $product), [
                'is_active' => false,
            ])
            ->assertForbidden();
    });

    test('is_active field is required', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_TOGGLE_STATUS);

        $product = createProductWithVariants();

        $this->actingAs($user)
            ->patch(route('admin.master.products.toggle_status', $product), [
                'is_active' => null,
            ])
            ->assertSessionHasErrors('is_active');
    });
});

// ─── Destroy ──────────────────────────────────────────────

describe('Product Destroy', function () {
    test('authenticated user with permission can submit delete request', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_DELETE);

        $product = createProductWithVariants();

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

        $this->assertDatabaseHas('owner_verification_requests', [
            'subject_id' => $product->id,
            'subject_type' => Product::class,
            'action' => OwnerVerificationAction::DELETE->value,
            'status' => OwnerVerificationStatus::PENDING->value,
        ]);

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

    test('approving delete request soft deletes product and variants', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_DELETE);
        $verifier = createProductVerifierUser();

        $product = createProductWithVariants();
        $variantIds = $product->variants->pluck('id')->toArray();

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

        approveLatestOwnerVerificationRequest($verifier);

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

        foreach ($variantIds as $variantId) {
            $this->assertSoftDeleted('product_variants', ['id' => $variantId]);
        }
    });

    test('approving delete request detaches categories', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW, PermissionEnum::PRODUCTS_DELETE);
        $verifier = createProductVerifierUser();

        $product = createProductWithVariants();

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

        approveLatestOwnerVerificationRequest($verifier);

        $this->assertDatabaseMissing('product_categories', ['product_id' => $product->id]);
    });

    test('guest cannot delete a product', function () {
        $product = createProductWithVariants();

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

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

    test('user without delete permission is forbidden', function () {
        $user = createProductUserWithPermission(PermissionEnum::PRODUCTS_VIEW);

        $product = createProductWithVariants();

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

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

// ─── Product Model ────────────────────────────────────────

describe('Product Model', function () {
    test('product uses soft deletes', function () {
        $product = Product::factory()->create();

        $product->delete();

        expect($product->trashed())->toBeTrue();
    });

    test('product can have categories', function () {
        $product = Product::factory()->create();
        $category = Category::factory()->create();
        $product->categories()->attach($category->id);

        expect($product->fresh()->categories)->toHaveCount(1);
    });

    test('product can have variants', function () {
        $product = Product::factory()->create();
        ProductVariant::factory()->count(3)->create(['product_id' => $product->id]);

        expect($product->fresh()->variants)->toHaveCount(3);
    });

    test('product has is_active cast to boolean', function () {
        $product = Product::factory()->create(['is_active' => true]);

        expect($product->is_active)->toBeTrue();

        $product->update(['is_active' => false]);

        expect($product->fresh()->is_active)->toBeFalse();
    });
});
