<?php

use App\Enums\OwnerVerificationAction;
use App\Enums\OwnerVerificationStatus;
use App\Enums\Permission as PermissionEnum;
use App\Enums\RawMaterialUnit;
use App\Models\RawMaterial;
use App\Models\RawMaterialPrice;
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 createRawMaterialUserWithPermission(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 createRawMaterialWithPrices(): RawMaterial
{
    $rawMaterial = RawMaterial::factory()->create();

    $prices = RawMaterialPrice::factory()->count(2)->create(['raw_material_id' => $rawMaterial->id]);

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

    return $rawMaterial;
}

function priceWithImage(string $variant = 'Default', int $price = 50000, float $stock = 10): array
{
    return [
        'variant' => $variant,
        'price' => $price,
        'stock' => $stock,
        'images' => [UploadedFile::fake()->image("{$variant}.jpg", 100, 100)],
    ];
}

function createRawMaterialVerifierUser(): 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;
}

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

describe('Raw Material Index', function () {
    test('authenticated user with permission can view raw material index', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);

        createRawMaterialWithPrices();

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

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

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

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

    test('index displays raw materials with prices', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);

        createRawMaterialWithPrices();
        createRawMaterialWithPrices();

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

    test('index can search raw materials by name', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);

        $rawMaterial = RawMaterial::factory()->create(['name' => 'Kain Batik']);
        RawMaterialPrice::factory()->create(['raw_material_id' => $rawMaterial->id]);

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

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

        createRawMaterialWithPrices();

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

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

describe('Raw Material Create', function () {
    test('authenticated user with permission can view create form', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

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

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

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

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

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

describe('Raw Material Store', function () {
    test('authenticated user with permission can submit raw material creation request', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [
                    priceWithImage('Merah', 75000, 50),
                ],
            ])
            ->assertRedirect(route('admin.master.raw_materials.index'));

        $this->assertDatabaseHas('raw_materials', [
            'name' => 'Kain Sutra',
            'unit' => RawMaterialUnit::METER->value,
            'is_active' => false,
        ]);

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

    test('guest cannot create a raw material', function () {
        $this->post(route('admin.master.raw_materials.store'), [
            'name' => 'Kain Sutra',
            'unit' => RawMaterialUnit::METER->value,
            'prices' => [priceWithImage()],
        ])->assertRedirect(route('login'));
    });

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

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [priceWithImage()],
            ])
            ->assertForbidden();
    });

    test('name is required', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => '',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [priceWithImage()],
            ])
            ->assertSessionHasErrors('name');
    });

    test('name must not exceed 200 characters', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => str_repeat('a', 201),
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [priceWithImage()],
            ])
            ->assertSessionHasErrors('name');
    });

    test('unit is required', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => '',
                'prices' => [priceWithImage()],
            ])
            ->assertSessionHasErrors('unit');
    });

    test('unit must be a valid enum value', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => 'invalid_unit',
                'prices' => [priceWithImage()],
            ])
            ->assertSessionHasErrors('unit');
    });

    test('prices is required', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [],
            ])
            ->assertSessionHasErrors('prices');
    });

    test('price variant is required', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [['variant' => '', 'price' => 50000, 'stock' => 10, 'images' => [UploadedFile::fake()->image('test.jpg')]]],
            ])
            ->assertSessionHasErrors('prices.0.variant');
    });

    test('price amount is required and must be greater than 0', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [priceWithImage('Merah', 0, 10)],
            ])
            ->assertSessionHasErrors('prices.0.price');
    });

    test('stock is required', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [['variant' => 'Merah', 'price' => 50000, 'stock' => '', 'images' => [UploadedFile::fake()->image('test.jpg')]]],
            ])
            ->assertSessionHasErrors('prices.0.stock');
    });

    test('stock must be non-negative', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Sutra',
                'unit' => RawMaterialUnit::METER->value,
                'prices' => [priceWithImage('Merah', 50000, -5)],
            ])
            ->assertSessionHasErrors('prices.0.stock');
    });

    test('creating raw material also creates prices', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);

        $this->actingAs($user)
            ->post(route('admin.master.raw_materials.store'), [
                'name' => 'Kain Premium',
                'unit' => RawMaterialUnit::YARD->value,
                'prices' => [
                    priceWithImage('Merah', 75000, 50),
                    priceWithImage('Biru', 80000, 30),
                ],
            ]);

        $rawMaterial = RawMaterial::where('name', 'Kain Premium')->first();
        expect($rawMaterial)->not->toBeNull();
        expect($rawMaterial->prices)->toHaveCount(2);
    });
});

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

describe('Raw Material Edit', function () {
    test('authenticated user with permission can view edit form', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);

        $rawMaterial = createRawMaterialWithPrices();

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

    test('guest is redirected to login', function () {
        $rawMaterial = createRawMaterialWithPrices();

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

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

        $rawMaterial = createRawMaterialWithPrices();

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

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

describe('Raw Material Update', function () {
    test('authenticated user with permission can submit raw material update request', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);

        $rawMaterial = createRawMaterialWithPrices();
        $price = $rawMaterial->prices->first();

        $this->actingAs($user)
            ->put(route('admin.master.raw_materials.update', $rawMaterial), [
                'name' => 'Nama Diubah',
                'unit' => RawMaterialUnit::KILOGRAM->value,
                'prices' => [
                    ['id' => $price->id, 'variant' => 'Putih', 'price' => 90000, 'stock' => 25],
                ],
            ])
            ->assertRedirect(route('admin.master.raw_materials.index'));

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

        expect($rawMaterial->fresh()->name)->not->toBe('Nama Diubah');
        expect($price->fresh()->variant)->not->toBe('Putih');
    });

    test('approving update request applies raw material changes', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
        $verifier = createRawMaterialVerifierUser();

        $rawMaterial = createRawMaterialWithPrices();
        $price = $rawMaterial->prices->first();

        $this->actingAs($user)
            ->put(route('admin.master.raw_materials.update', $rawMaterial), [
                'name' => 'Nama Diubah',
                'unit' => RawMaterialUnit::KILOGRAM->value,
                'prices' => [
                    ['id' => $price->id, 'variant' => 'Putih', 'price' => 90000, 'stock' => 25],
                ],
            ]);

        approveLatestOwnerVerificationRequest($verifier);

        expect($rawMaterial->fresh()->name)->toBe('Nama Diubah');
        expect($price->fresh()->variant)->toBe('Putih');
    });

    test('guest cannot update a raw material', function () {
        $rawMaterial = createRawMaterialWithPrices();
        $price = $rawMaterial->prices->first();

        $this->put(route('admin.master.raw_materials.update', $rawMaterial), [
            'name' => 'Nama Baru',
            'unit' => $rawMaterial->unit->value,
            'prices' => [['id' => $price->id, 'variant' => $price->variant, 'price' => $price->price, 'stock' => $price->stock]],
        ])->assertRedirect(route('login'));
    });

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

        $rawMaterial = createRawMaterialWithPrices();
        $price = $rawMaterial->prices->first();

        $this->actingAs($user)
            ->put(route('admin.master.raw_materials.update', $rawMaterial), [
                'name' => 'Nama Baru',
                'unit' => $rawMaterial->unit->value,
                'prices' => [['id' => $price->id, 'variant' => $price->variant, 'price' => $price->price, 'stock' => $price->stock]],
            ])
            ->assertForbidden();
    });

    test('name is required on update', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);

        $rawMaterial = createRawMaterialWithPrices();
        $price = $rawMaterial->prices->first();

        $this->actingAs($user)
            ->put(route('admin.master.raw_materials.update', $rawMaterial), [
                'name' => '',
                'unit' => $rawMaterial->unit->value,
                'prices' => [
                    ['id' => $price->id, 'variant' => $price->variant, 'price' => $price->price, 'stock' => $price->stock],
                ],
            ])
            ->assertSessionHasErrors('name');
    });

    test('prices is required on update', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);

        $rawMaterial = createRawMaterialWithPrices();

        $this->actingAs($user)
            ->put(route('admin.master.raw_materials.update', $rawMaterial), [
                'name' => 'Nama Bahan',
                'unit' => $rawMaterial->unit->value,
                'prices' => [],
            ])
            ->assertSessionHasErrors('prices');
    });

    test('unsubmitted prices are removed after approving update request', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
        $verifier = createRawMaterialVerifierUser();

        $rawMaterial = createRawMaterialWithPrices();
        $priceToKeep = $rawMaterial->prices->first();

        $this->actingAs($user)
            ->put(route('admin.master.raw_materials.update', $rawMaterial), [
                'name' => 'Updated Material',
                'unit' => $rawMaterial->unit->value,
                'prices' => [
                    ['id' => $priceToKeep->id, 'variant' => 'Kept', 'price' => 60000, 'stock' => 15],
                ],
            ]);

        approveLatestOwnerVerificationRequest($verifier);

        $rawMaterial->refresh();
        expect($rawMaterial->prices)->toHaveCount(1);
        expect($rawMaterial->prices->first()->variant)->toBe('Kept');
    });
});

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

describe('Raw Material Toggle Status', function () {
    test('authenticated user with permission can submit toggle status request', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_TOGGLE_STATUS);

        $rawMaterial = RawMaterial::factory()->create();

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

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

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

    test('raw material index exposes display is active for pending toggle status request', function () {
        $user = createRawMaterialUserWithPermission(
            PermissionEnum::RAW_MATERIALS_VIEW,
            PermissionEnum::RAW_MATERIALS_TOGGLE_STATUS,
        );

        $rawMaterial = RawMaterial::factory()->create(['is_active' => true]);

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

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

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

    test('approving toggle status request updates raw material status', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_TOGGLE_STATUS);
        $verifier = createRawMaterialVerifierUser();

        $rawMaterial = RawMaterial::factory()->create();

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

        approveLatestOwnerVerificationRequest($verifier);

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

    test('guest cannot toggle raw material status', function () {
        $rawMaterial = RawMaterial::factory()->create();

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

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

        $rawMaterial = RawMaterial::factory()->create();

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

    test('is_active field is required', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_TOGGLE_STATUS);

        $rawMaterial = RawMaterial::factory()->create();

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

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

describe('Raw Material Destroy', function () {
    test('authenticated user with permission can submit delete request', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_DELETE);

        $rawMaterial = createRawMaterialWithPrices();

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

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

        $this->assertNotSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
    });

    test('approving delete request soft deletes raw material and prices', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_DELETE);
        $verifier = createRawMaterialVerifierUser();

        $rawMaterial = createRawMaterialWithPrices();
        $priceIds = $rawMaterial->prices->pluck('id')->toArray();

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

        approveLatestOwnerVerificationRequest($verifier);

        $this->assertSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);

        foreach ($priceIds as $priceId) {
            $this->assertSoftDeleted('raw_material_prices', ['id' => $priceId]);
        }
    });

    test('guest cannot delete a raw material', function () {
        $rawMaterial = createRawMaterialWithPrices();

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

        $this->assertNotSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
    });

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

        $rawMaterial = createRawMaterialWithPrices();

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

        $this->assertNotSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
    });

    test('deleting raw material is not applied until owner approves', function () {
        $user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_DELETE);

        $rawMaterial = createRawMaterialWithPrices();
        $priceIds = $rawMaterial->prices->pluck('id')->toArray();

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

        $this->assertNotSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);

        foreach ($priceIds as $priceId) {
            $this->assertNotSoftDeleted('raw_material_prices', ['id' => $priceId]);
        }
    });
});

// ─── Raw Material Model ───────────────────────────────────

describe('Raw Material Model', function () {
    test('raw material uses soft deletes', function () {
        $rawMaterial = RawMaterial::factory()->create();

        $rawMaterial->delete();

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

    test('raw material can have prices', function () {
        $rawMaterial = RawMaterial::factory()->create();
        RawMaterialPrice::factory()->count(3)->create(['raw_material_id' => $rawMaterial->id]);

        expect($rawMaterial->fresh()->prices)->toHaveCount(3);
    });

    test('raw material has is_active cast to boolean', function () {
        $rawMaterial = RawMaterial::factory()->create(['is_active' => true]);

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

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

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

    test('raw material has unit cast to enum', function () {
        $rawMaterial = RawMaterial::factory()->create(['unit' => RawMaterialUnit::YARD->value]);

        expect($rawMaterial->unit)->toBe(RawMaterialUnit::YARD);
    });

    test('raw material has unit label accessor', function () {
        $rawMaterial = RawMaterial::factory()->create(['unit' => RawMaterialUnit::METER->value]);

        expect($rawMaterial->unit_label)->toBe('Meter');
    });

    test('raw material has unit abbreviation accessor', function () {
        $rawMaterial = RawMaterial::factory()->create(['unit' => RawMaterialUnit::KILOGRAM->value]);

        expect($rawMaterial->unit_abbreviation)->toBe('kg');
    });
});
