<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Blog\Support\ThemeInjector;
use App\Blog\Support\ThemeManager;
use App\Models\Setting;
use Filament\Actions\Action;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;

class ThemeInject extends Page
{
    use InteractsWithForms;

    protected static \UnitEnum|string|null $navigationGroup = '管理';

    protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-squares-plus';

    protected static ?string $navigationLabel = '主题注入';

    protected string $view = 'filament.pages.theme-inject';

    public array $data = [];

    public function mount(): void
    {
        $this->form->fill([
            'inject' => $this->normalizeBlocks(Setting::get('inject.blocks', [])),
            'theme_vars' => app(ThemeManager::class)->variables(),
        ]);
    }

    public function form(Schema $schema): Schema
    {
        $tabs = [];
        $i = 0;

        foreach (ThemeInjector::POINTS as $point => $label) {
            $tabs[] = Tab::make(($i + 1).'. '.$label)
                ->schema([
                    Repeater::make("inject.{$point}")
                        ->label('注入块（可多条，拖拽排序，按顺序渲染）')
                        ->schema([
                            TextInput::make('title')->label('名称')->placeholder('如：百度统计')->columnSpan(2),
                            Textarea::make('html')->label('内容（HTML）')->rows(3)->columnSpanFull(),
                            Toggle::make('enabled')->label('启用')->default(true),
                        ])
                        ->columns(3)
                        ->defaultItems(0)
                        ->collapsible()
                        ->reorderable()
                        ->reorderableWithButtons()
                        ->addActionLabel('添加一条'),
                ]);
            $i++;
        }

        $tabs[] = Tab::make('主题变量（stylevar）')
            ->schema([
                KeyValue::make('theme_vars')
                    ->label('当前主题变量：视图用 {{ theme(\'var\', \'key\') }} 引用')
                    ->keyLabel('变量名')
                    ->valueLabel('内容（HTML）')
                    ->reorderable()
                    ->columnSpanFull(),
            ]);

        return $schema
            ->components([
                Tabs::make('inject-tabs')
                    ->tabs($tabs),
            ])
            ->statePath('data');
    }

    public function save(): void
    {
        $data = $this->form->getState();

        $blocks = [];
        foreach ($data['inject'] ?? [] as $point => $items) {
            $order = 0;
            foreach ($items ?? [] as $item) {
                if (trim((string) ($item['html'] ?? '')) === '') {
                    continue;
                }
                $blocks[] = [
                    'point' => $point,
                    'title' => $item['title'] ?? '',
                    'html' => $item['html'],
                    'sort' => $order++,
                    'enabled' => (bool) ($item['enabled'] ?? true),
                ];
            }
        }

        Setting::set('inject.blocks', $blocks);
        Setting::set('theme_vars_'.app(ThemeManager::class)->active(), $data['theme_vars'] ?? []);

        Notification::make()->title('注入内容已保存')->success()->send();
    }

    protected function getFormActions(): array
    {
        return [
            Action::make('save')->label('保存')->submit('save'),
        ];
    }

    private function normalizeBlocks(mixed $blocks): array
    {
        if (! is_array($blocks)) {
            $blocks = json_decode((string) $blocks, true) ?: [];
        }

        $normalized = [];
        foreach ($blocks as $b) {
            $point = $b['point'] ?? null;
            if (! $point) {
                continue;
            }
            $normalized[$point][] = [
                'title' => $b['title'] ?? '',
                'html' => $b['html'] ?? '',
                'sort' => (int) ($b['sort'] ?? 0),
                'enabled' => (bool) ($b['enabled'] ?? true),
            ];
        }

        return $normalized;
    }
}
