<?php

namespace App\ViewComposers;

use App\Queries\EventQuery;
use App\ViewModels\EventPresenter;
use Illuminate\Support\Facades\Route;
use Illuminate\View\View;

class AppShellComposer
{
    public function __construct(
        private EventQuery $eventQuery,
        private EventPresenter $eventPresenter,
    ) {}

    public function compose(View $view): void
    {
        $user = auth()->user();
        $profile = $user?->playerProfile;

        $player = null;
        if ($user) {
            $player = [
                'id' => $user->id,
                'display_name' => $profile?->display_name ?? $user->display_name ?? $user->username,
                'username' => $user->username,
                'email' => $user->email,
                'avatar' => $profile?->avatar_path
                    ? asset('storage/'.$profile->avatar_path)
                    : asset('assets/images/generated/players/player-1.webp'),
                'level' => $this->estimateLevel($profile?->profile_completion_percentage ?? 40),
                'profile_url' => $profile
                    ? route('profile.show', $profile)
                    : route('settings'),
                'settings_url' => route('settings'),
            ];
        }

        $view->with([
            'shellPlayer' => $player,
            'notificationCount' => $user ? $user->unreadNotifications()->count() : 0,
            'navItems' => $this->resolveNavItems(config('navigation.sidebar', [])),
            'mobileNavItems' => $this->resolveNavItems(config('navigation.mobile', [])),
            'featuredTournament' => $view->offsetExists('featuredTournament')
                ? $view->offsetGet('featuredTournament')
                : $this->featuredTournament(),
        ]);
    }

    /**
     * @param  array<int, array<string, mixed>>  $items
     * @return array<int, array<string, mixed>>
     */
    private function resolveNavItems(array $items): array
    {
        return collect($items)->map(function (array $item) {
            $url = '#';
            if (! empty($item['route']) && Route::has($item['route'])) {
                $url = route($item['route']);
            } elseif (! empty($item['preview']) && Route::has($item['preview'])) {
                $url = route($item['preview']);
            }

            $activePatterns = $item['active'] ?? [];
            $isActive = false;
            foreach ($activePatterns as $pattern) {
                if (request()->routeIs($pattern)) {
                    $isActive = true;
                    break;
                }
            }

            return array_merge($item, [
                'url' => $url,
                'is_active' => $isActive,
            ]);
        })->all();
    }

    private function featuredTournament(): ?array
    {
        $event = $this->eventQuery->featured(1)->first();
        if (! $event) {
            return null;
        }

        $mapped = $this->eventPresenter->toTournamentArray($event);

        return [
            'game_name' => $mapped['game_name'],
            'name' => $mapped['name'],
            'starts_at' => $mapped['starts_at']?->toIso8601String() ?? $mapped['start_date'],
            'url' => route('events.show', ['event' => $mapped['slug']]),
        ];
    }

    private function estimateLevel(int $completion): int
    {
        return max(1, (int) round($completion / 4));
    }
}
