<?php

namespace App\Queries;

use App\Enums\EventStatus;
use App\Enums\PricingType;
use App\Models\Event;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;

class EventQuery
{
    public function publicListing(array $filters = [], int $perPage = 12): LengthAwarePaginator
    {
        $query = Event::query()
            ->with(['game', 'creator', 'prizes'])
            ->whereIn('status', [
                EventStatus::Published,
                EventStatus::RegistrationOpen,
                EventStatus::RegistrationClosed,
                EventStatus::InProgress,
                EventStatus::Completed,
            ])
            ->orderBy('starts_at');

        $this->applyFilters($query, $filters);

        return $query->paginate($perPage)->withQueryString();
    }

    public function featured(int $limit = 3): \Illuminate\Support\Collection
    {
        return Event::query()
            ->with(['game', 'creator', 'prizes'])
            ->where('status', EventStatus::RegistrationOpen)
            ->orderBy('starts_at')
            ->limit($limit)
            ->get();
    }

    public function upcomingForDashboard(int $limit = 6): array
    {
        return Event::query()
            ->with(['game'])
            ->whereIn('status', [EventStatus::RegistrationOpen, EventStatus::Published])
            ->orderBy('starts_at')
            ->limit($limit)
            ->get()
            ->map(fn (Event $event) => app(\App\ViewModels\EventPresenter::class)->toTournamentArray($event))
            ->all();
    }

    private function applyFilters(Builder $query, array $filters): void
    {
        if (filled($filters['game'] ?? null)) {
            $query->whereHas('game', fn (Builder $q) => $q->where('slug', $filters['game']));
        }

        if (filled($filters['status'] ?? null)) {
            $query->where('status', $filters['status']);
        }

        if (filled($filters['pricing'] ?? null)) {
            $query->where('pricing_type', $filters['pricing'] === 'paid' ? PricingType::Paid : PricingType::Free);
        }

        if (filled($filters['q'] ?? null)) {
            $term = '%'.$filters['q'].'%';
            $query->where(function (Builder $q) use ($term) {
                $q->where('title', 'like', $term)
                    ->orWhere('short_description', 'like', $term);
            });
        }
    }
}
