<?php

namespace App\ViewModels;

use App\Enums\EventStatus;
use App\Models\Event;
use App\Services\RegistrationStatusService;

class EventPresenter
{
    public function __construct(private RegistrationStatusService $registrationStatus) {}

    public function toTournamentArray(Event $event): array
    {
        $event->loadMissing(['game', 'creator', 'prizes']);

        $registered = $this->registrationStatus->occupiedCount($event);
        $prizePool = $this->calculatePrizePool($event);

        return [
            'id' => $event->id,
            'public_id' => $event->public_id,
            'slug' => $event->slug,
            'name' => $event->title,
            'game' => $event->game->slug,
            'game_name' => $event->game->name,
            'organizer' => $event->creator?->display_name ?? 'ALGA ARENA',
            'region' => $event->location_type->label(),
            'format' => $event->event_type->label(),
            'status' => $this->mapStatus($event->status),
            'status_label' => $event->status->label(),
            'featured' => $event->published_at !== null && $event->status === EventStatus::RegistrationOpen,
            'cover' => $event->cover_image ? asset('storage/'.$event->cover_image) : null,
            'prize_pool' => $prizePool,
            'prize_currency' => $event->currency ?? 'USD',
            'max_teams' => $event->capacity ?? 0,
            'registered_teams' => $registered,
            'start_date' => $event->starts_at?->toDateString(),
            'end_date' => $event->ends_at?->toDateString(),
            'registration_deadline' => $event->registration_closes_at?->toDateString(),
            'starts_at' => $event->starts_at,
            'ends_at' => $event->ends_at,
            'pricing_type' => $event->pricing_type->value,
            'fee_amount_minor' => $event->fee_amount_minor,
            'currency' => $event->currency,
            'participation_type' => $event->participation_type->value,
            'location_type' => $event->location_type->value,
            'description' => $event->description,
            'short_description' => $event->short_description,
            'stream_url' => null,
            'requirements' => [
                'min_rank' => '—',
                'verified_only' => false,
                'region_locked' => false,
            ],
        ];
    }

    /** @param iterable<Event> $events */
    public function mapCollection(iterable $events): array
    {
        $items = [];

        foreach ($events as $event) {
            $items[] = $this->toTournamentArray($event);
        }

        return $items;
    }

    private function mapStatus(EventStatus $status): string
    {
        return match ($status) {
            EventStatus::RegistrationOpen => 'registration_open',
            EventStatus::InProgress => 'live',
            EventStatus::Completed => 'completed',
            EventStatus::Cancelled => 'cancelled',
            EventStatus::RegistrationClosed => 'upcoming',
            default => 'upcoming',
        };
    }

    private function calculatePrizePool(Event $event): int
    {
        $total = 0;

        foreach ($event->prizes()->get() as $prize) {
            $amount = preg_replace('/[^\d.]/', '', (string) $prize->amount) ?? '';
            if ($amount !== '' && is_numeric($amount)) {
                $total += (int) round((float) $amount);
            }
        }

        if ($total > 0) {
            return $total;
        }

        $legacyPrizes = $event->getAttributes()['prizes'] ?? null;

        if (filled($legacyPrizes) && is_numeric(preg_replace('/[^\d.]/', '', (string) $legacyPrizes))) {
            return (int) round((float) preg_replace('/[^\d.]/', '', (string) $legacyPrizes));
        }

        return 0;
    }
}
