<?php

namespace Tests\Unit;

use App\Enums\GuestNotificationType;
use App\Events\GuestPhotoUploaded;
use App\Listeners\GuestNotifications\SendPhotoUploadedNotification;
use App\Models\Event;
use App\Models\GuestNotification;
use App\Models\GuestNotificationReceipt;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class SendPhotoUploadedNotificationTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_dedupes_recent_photo_activity_notifications(): void
    {
        Carbon::setTestNow('2026-01-12 13:48:01');

        $event = Event::factory()->create();
        $listener = $this->app->make(SendPhotoUploadedNotification::class);

        GuestNotification::factory()->create([
            'tenant_id' => $event->tenant_id,
            'event_id' => $event->id,
            'type' => GuestNotificationType::PHOTO_ACTIVITY,
            'title' => 'Fotospiel-Test hat gerade ein Foto gemacht 🎉',
            'payload' => [
                'photo_id' => 123,
                'photo_ids' => [123],
                'count' => 1,
            ],
            'created_at' => now()->subSeconds(5),
            'updated_at' => now()->subSeconds(5),
        ]);

        $listener->handle(new GuestPhotoUploaded(
            $event,
            123,
            'device-123',
            'Fotospiel-Test'
        ));

        $notification = GuestNotification::query()
            ->where('event_id', $event->id)
            ->where('type', GuestNotificationType::PHOTO_ACTIVITY)
            ->first();

        $this->assertSame(1, GuestNotification::query()
            ->where('event_id', $event->id)
            ->where('type', GuestNotificationType::PHOTO_ACTIVITY)
            ->count());
        $this->assertSame(1, (int) ($notification?->payload['count'] ?? 0));
    }

    public function test_it_groups_recent_photo_activity_notifications(): void
    {
        Carbon::setTestNow('2026-01-12 13:48:01');

        $event = Event::factory()->create();
        $listener = $this->app->make(SendPhotoUploadedNotification::class);

        GuestNotification::factory()->create([
            'tenant_id' => $event->tenant_id,
            'event_id' => $event->id,
            'type' => GuestNotificationType::PHOTO_ACTIVITY,
            'title' => 'Fotospiel-Test hat gerade ein Foto gemacht 🎉',
            'payload' => [
                'photo_id' => 122,
                'photo_ids' => [122],
                'count' => 1,
            ],
            'created_at' => now()->subMinutes(5),
            'updated_at' => now()->subMinutes(5),
        ]);

        $listener->handle(new GuestPhotoUploaded(
            $event,
            123,
            'device-123',
            'Fotospiel-Test'
        ));

        $this->assertSame(1, GuestNotification::query()
            ->where('event_id', $event->id)
            ->where('type', GuestNotificationType::PHOTO_ACTIVITY)
            ->count());

        $notification = GuestNotification::query()
            ->where('event_id', $event->id)
            ->where('type', GuestNotificationType::PHOTO_ACTIVITY)
            ->first();

        $this->assertSame('Es gibt 2 neue Fotos!', $notification?->title);
        $this->assertSame(2, (int) ($notification?->payload['count'] ?? 0));

        $this->assertSame(1, GuestNotificationReceipt::query()
            ->where('guest_identifier', 'device-123')
            ->where('status', 'read')
            ->count());
    }

    public function test_it_creates_notification_outside_group_window(): void
    {
        Carbon::setTestNow('2026-01-12 13:48:01');

        $event = Event::factory()->create();
        $listener = $this->app->make(SendPhotoUploadedNotification::class);

        GuestNotification::factory()->create([
            'tenant_id' => $event->tenant_id,
            'event_id' => $event->id,
            'type' => GuestNotificationType::PHOTO_ACTIVITY,
            'title' => 'Fotospiel-Test hat gerade ein Foto gemacht 🎉',
            'payload' => [
                'photo_id' => 122,
                'photo_ids' => [122],
                'count' => 1,
            ],
            'created_at' => now()->subMinutes(20),
            'updated_at' => now()->subMinutes(20),
        ]);

        $listener->handle(new GuestPhotoUploaded(
            $event,
            123,
            'device-123',
            'Fotospiel-Test'
        ));

        $this->assertSame(2, GuestNotification::query()
            ->where('event_id', $event->id)
            ->where('type', GuestNotificationType::PHOTO_ACTIVITY)
            ->count());

        $this->assertSame(1, GuestNotificationReceipt::query()
            ->where('guest_identifier', 'device-123')
            ->where('status', 'read')
            ->count());
    }
}
