<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Domain\Theme\ThemeManager;
use App\Settings\GeneralSettings;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\Artisan;
use UnitEnum;

class ManageThemes extends Page
{
    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedSwatch;

    protected static ?int $navigationSort = 80;

    protected string $view = 'filament.pages.manage-themes';

    public string $activeTheme = 'default';

    /** @var array<int, array<string, mixed>> */
    public array $themes = [];

    public static function getNavigationGroup(): ?string
    {
        return __('admin.groups.system');
    }

    public static function getNavigationLabel(): string
    {
        return __('admin.nav.themes');
    }

    public function getTitle(): string
    {
        return __('admin.pages.themes_title');
    }

    public function mount(ThemeManager $themes, GeneralSettings $settings): void
    {
        $this->reload($themes, $settings);
    }

    public function activate(string $slug, ThemeManager $themes, GeneralSettings $settings): void
    {
        $themes->setActive($slug);
        Artisan::call('themes:publish', ['theme' => $slug]);
        $this->reload($themes, $settings);

        $report = $themes->slotReport($slug);
        $notification = Notification::make()->title(__('admin.pages.activate').'：'.$slug);

        if (($report['status'] ?? '') === 'full') {
            $notification->success()->send();

            return;
        }

        $notification
            ->warning()
            ->body(__('admin.messages.theme_slots_warn', [
                'label' => $report['label'] ?? __('admin.slots.status_undeclared'),
            ]))
            ->send();
    }

    protected function reload(ThemeManager $themes, GeneralSettings $settings): void
    {
        $this->activeTheme = $settings->active_theme ?: 'default';
        $this->themes = $themes->discover()->map(function (array $theme) use ($themes) {
            $slug = (string) ($theme['slug'] ?? $theme['name'] ?? '');
            $titleKey = 'admin.themes.'.$slug.'.title';
            $descKey = 'admin.themes.'.$slug.'.description';
            $previewFile = base_path('themes/'.$slug.'/assets/preview.svg');
            $report = $theme['slot_report'] ?? $themes->slotReport($slug);

            return [
                'slug' => $slug,
                'title' => __($titleKey) !== $titleKey ? __($titleKey) : ($theme['title'] ?? $slug),
                'description' => __($descKey) !== $descKey ? __($descKey) : ($theme['description'] ?? ''),
                'version' => $theme['version'] ?? '1.0.0',
                'preview' => is_file($previewFile)
                    ? url('/themes/'.$slug.'/preview.svg').'?v='.filemtime($previewFile)
                    : null,
                'slots_status' => $report['status'] ?? 'undeclared',
                'slots_label' => $report['label'] ?? __('admin.slots.status_undeclared'),
                'slots_missing' => $report['missing_standard'] ?? [],
                'slots_declared_count' => count($report['declared'] ?? []),
            ];
        })->values()->all();
    }

    protected function getHeaderActions(): array
    {
        return [
            Action::make('refresh')
                ->label(__('admin.pages.themes_refresh'))
                ->action(fn (ThemeManager $themes, GeneralSettings $settings) => $this->reload($themes, $settings)),
            Action::make('publish')
                ->label(__('admin.pages.themes_publish'))
                ->action(function (): void {
                    Artisan::call('themes:publish');
                    Notification::make()->title(__('admin.pages.themes_publish'))->success()->send();
                }),
        ];
    }
}
