<?php

namespace App\Listeners\GuestNotifications;

use App\Enums\GuestNotificationAudience;
use App\Enums\GuestNotificationType;
use App\Events\GuestPhotoUploaded;
use App\Models\Photo;
use App\Services\GuestNotificationService;

class SendPhotoUploadedNotification
{
    /**
     * @param  int[]  $milestones
     */
    public function __construct(
        private readonly GuestNotificationService $notifications,
        private readonly array $milestones = []
    ) {}

    public function handle(GuestPhotoUploaded $event): void
    {
        $guestLabel = $this->resolveGuestLabel($event->guestName, $event->guestIdentifier);
        $title = $guestLabel
            ? sprintf('%s hat gerade ein Foto gemacht 🎉', $guestLabel)
            : 'Es gibt neue Fotos!';

        $this->notifications->createNotification(
            $event->event,
            GuestNotificationType::PHOTO_ACTIVITY,
            $title,
            null,
            [
                'audience_scope' => GuestNotificationAudience::ALL,
                'payload' => [
                    'photo_id' => $event->photoId,
                ],
                'expires_at' => now()->addHours(3),
            ]
        );

        $this->maybeCreateMilestoneNotification($event, $guestLabel);
    }

    private function maybeCreateMilestoneNotification(GuestPhotoUploaded $event, ?string $guestLabel): void
    {
        if (! $guestLabel) {
            return;
        }

        $count = Photo::where('event_id', $event->event->id)
            ->where('guest_name', $event->guestIdentifier)
            ->count();

        $milestones = $this->milestones ?: config('notifications.guest_achievements.milestones', [10, 25, 50]);

        if (! in_array($count, $milestones, true)) {
            return;
        }

        $title = sprintf('%s hat ein neues Achievement erreicht 🏅', $guestLabel);
        $body = sprintf('%s hat jetzt %d Fotos beigetragen – weiter so!', $guestLabel, $count);

        $this->notifications->createNotification(
            $event->event,
            GuestNotificationType::ACHIEVEMENT_MAJOR,
            $title,
            $body,
            [
                'audience_scope' => GuestNotificationAudience::ALL,
                'expires_at' => now()->addDay(),
            ]
        );
    }

    private function resolveGuestLabel(?string $guestName, string $guestIdentifier): ?string
    {
        $name = $guestName && trim($guestName) !== '' ? trim($guestName) : null;

        if ($name) {
            return $name;
        }

        if ($guestIdentifier === 'anon') {
            return null;
        }

        return $guestIdentifier;
    }
}
