<?php

namespace App\Filament\Clusters\DailyOps\Pages;

use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Widgets\JoinTokenOverviewWidget;
use App\Filament\Widgets\JoinTokenTopTokensWidget;
use App\Filament\Widgets\JoinTokenTrendWidget;
use App\Models\Event;
use BackedEnum;
use Filament\Forms\Components\Select;
use Filament\Pages\Dashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use UnitEnum;

class JoinTokenAnalyticsDashboard extends Dashboard
{
    use HasFiltersForm;

    protected static ?string $cluster = DailyOpsCluster::class;

    protected static string $routePath = 'join-token-analytics';

    protected static null|string|BackedEnum $navigationIcon = 'heroicon-o-chart-bar';

    protected static null|string|UnitEnum $navigationGroup = null;

    protected static ?int $navigationSort = 12;

    public static function getNavigationGroup(): UnitEnum|string|null
    {
        return __('admin.nav.security');
    }

    public static function getNavigationLabel(): string
    {
        return __('admin.join_token_analytics.navigation.label');
    }

    public function getHeading(): string
    {
        return __('admin.join_token_analytics.heading');
    }

    public function getSubheading(): ?string
    {
        return __('admin.join_token_analytics.subheading');
    }

    public function getColumns(): int|array
    {
        return 1;
    }

    public function getWidgets(): array
    {
        return [
            JoinTokenOverviewWidget::class,
            JoinTokenTrendWidget::class,
            JoinTokenTopTokensWidget::class,
        ];
    }

    public function filtersForm(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make()
                    ->schema([
                        Select::make('range')
                            ->label(__('admin.join_token_analytics.filters.range'))
                            ->options(trans('admin.join_token_analytics.filters.range_options'))
                            ->default('24h')
                            ->native(false),
                        Select::make('event_id')
                            ->label(__('admin.join_token_analytics.filters.event'))
                            ->placeholder(__('admin.join_token_analytics.filters.event_placeholder'))
                            ->searchable()
                            ->getSearchResultsUsing(fn (string $search): array => $this->searchEvents($search))
                            ->getOptionLabelUsing(fn ($value): ?string => $this->resolveEventLabel($value))
                            ->native(false),
                    ])
                    ->columns(2),
            ]);
    }

    private function searchEvents(string $search): array
    {
        return Event::query()
            ->with('tenant')
            ->when($search !== '', function ($query) use ($search) {
                $query->where('slug', 'like', "%{$search}%")
                    ->orWhere('name->de', 'like', "%{$search}%")
                    ->orWhere('name->en', 'like', "%{$search}%");
            })
            ->orderByDesc('date')
            ->limit(25)
            ->get()
            ->mapWithKeys(fn (Event $event) => [$event->id => $this->formatEventLabel($event)])
            ->all();
    }

    private function resolveEventLabel(mixed $value): ?string
    {
        if (! is_numeric($value)) {
            return null;
        }

        $event = Event::query()
            ->with('tenant')
            ->find((int) $value);

        return $event ? $this->formatEventLabel($event) : null;
    }

    private function formatEventLabel(Event $event): string
    {
        $locale = app()->getLocale();
        $name = $event->name[$locale] ?? $event->name['de'] ?? $event->name['en'] ?? $event->slug ?? __('admin.common.unnamed');
        $tenant = $event->tenant?->name ?? __('admin.common.unnamed');
        $date = $event->date?->format('Y-m-d');

        return $date ? "{$name} ({$tenant}) {$date}" : "{$name} ({$tenant})";
    }
}
