<?php

namespace Tests\Feature;

use App\Models\Booking;
use App\Models\Service;
use App\Models\User;
use App\Services\AvailabilityService;
use App\Services\BookingStateService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class BookingFlowTest extends TestCase
{
    use RefreshDatabase;

    public function test_booking_lifecycle_and_slot_generation(): void
    {
        \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'provider']);
        \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'customer']);

        $provider = User::factory()->create();
        $provider->assignRole('provider');

        $customer = User::factory()->create();
        $customer->assignRole('customer');

        $service = Service::factory()->create([
            'user_id' => $provider->id,
            'delivery_mode' => 'online',
            'booking_mode' => 'approval_required',
            'scheduling_type' => 'fixed_datetime',
            'duration_minutes' => 60,
        ]);

        $booking = Booking::create([
            'service_id' => $service->id,
            'customer_id' => $customer->id,
            'provider_id' => $provider->id,
            'status' => 'draft',
            'booking_mode' => 'approval_required',
            'scheduling_type' => 'fixed_datetime',
            'delivery_mode' => 'online',
            'amount' => 100,
            'currency' => 'USD',
            'approval_expires_at' => now()->addDay(),
        ]);

        $state = app(BookingStateService::class);
        $state->transition($booking, 'pending_payment');
        $state->transition($booking, 'pending_provider_approval');
        $state->transition($booking, 'confirmed');

        $this->assertEquals('confirmed', $booking->refresh()->status);

        $availability = app(AvailabilityService::class);
        $slots = $availability->getSlots(
            $service,
            Carbon::now()->startOfWeek(),
            Carbon::now()->startOfWeek()->addDay()
        );

        $this->assertInstanceOf(\Illuminate\Support\Collection::class, $slots);
    }
}
