<?php

namespace Tests\Feature;

use App\Models\Divisi;
use App\Models\User;
use App\Models\Vehicle;
use App\Models\VehicleBooking;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class VehicleBookingFlowTest extends TestCase
{
    use RefreshDatabase;

    private function createVehicle(Divisi $divisi, array $overrides = []): Vehicle
    {
        return Vehicle::create(array_merge([
            'name' => 'Toyota Avanza Test',
            'type' => 'mobil',
            'plate_number' => 'L 1000 TT',
            'brand' => 'Toyota',
            'model' => 'Avanza',
            'year' => 2022,
            'color' => 'Hitam',
            'fuel_type' => 'Bensin',
            'capacity' => 7,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ], $overrides));
    }

    public function test_user_can_create_vehicle_booking(): void
    {
        $divisi = Divisi::create(['nama' => 'Operasional']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Toyota Avanza',
            'type' => 'mobil',
            'plate_number' => 'L 1234 AB',
            'brand' => 'Toyota',
            'model' => 'Avanza',
            'year' => 2022,
            'color' => 'Hitam',
            'fuel_type' => 'Bensin',
            'capacity' => 7,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan lapangan',
            'destination' => 'Surabaya Barat',
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
            'notes' => 'Berangkat pagi',
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'user_id' => $user->id,
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan lapangan',
            'destination' => 'Surabaya Barat',
            'status' => 'pending',
        ]);
    }

    public function test_guest_cannot_create_vehicle_booking(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Guest']);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Guest',
            'plate_number' => 'L 1111 GS',
        ]);

        $response = $this->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan tamu',
            'destination' => 'Surabaya',
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(2)->format('Y-m-d H:i:s'),
        ]);

        $response->assertRedirect(route('login'));
        $this->assertDatabaseCount('vehicle_bookings', 0);
    }

    public function test_vehicle_booking_stores_optional_notes(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Notes']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Notes',
            'plate_number' => 'L 1212 NT',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan catatan',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(2)->format('Y-m-d H:i:s'),
            'notes' => 'Perlu kursi tambahan',
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan catatan',
            'notes' => 'Perlu kursi tambahan',
            'status' => 'pending',
        ]);
    }

    public function test_vehicle_booking_is_rejected_when_schedule_conflicts(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Honda Beat',
            'type' => 'motor',
            'plate_number' => 'L 9999 CD',
            'brand' => 'Honda',
            'model' => 'Beat',
            'year' => 2023,
            'color' => 'Putih',
            'fuel_type' => 'Bensin',
            'capacity' => 2,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);
        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking lama',
            'destination' => 'Kantor',
            'start_time' => now()->addHours(2),
            'end_time' => now()->addHours(5),
            'status' => 'approved',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking bentrok',
            'destination' => 'Lokasi lain',
            'start_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(4)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('error');
        $this->assertDatabaseCount('vehicle_bookings', 1);
    }

    public function test_kepala_bidang_can_approve_vehicle_booking(): void
    {
        $divisi = Divisi::create(['nama' => 'Mobilitas']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $kepala = User::factory()->create(['role' => 'kepala_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Suzuki Ertiga',
            'type' => 'mobil',
            'plate_number' => 'L 7777 EF',
            'brand' => 'Suzuki',
            'model' => 'Ertiga',
            'year' => 2021,
            'color' => 'Silver',
            'fuel_type' => 'Bensin',
            'capacity' => 7,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas luar',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(5),
            'end_time' => now()->addHours(7),
            'status' => 'staff_approved',
        ]);

        $response = $this->actingAs($kepala)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ]);

        $response->assertSessionHas('success');
        $this->assertSame('final_approved', $booking->fresh()->status);
    }

    public function test_vehicle_verification_page_shows_start_and_end_time(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Jadwal']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $kepala = User::factory()->create(['role' => 'kepala_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Toyota Hiace',
            'type' => 'mobil',
            'plate_number' => 'L 1234 TJ',
            'brand' => 'Toyota',
            'model' => 'Hiace',
            'year' => 2023,
            'color' => 'Putih',
            'fuel_type' => 'Solar',
            'capacity' => 12,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);
        $startTime = now()->addDays(2)->setTime(9, 30);
        $endTime = now()->addDays(2)->setTime(15, 45);
        $submittedAt = now()->subMinutes(12);

        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Kunjungan kerja',
            'destination' => 'Malang',
            'start_time' => $startTime,
            'end_time' => $endTime,
            'status' => 'staff_approved',
        ]);
        $booking->forceFill([
            'created_at' => $submittedAt,
            'updated_at' => $submittedAt,
        ])->save();

        $response = $this->actingAs($kepala)->get(route('verification.index'));

        $response->assertOk();
        $response->assertSee('Mulai Pinjam');
        $response->assertSee('Rencana Kembali');
        $response->assertSee('Masuk');
        $response->assertSee('Tujuan Penggunaan');
        $response->assertSee('Lokasi Tujuan');
        $response->assertSee('Kunjungan kerja');
        $response->assertSee('Malang');
        $response->assertSee($submittedAt->format('d M Y, H:i'));
        $response->assertSee($startTime->format('d M Y, H:i'));
        $response->assertSee($endTime->format('d M Y, H:i'));
    }

    public function test_vehicle_index_shows_booking_schedule(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Kalender']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Mitsubishi Xpander',
            'type' => 'mobil',
            'plate_number' => 'L 4567 TK',
            'brand' => 'Mitsubishi',
            'model' => 'Xpander',
            'year' => 2024,
            'color' => 'Hitam',
            'fuel_type' => 'Bensin',
            'capacity' => 7,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);
        $startTime = now()->addDay()->setTime(10, 15);
        $endTime = now()->addDay()->setTime(14, 45);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Kunjungan kantor',
            'destination' => 'Sidoarjo',
            'start_time' => $startTime,
            'end_time' => $endTime,
            'status' => 'approved',
        ]);
        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Survey lokasi',
            'destination' => 'Gresik',
            'start_time' => now()->addDays(2)->setTime(9, 0),
            'end_time' => now()->addDays(2)->setTime(11, 30),
            'status' => 'pending',
        ]);

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

        $response->assertOk();
        $response->assertSee('Akan dipakai');
        $response->assertSee('Lihat semua jadwal');
        $response->assertSee('Dipakai');
        $response->assertSee('Kembali');
        $response->assertSee($startTime->format('d M Y, H:i'));
        $response->assertSee($endTime->format('d M Y, H:i'));
    }

    public function test_vehicle_booking_rejects_start_time_in_the_past(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Validasi']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Toyota Innova',
            'type' => 'mobil',
            'plate_number' => 'L 5656 TV',
            'brand' => 'Toyota',
            'model' => 'Innova',
            'year' => 2022,
            'color' => 'Hitam',
            'fuel_type' => 'Bensin',
            'capacity' => 7,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Perjalanan lampau',
            'destination' => 'Surabaya',
            'start_time' => now()->subHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHour()->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHasErrors('start_time');
        $this->assertDatabaseMissing('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Perjalanan lampau',
        ]);
    }

    public function test_vehicle_booking_rejects_end_time_before_start_time(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Range']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = Vehicle::create([
            'name' => 'Honda Vario',
            'type' => 'motor',
            'plate_number' => 'L 5757 HR',
            'brand' => 'Honda',
            'model' => 'Vario',
            'year' => 2021,
            'color' => 'Biru',
            'fuel_type' => 'Bensin',
            'capacity' => 2,
            'status' => 'available',
            'divisi_id' => $divisi->id,
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Range salah',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(4)->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHasErrors('end_time');
        $this->assertDatabaseMissing('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Range salah',
        ]);
    }

    public function test_vehicle_booking_rejects_end_time_equal_to_start_time(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Equal']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Equal',
            'plate_number' => 'L 2020 EQ',
        ]);
        $startTime = now()->addHours(3)->format('Y-m-d H:i:s');

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Waktu sama',
            'destination' => 'Surabaya',
            'start_time' => $startTime,
            'end_time' => $startTime,
        ]);

        $response->assertSessionHasErrors('end_time');
        $this->assertDatabaseMissing('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Waktu sama',
        ]);
    }

    public function test_vehicle_booking_requires_complete_required_fields(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Required']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), []);

        $response->assertSessionHasErrors([
            'vehicle_id',
            'purpose',
            'destination',
            'start_time',
            'end_time',
        ]);
        $this->assertDatabaseCount('vehicle_bookings', 0);
    }

    public function test_vehicle_booking_rejects_overlong_text_fields(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Long Text']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Long Text',
            'plate_number' => 'L 2121 LT',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => str_repeat('A', 256),
            'destination' => str_repeat('B', 256),
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(2)->format('Y-m-d H:i:s'),
            'notes' => str_repeat('C', 501),
        ]);

        $response->assertSessionHasErrors(['purpose', 'destination', 'notes']);
        $this->assertDatabaseCount('vehicle_bookings', 0);
    }

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

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => 999999,
            'purpose' => 'Kunjungan',
            'destination' => 'Surabaya',
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(2)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHasErrors('vehicle_id');
        $this->assertDatabaseCount('vehicle_bookings', 0);
    }

    public function test_vehicle_booking_rejects_unavailable_vehicle(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Maintenance']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Maintenance',
            'plate_number' => 'L 2222 MT',
            'status' => 'maintenance',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan',
            'destination' => 'Surabaya',
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(2)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('error');
        $this->assertDatabaseMissing('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan',
        ]);
    }

    public function test_vehicle_booking_rejects_unavailable_status_vehicle(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Unavailable']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Tidak Tersedia',
            'plate_number' => 'L 2323 UT',
            'status' => 'unavailable',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan',
            'destination' => 'Surabaya',
            'start_time' => now()->addHour()->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(2)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('error');
        $this->assertDatabaseMissing('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Kunjungan',
        ]);
    }

    public function test_vehicle_booking_rejects_conflict_with_pending_schedule(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Pending']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Pending',
            'plate_number' => 'L 3333 PN',
        ]);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking pending',
            'destination' => 'Kantor',
            'start_time' => now()->addHours(2),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Bentrok pending',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(4)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('error');
        $this->assertDatabaseCount('vehicle_bookings', 1);
    }

    public function test_vehicle_booking_rejects_when_new_range_contains_existing_schedule(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Contains']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Contains',
            'plate_number' => 'L 4141 CT',
        ]);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking tengah',
            'destination' => 'Kantor',
            'start_time' => now()->addHours(4),
            'end_time' => now()->addHours(5),
            'status' => 'approved',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking membungkus',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(6)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('error');
        $this->assertDatabaseMissing('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking membungkus',
        ]);
    }

    public function test_vehicle_booking_allows_adjacent_schedule_without_overlap(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Adjacent']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Adjacent',
            'plate_number' => 'L 4444 AD',
        ]);
        $existingEnd = now()->addHours(4)->seconds(0);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking pagi',
            'destination' => 'Kantor',
            'start_time' => now()->addHours(2)->seconds(0),
            'end_time' => $existingEnd,
            'status' => 'approved',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking lanjutan',
            'destination' => 'Gresik',
            'start_time' => $existingEnd->format('Y-m-d H:i:s'),
            'end_time' => $existingEnd->copy()->addHours(2)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking lanjutan',
            'status' => 'pending',
        ]);
        $this->assertSame(2, VehicleBooking::where('vehicle_id', $vehicle->id)->count());
    }

    public function test_vehicle_booking_allows_schedule_that_ends_when_existing_starts(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Adjacent Before']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Adjacent Before',
            'plate_number' => 'L 4242 AB',
        ]);
        $existingStart = now()->addHours(5)->seconds(0);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking sore',
            'destination' => 'Kantor',
            'start_time' => $existingStart,
            'end_time' => $existingStart->copy()->addHours(2),
            'status' => 'approved',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking sebelum sore',
            'destination' => 'Gresik',
            'start_time' => $existingStart->copy()->subHours(2)->format('Y-m-d H:i:s'),
            'end_time' => $existingStart->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking sebelum sore',
            'status' => 'pending',
        ]);
    }

    public function test_vehicle_booking_ignores_rejected_schedule_when_checking_conflict(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Rejected']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Rejected',
            'plate_number' => 'L 5555 RJ',
        ]);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking ditolak',
            'destination' => 'Kantor',
            'start_time' => now()->addHours(2),
            'end_time' => now()->addHours(5),
            'status' => 'rejected',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking pengganti',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(4)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking pengganti',
            'status' => 'pending',
        ]);
    }

    public function test_vehicle_booking_ignores_cancelled_schedule_when_checking_conflict(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Cancelled']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Cancelled',
            'plate_number' => 'L 4343 CL',
        ]);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking batal',
            'destination' => 'Kantor',
            'start_time' => now()->addHours(2),
            'end_time' => now()->addHours(5),
            'status' => 'cancelled',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking setelah batal',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(3)->format('Y-m-d H:i:s'),
            'end_time' => now()->addHours(4)->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'vehicle_id' => $vehicle->id,
            'purpose' => 'Booking setelah batal',
            'status' => 'pending',
        ]);
    }

    public function test_vehicle_booking_allows_same_time_for_different_vehicles(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Multi Vehicle']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $firstVehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Pertama',
            'plate_number' => 'L 3030 MV',
        ]);
        $secondVehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Kedua',
            'plate_number' => 'L 3131 MV',
        ]);
        $startTime = now()->addHours(3)->seconds(0);
        $endTime = now()->addHours(5)->seconds(0);

        VehicleBooking::create([
            'vehicle_id' => $firstVehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking kendaraan pertama',
            'destination' => 'Kantor',
            'start_time' => $startTime,
            'end_time' => $endTime,
            'status' => 'approved',
        ]);

        $response = $this->actingAs($user)->post(route('vehicles.booking.store'), [
            'vehicle_id' => $secondVehicle->id,
            'purpose' => 'Booking kendaraan kedua',
            'destination' => 'Surabaya',
            'start_time' => $startTime->format('Y-m-d H:i:s'),
            'end_time' => $endTime->format('Y-m-d H:i:s'),
        ]);

        $response->assertSessionHas('success');
        $this->assertDatabaseHas('vehicle_bookings', [
            'vehicle_id' => $secondVehicle->id,
            'purpose' => 'Booking kendaraan kedua',
            'status' => 'pending',
        ]);
    }

    public function test_sekretariat_can_approve_vehicle_booking(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Sekretariat']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $sekretariat = User::factory()->create(['role' => 'sekretariat', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Sekretariat',
            'plate_number' => 'L 6666 SK',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas sekretariat',
            'destination' => 'Malang',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($sekretariat)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ]);

        $response->assertSessionHas('success');
        $this->assertSame('sekretariat_approved', $booking->fresh()->status);
    }

    public function test_staff_bidang_can_first_approve_vehicle_booking(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Staff']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $staff = User::factory()->create(['role' => 'staff_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Staff',
            'plate_number' => 'L 5555 SF',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas staff',
            'destination' => 'Gresik',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($staff)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ]);

        $response->assertSessionHas('success');
        $this->assertSame('staff_approved', $booking->fresh()->status);
    }

    public function test_sekretariat_cannot_approve_vehicle_after_staff_already_approved_first_stage(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Double Staff']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $staff = User::factory()->create(['role' => 'staff_bidang', 'divisi_id' => $divisi->id]);
        $sekretariat = User::factory()->create(['role' => 'sekretariat', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Double Staff',
            'plate_number' => 'L 5656 DS',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas double staff',
            'destination' => 'Sidoarjo',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $this->actingAs($staff)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ])->assertSessionHas('success');

        $response = $this->actingAs($sekretariat)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ]);

        $response->assertSessionHas('error');
        $this->assertSame('staff_approved', $booking->fresh()->status);
    }

    public function test_staff_cannot_approve_vehicle_after_sekretariat_already_approved_first_stage(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Double Sekre']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $staff = User::factory()->create(['role' => 'staff_bidang', 'divisi_id' => $divisi->id]);
        $sekretariat = User::factory()->create(['role' => 'sekretariat', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Double Sekre',
            'plate_number' => 'L 5757 DK',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas double sekre',
            'destination' => 'Mojokerto',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $this->actingAs($sekretariat)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ])->assertSessionHas('success');

        $response = $this->actingAs($staff)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ]);

        $response->assertSessionHas('error');
        $this->assertSame('sekretariat_approved', $booking->fresh()->status);
    }

    public function test_kepala_bidang_can_reject_vehicle_booking(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Reject']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $kepala = User::factory()->create(['role' => 'kepala_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Reject',
            'plate_number' => 'L 7777 RJ',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas ditolak',
            'destination' => 'Mojokerto',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'staff_approved',
        ]);

        $response = $this->actingAs($kepala)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'reject',
        ]);

        $response->assertSessionHas('success');
        $this->assertSame('rejected', $booking->fresh()->status);
    }

    public function test_vehicle_booking_revision_action_is_rejected(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Revision']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $kepala = User::factory()->create(['role' => 'kepala_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Revision',
            'plate_number' => 'L 8888 RV',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas revisi',
            'destination' => 'Surabaya',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($kepala)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'revise',
        ]);

        $response->assertSessionHas('error');
        $this->assertSame('pending', $booking->fresh()->status);
    }

    public function test_kepala_cannot_approve_vehicle_booking_before_first_stage_approval(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Kepala Loncat']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $kepala = User::factory()->create(['role' => 'kepala_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Kepala Loncat',
            'plate_number' => 'L 5858 KL',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas kepala loncat',
            'destination' => 'Lamongan',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($kepala)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'approve',
        ]);

        $response->assertSessionHas('error');
        $this->assertSame('pending', $booking->fresh()->status);
    }

    public function test_kepala_can_reject_vehicle_booking_after_sekretariat_first_stage_approval(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Reject Sekre']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $kepala = User::factory()->create(['role' => 'kepala_bidang', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Reject Sekre',
            'plate_number' => 'L 5959 RS',
        ]);
        $booking = VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Dinas reject sekre',
            'destination' => 'Batu',
            'start_time' => now()->addHours(3),
            'end_time' => now()->addHours(5),
            'status' => 'sekretariat_approved',
        ]);

        $response = $this->actingAs($kepala)->post(route('verification.vehicle.action', $booking->id), [
            'action' => 'reject',
        ]);

        $response->assertSessionHas('success');
        $this->assertSame('rejected', $booking->fresh()->status);
    }

    public function test_vehicle_index_shows_ready_panel_when_no_schedule_exists(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Ready']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);

        $this->createVehicle($divisi, [
            'name' => 'Mobil Siap',
            'plate_number' => 'L 9999 RD',
        ]);

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

        $response->assertOk();
        $response->assertSee('Siap Dipinjam');
        $response->assertSee('Belum ada jadwal aktif atau menunggu verifikasi.');
    }

    public function test_vehicle_index_ignores_past_booking_schedule(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Past']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Jadwal Lampau',
            'plate_number' => 'L 4040 PS',
        ]);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking lampau',
            'destination' => 'Kantor',
            'start_time' => now()->subHours(5),
            'end_time' => now()->subHours(3),
            'status' => 'approved',
        ]);

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

        $response->assertOk();
        $response->assertSee('Siap Dipinjam');
        $response->assertDontSee('Booking lampau');
    }

    public function test_vehicle_index_marks_current_approved_booking_as_in_use(): void
    {
        $divisi = Divisi::create(['nama' => 'Transport Active']);
        $user = User::factory()->create(['role' => 'user', 'divisi_id' => $divisi->id]);
        $vehicle = $this->createVehicle($divisi, [
            'name' => 'Mobil Aktif',
            'plate_number' => 'L 5050 AC',
        ]);

        VehicleBooking::create([
            'vehicle_id' => $vehicle->id,
            'user_id' => $user->id,
            'purpose' => 'Booking aktif',
            'destination' => 'Kantor',
            'start_time' => now()->subHour(),
            'end_time' => now()->addHour(),
            'status' => 'approved',
        ]);

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

        $response->assertOk();
        $response->assertSee('Sedang Dipinjam');
        $response->assertSee('Sedang dipakai');
    }
}
