<?php

namespace Tests\Feature;

use App\Enums\PhotoLiveStatus;
use App\Models\Event;
use App\Models\Photo;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LiveShowRealtimeTest extends TestCase
{
    use RefreshDatabase;

    public function test_live_show_state_returns_ordered_photos_and_cursor(): void
    {
        $event = Event::factory()->create([
            'live_show_token' => str_repeat('a', 64),
        ]);

        $first = Photo::factory()->for($event)->create([
            'status' => 'approved',
            'live_status' => PhotoLiveStatus::APPROVED,
            'live_approved_at' => now()->subMinutes(10),
        ]);

        $second = Photo::factory()->for($event)->create([
            'status' => 'approved',
            'live_status' => PhotoLiveStatus::APPROVED,
            'live_approved_at' => now()->subMinutes(3),
        ]);

        $response = $this->getJson("/api/v1/live-show/{$event->live_show_token}");

        $response->assertOk();
        $response->assertJsonPath('photos.0.id', $first->id);
        $response->assertJsonPath('photos.1.id', $second->id);
        $response->assertJsonPath('cursor.id', $second->id);
        $response->assertJsonStructure([
            'settings',
            'settings_version',
            'photos',
            'cursor' => ['approved_at', 'id'],
        ]);
    }

    public function test_live_show_updates_respects_cursor(): void
    {
        $event = Event::factory()->create([
            'live_show_token' => str_repeat('b', 64),
        ]);

        $first = Photo::factory()->for($event)->create([
            'status' => 'approved',
            'live_status' => PhotoLiveStatus::APPROVED,
            'live_approved_at' => now()->subMinutes(9),
        ]);

        $second = Photo::factory()->for($event)->create([
            'status' => 'approved',
            'live_status' => PhotoLiveStatus::APPROVED,
            'live_approved_at' => now()->subMinutes(6),
        ]);

        $third = Photo::factory()->for($event)->create([
            'status' => 'approved',
            'live_status' => PhotoLiveStatus::APPROVED,
            'live_approved_at' => now()->subMinutes(1),
        ]);

        $query = http_build_query([
            'after_approved_at' => $second->live_approved_at->toAtomString(),
            'after_id' => $second->id,
        ]);

        $response = $this->getJson("/api/v1/live-show/{$event->live_show_token}/updates?{$query}");

        $response->assertOk();
        $response->assertJsonCount(1, 'photos');
        $response->assertJsonPath('photos.0.id', $third->id);
        $response->assertJsonPath('cursor.id', $third->id);
        $response->assertJsonMissing(['photos' => [['id' => $first->id]]]);
    }

    public function test_live_show_returns_404_for_invalid_token(): void
    {
        $response = $this->getJson('/api/v1/live-show/invalid-token');

        $response->assertNotFound();
    }

    public function test_live_show_updates_returns_settings_when_version_changes(): void
    {
        $event = Event::factory()->create([
            'live_show_token' => str_repeat('c', 64),
            'settings' => [
                'live_show' => [
                    'effect_preset' => 'film_cut',
                ],
            ],
        ]);

        $state = $this->getJson("/api/v1/live-show/{$event->live_show_token}");
        $state->assertOk();
        $version = $state->json('settings_version');

        $updates = $this->getJson("/api/v1/live-show/{$event->live_show_token}/updates?settings_version={$version}");
        $updates->assertOk();
        $updates->assertJsonPath('settings', null);

        $event->forceFill([
            'settings' => [
                'live_show' => [
                    'effect_preset' => 'shutter_flash',
                ],
            ],
        ])->save();

        $updates = $this->getJson("/api/v1/live-show/{$event->live_show_token}/updates?settings_version={$version}");
        $updates->assertOk();
        $updates->assertJsonMissing(['settings' => null]);
        $updates->assertJsonPath('settings.effect_preset', 'shutter_flash');
    }

    public function test_live_show_updates_rejects_invalid_cursor(): void
    {
        $event = Event::factory()->create([
            'live_show_token' => str_repeat('d', 64),
        ]);

        $response = $this->getJson("/api/v1/live-show/{$event->live_show_token}/updates?after_approved_at=invalid&after_id=1");

        $response->assertStatus(422);
        $response->assertJsonPath('error', 'invalid_cursor');
    }
}
