<?php

namespace Tests\Feature;

use App\Models\RequestItem;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class AdminRequestItemCrudTest extends TestCase
{
    use RefreshDatabase;

    public function test_allowed_role_can_store_request_item(): void
    {
        $staff = User::factory()->create(['role' => 'staff_bidang']);

        $response = $this->actingAs($staff)->post(route('admin.request-items.store'), [
            'short_name' => 'Kabel LAN',
            'full_name' => 'Local Area Network',
            'unit' => 'botol',
            'stock' => 50,
            'min_stock' => 10,
            'description' => 'Kabel jaringan',
            'is_active' => 1,
        ]);

        $response->assertRedirect(route('admin.request-items.index'));
        $this->assertDatabaseHas('request_items', [
            'short_name' => 'Kabel LAN',
            'full_name' => 'Local Area Network',
            'display_name' => 'Kabel LAN (Local Area Network)',
            'unit' => 'botol',
            'stock' => 50,
        ]);
    }

    public function test_regular_user_cannot_store_request_item(): void
    {
        $user = User::factory()->create(['role' => 'user']);

        $response = $this->actingAs($user)->post(route('admin.request-items.store'), [
            'short_name' => 'Mouse',
            'full_name' => 'Mouse USB',
            'unit' => 'pcs',
            'stock' => 5,
            'min_stock' => 1,
        ]);

        $response->assertForbidden();
        $this->assertDatabaseCount('request_items', 0);
    }

    public function test_allowed_role_can_delete_request_item(): void
    {
        $kepalaBidang = User::factory()->create(['role' => 'kepala_bidang']);
        $item = RequestItem::create([
            'short_name' => 'RJ45',
            'full_name' => 'Konektor RJ45',
            'display_name' => 'RJ45 (Konektor RJ45)',
            'unit' => 'pcs',
            'stock' => 25,
            'min_stock' => 5,
            'is_active' => true,
        ]);

        $response = $this->actingAs($kepalaBidang)->delete(route('admin.request-items.destroy', $item));

        $response->assertRedirect(route('admin.request-items.index'));
        $this->assertDatabaseMissing('request_items', ['id' => $item->id]);
    }

    public function test_request_item_photo_upload_is_stored_on_public_disk(): void
    {
        Storage::fake('public');

        $staff = User::factory()->create(['role' => 'staff_bidang']);

        $response = $this->actingAs($staff)->post(route('admin.request-items.store'), [
            'short_name' => 'Kertas A4',
            'full_name' => 'Kertas HVS A4',
            'unit' => 'rim',
            'stock' => 12,
            'min_stock' => 2,
            'description' => 'Kertas operasional',
            'is_active' => 1,
            'image_file' => UploadedFile::fake()->image('kertas.png', 640, 480),
        ]);

        $response->assertRedirect(route('admin.request-items.index'));

        $item = RequestItem::where('short_name', 'Kertas A4')->firstOrFail();
        $storedPath = str_replace('storage/', '', $item->getRawOriginal('image_url'));

        $this->assertStringStartsWith('storage/request-items/', $item->getRawOriginal('image_url'));
        Storage::disk('public')->assertExists($storedPath);
    }

    public function test_request_item_photo_upload_must_not_exceed_two_megabytes(): void
    {
        Storage::fake('public');

        $staff = User::factory()->create(['role' => 'staff_bidang']);

        $response = $this->actingAs($staff)
            ->from(route('admin.request-items.create'))
            ->post(route('admin.request-items.store'), [
                'short_name' => 'Kertas Besar',
                'full_name' => 'Kertas Foto Besar',
                'unit' => 'rim',
                'stock' => 12,
                'min_stock' => 2,
                'description' => 'Foto terlalu besar',
                'is_active' => 1,
                'image_file' => UploadedFile::fake()->image('kertas-besar.png', 640, 480)->size(2049),
            ]);

        $response->assertRedirect(route('admin.request-items.create'));
        $response->assertSessionHasErrors('image_file');
        $this->assertDatabaseMissing('request_items', ['short_name' => 'Kertas Besar']);
    }

    public function test_updating_request_item_photo_deletes_old_photo(): void
    {
        Storage::fake('public');

        $staff = User::factory()->create(['role' => 'staff_bidang']);
        Storage::disk('public')->put('request-items/old.png', 'old-photo');
        $item = RequestItem::create([
            'short_name' => 'Map',
            'full_name' => 'Map Arsip',
            'display_name' => 'Map (Map Arsip)',
            'unit' => 'pcs',
            'stock' => 10,
            'min_stock' => 2,
            'image_url' => 'storage/request-items/old.png',
            'is_active' => true,
        ]);

        $response = $this->actingAs($staff)->put(route('admin.request-items.update', $item), [
            'short_name' => 'Map Baru',
            'full_name' => 'Map Arsip Baru',
            'unit' => 'pcs',
            'stock' => 12,
            'min_stock' => 2,
            'is_active' => 1,
            'image_file' => UploadedFile::fake()->image('map-baru.webp', 640, 480),
        ]);

        $response->assertRedirect(route('admin.request-items.index'));
        $item->refresh();
        $newStoredPath = str_replace('storage/', '', $item->getRawOriginal('image_url'));

        Storage::disk('public')->assertMissing('request-items/old.png');
        Storage::disk('public')->assertExists($newStoredPath);
    }

    public function test_deleting_request_item_removes_photo_from_storage(): void
    {
        Storage::fake('public');

        $kepala = User::factory()->create(['role' => 'kepala_bidang']);
        Storage::disk('public')->put('request-items/delete.png', 'delete-photo');
        $item = RequestItem::create([
            'short_name' => 'Amplop',
            'full_name' => 'Amplop Coklat',
            'display_name' => 'Amplop (Amplop Coklat)',
            'unit' => 'pcs',
            'stock' => 10,
            'min_stock' => 2,
            'image_url' => 'storage/request-items/delete.png',
            'is_active' => true,
        ]);

        $response = $this->actingAs($kepala)->delete(route('admin.request-items.destroy', $item));

        $response->assertRedirect(route('admin.request-items.index'));
        Storage::disk('public')->assertMissing('request-items/delete.png');
    }
}
