<?php

namespace Tests\Feature\Api\V1;

use App\Models\QueueEntry;
use App\Models\User;
use Database\Seeders\ClinicDemoSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class QueueRegressionTest extends TestCase
{
    use RefreshDatabase;

    public function test_call_next_advances_04_to_05_not_06(): void
    {
        $this->seed(ClinicDemoSeeder::class);
        $assistant = User::where('email', 'assistant.one@smartclinic.test')->firstOrFail();
        Sanctum::actingAs($assistant);

        $tokenFour = QueueEntry::where('token_number', 4)->firstOrFail();

        $response = $this->postJson('/api/v1/queue/call-next', [
            'doctor_id' => $tokenFour->doctor_id,
            'location_id' => $tokenFour->location_id,
            'queue_date' => $tokenFour->queue_date->toDateString(),
        ]);

        $response->assertOk()
            ->assertJsonPath('data.token_number', 5)
            ->assertJsonPath('data.status', 'with_doctor');
    }

    public function test_manual_token_collision_is_rejected(): void
    {
        $this->seed(ClinicDemoSeeder::class);
        $assistant = User::where('email', 'assistant.one@smartclinic.test')->firstOrFail();
        Sanctum::actingAs($assistant);

        $tokenSix = QueueEntry::where('token_number', 6)->firstOrFail();

        $this->patchJson("/api/v1/queue/{$tokenSix->id}/token", [
            'token_number' => 5,
        ])->assertStatus(409)
            ->assertJsonPath('error.code', 'TOKEN_ALREADY_IN_USE');
    }

    public function test_queue_status_transitions_keep_appointment_and_visit_metrics_synchronized(): void
    {
        $this->seed(ClinicDemoSeeder::class);
        $assistant = User::where('email', 'assistant.one@smartclinic.test')->firstOrFail();
        Sanctum::actingAs($assistant);

        $entry = QueueEntry::where('token_number', 5)->with(['appointment', 'patient'])->firstOrFail();
        $beforeVisits = $entry->patient->total_visits;

        $this->postJson("/api/v1/queue/{$entry->id}/status", [
            'status' => 'with_doctor',
        ])->assertOk()->assertJsonPath('data.status', 'with_doctor');
        $this->assertSame('with_doctor', $entry->appointment->fresh()->status->value);

        $this->postJson("/api/v1/queue/{$entry->id}/status", [
            'status' => 'completed',
        ])->assertOk()->assertJsonPath('data.status', 'completed');
        $this->assertSame('completed', $entry->appointment->fresh()->status->value);
        $this->assertSame($beforeVisits + 1, $entry->patient->fresh()->total_visits);
    }
}
