<?php

namespace Modules\Vrc\Tests\Unit;

use Illuminate\Database\Capsule\Manager as Capsule;
use Modules\Vrc\Entities\VrcAppointment;
use PHPUnit\Framework\TestCase;

/**
 * §6.2 acceptance: "booking blocks the slot" — verifies the bay double-booking
 * detection (bayConflicts scope) against an in-memory SQLite DB.
 */
class AppointmentConflictTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        $capsule = new Capsule;
        $capsule->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '']);
        $capsule->setAsGlobal();
        $capsule->bootEloquent();

        Capsule::schema()->create('vrc_appointments', function ($t) {
            $t->increments('id');
            $t->integer('business_id');
            $t->integer('bay_id')->nullable();
            $t->dateTime('scheduled_start');
            $t->dateTime('scheduled_end')->nullable();
            $t->string('status')->default('requested');
            $t->timestamps();
        });

        VrcAppointment::query()->insert([
            ['business_id' => 1, 'bay_id' => 5, 'scheduled_start' => '2026-06-25 10:00:00', 'scheduled_end' => '2026-06-25 12:00:00', 'status' => 'confirmed'],
            ['business_id' => 1, 'bay_id' => 5, 'scheduled_start' => '2026-06-25 14:00:00', 'scheduled_end' => '2026-06-25 15:00:00', 'status' => 'cancelled'],
        ]);
    }

    protected function tearDown(): void
    {
        Capsule::schema()->drop('vrc_appointments');
        parent::tearDown();
    }

    private function conflicts(string $start, string $end, ?int $ignore = null): int
    {
        return VrcAppointment::where('business_id', 1)->bayConflicts(5, $start, $end, $ignore)->count();
    }

    public function test_overlapping_slot_conflicts(): void
    {
        $this->assertSame(1, $this->conflicts('2026-06-25 11:00:00', '2026-06-25 11:30:00'));
    }

    public function test_adjacent_slot_does_not_conflict(): void
    {
        // starts exactly when the existing one ends
        $this->assertSame(0, $this->conflicts('2026-06-25 12:00:00', '2026-06-25 13:00:00'));
    }

    public function test_cancelled_appointment_is_ignored(): void
    {
        // overlaps the 14:00–15:00 slot, but that one is cancelled
        $this->assertSame(0, $this->conflicts('2026-06-25 14:15:00', '2026-06-25 14:45:00'));
    }

    public function test_ignore_id_excludes_self_when_rescheduling(): void
    {
        $this->assertSame(0, $this->conflicts('2026-06-25 11:00:00', '2026-06-25 11:30:00', 1));
    }
}
