<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Domain\Blog\ContentFormat;
use App\Domain\Theme\ThemeSlot;
use App\Settings\AiSettings;
use App\Settings\BlogSettings;
use App\Settings\CommentSettings;
use App\Settings\GeneralSettings;
use App\Settings\SeoSettings;
use App\Settings\SnippetSettings;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\EmbeddedSchema;
use Filament\Schemas\Components\Form;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;

/**
 * @property-read Schema $form
 */
class SiteSettings extends Page
{
    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCog6Tooth;

    protected static ?int $navigationSort = 85;

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

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

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

    /** @var array<string, mixed>|null */
    public ?array $data = [];

    public function mount(
        GeneralSettings $general,
        SeoSettings $seo,
        AiSettings $ai,
        BlogSettings $blog,
        CommentSettings $comment,
        SnippetSettings $snippets,
    ): void {
        $this->form->fill([
            'site_name' => $general->site_name,
            'site_url' => $general->site_url,
            'site_description' => $general->site_description,
            'active_theme' => $general->active_theme,
            'attachments_url_prefix' => $general->attachments_url_prefix,
            'default_content_format' => $general->default_content_format,
            'import_content_format' => $general->import_content_format,
            'import_convert_html_to_markdown' => $general->import_convert_html_to_markdown,
            'posts_per_page' => $blog->posts_per_page,
            'allow_comments' => $blog->allow_comments,
            'comment_order' => $blog->comment_order,
            'show_views' => $blog->show_views,
            'show_author' => $blog->show_author,
            'date_format' => $blog->date_format,
            'close_comments_on_old_posts' => $blog->close_comments_on_old_posts,
            'close_comments_days' => $blog->close_comments_days,
            'guest_can_comment' => $comment->guest_can_comment,
            'require_moderation' => $comment->require_moderation,
            'rate_limit_per_minute' => $comment->rate_limit_per_minute,
            'enable_website_field' => $comment->enable_website_field,
            'forbidden_words' => $comment->forbidden_words,
            'meta_title_suffix' => $seo->meta_title_suffix,
            'default_description' => $seo->default_description,
            'default_keywords' => $seo->default_keywords,
            'json_ld_enabled' => $seo->json_ld_enabled,
            'robots_index' => $seo->robots_index,
            'twitter_site' => $seo->twitter_site,
            'canonical_force_https' => $seo->canonical_force_https,
            'ai_provider' => $ai->provider,
            'ai_api_base_url' => $ai->api_base_url,
            'ai_api_key' => $ai->api_key,
            'ai_model' => $ai->model,
            'comment_moderation_enabled' => $ai->comment_moderation_enabled,
            'content_optimization_enabled' => $ai->content_optimization_enabled,
            'analytics_head' => $snippets->analytics_head,
            'body_end' => $snippets->body_end,
            'ads_sidebar' => $snippets->ads_sidebar,
            'ads_article_top' => $snippets->ads_article_top,
            'ads_article_bottom' => $snippets->ads_article_bottom,
            'header_banner' => $snippets->header_banner,
            'custom_links_html' => $snippets->custom_links_html,
            'footer_html' => $snippets->footer_html,
        ]);
    }

    public function defaultForm(Schema $schema): Schema
    {
        return $schema->statePath('data');
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Tabs::make('settings')
                    ->persistTabInQueryString()
                    ->columnSpanFull()
                    ->tabs([
                        Tab::make(__('admin.settings.tabs.site'))
                            ->icon(Heroicon::OutlinedGlobeAlt)
                            ->schema([
                                TextInput::make('site_name')->label(__('admin.settings.site_name'))->required(),
                                TextInput::make('site_url')->label(__('admin.settings.site_url'))->required()->url(),
                                Textarea::make('site_description')->label(__('admin.settings.site_description'))->rows(3),
                                TextInput::make('active_theme')->label(__('admin.settings.active_theme'))->required(),
                                TextInput::make('attachments_url_prefix')->label(__('admin.settings.attachments_url_prefix'))->required(),
                                Select::make('default_content_format')
                                    ->label(__('admin.settings.default_content_format'))
                                    ->options([
                                        ContentFormat::MARKDOWN => __('admin.options.markdown'),
                                        ContentFormat::HTML => __('admin.options.html'),
                                    ])->required(),
                                Select::make('import_content_format')
                                    ->label(__('admin.settings.import_content_format'))
                                    ->options([
                                        ContentFormat::HTML => __('admin.options.html'),
                                        ContentFormat::MARKDOWN => __('admin.options.markdown'),
                                    ])->required(),
                                Toggle::make('import_convert_html_to_markdown')
                                    ->label(__('admin.settings.import_convert_html_to_markdown')),
                            ]),
                        Tab::make(__('admin.settings.tabs.reading'))
                            ->icon(Heroicon::OutlinedNewspaper)
                            ->schema([
                                TextInput::make('posts_per_page')->label(__('admin.settings.posts_per_page'))->numeric()->required()->minValue(1)->maxValue(100),
                                TextInput::make('date_format')->label(__('admin.settings.date_format'))->required(),
                                Toggle::make('show_views')->label(__('admin.settings.show_views')),
                                Toggle::make('show_author')->label(__('admin.settings.show_author')),
                                Toggle::make('allow_comments')->label(__('admin.settings.allow_comments')),
                                Select::make('comment_order')
                                    ->label(__('admin.settings.comment_order'))
                                    ->options([
                                        'asc' => __('admin.options.comment_order_asc'),
                                        'desc' => __('admin.options.comment_order_desc'),
                                    ])
                                    ->required(),
                                Toggle::make('close_comments_on_old_posts')->label(__('admin.settings.close_comments_on_old_posts')),
                                TextInput::make('close_comments_days')->label(__('admin.settings.close_comments_days'))->numeric()->minValue(1),
                            ]),
                        Tab::make(__('admin.settings.tabs.comments'))
                            ->icon(Heroicon::OutlinedChatBubbleLeftRight)
                            ->schema([
                                Toggle::make('guest_can_comment')->label(__('admin.settings.guest_can_comment')),
                                Toggle::make('require_moderation')->label(__('admin.settings.require_moderation')),
                                TextInput::make('rate_limit_per_minute')->label(__('admin.settings.rate_limit_per_minute'))->numeric()->minValue(1),
                                Toggle::make('enable_website_field')->label(__('admin.settings.enable_website_field')),
                                Textarea::make('forbidden_words')->label(__('admin.settings.forbidden_words'))->rows(3),
                            ]),
                        Tab::make(__('admin.settings.tabs.seo'))
                            ->icon(Heroicon::OutlinedMagnifyingGlass)
                            ->schema([
                                TextInput::make('meta_title_suffix')->label(__('admin.settings.meta_title_suffix')),
                                Textarea::make('default_description')->label(__('admin.settings.default_description'))->rows(3),
                                TextInput::make('default_keywords')->label(__('admin.settings.default_keywords')),
                                Toggle::make('json_ld_enabled')->label(__('admin.settings.json_ld_enabled')),
                                Toggle::make('robots_index')->label(__('admin.settings.robots_index')),
                                TextInput::make('twitter_site')->label(__('admin.settings.twitter_site')),
                                Toggle::make('canonical_force_https')->label(__('admin.settings.canonical_force_https')),
                            ]),
                        Tab::make(__('admin.settings.tabs.storage'))
                            ->icon(Heroicon::OutlinedCloudArrowUp)
                            ->schema([
                                TextInput::make('attachments_url_prefix')
                                    ->label(__('admin.settings.attachments_legacy_prefix'))
                                    ->helperText(__('admin.helpers.attachments_prefix'))
                                    ->required(),
                            ]),
                        Tab::make(__('admin.settings.tabs.ai'))
                            ->icon(Heroicon::OutlinedSparkles)
                            ->schema([
                                Select::make('ai_provider')->label(__('admin.settings.ai_provider'))->options([
                                    'stub' => __('admin.options.ai_provider_stub'),
                                    'openai_compatible' => __('admin.options.ai_provider_openai'),
                                ])->required(),
                                TextInput::make('ai_api_base_url')->label(__('admin.settings.ai_api_base_url')),
                                TextInput::make('ai_api_key')->label(__('admin.settings.ai_api_key'))->password()->revealable(),
                                TextInput::make('ai_model')->label(__('admin.settings.ai_model')),
                                Toggle::make('comment_moderation_enabled')->label(__('admin.settings.comment_moderation_enabled')),
                                Toggle::make('content_optimization_enabled')->label(__('admin.settings.content_optimization_enabled')),
                            ]),
                        Tab::make(__('admin.settings.tabs.snippets'))
                            ->icon(Heroicon::OutlinedCodeBracket)
                            ->schema([
                                Section::make(__('admin.settings.snippet_groups.analytics'))
                                    ->description(__('admin.settings.snippet_groups.analytics_help'))
                                    ->icon(Heroicon::OutlinedChartBar)
                                    ->collapsible()
                                    ->schema([
                                        Textarea::make('analytics_head')
                                            ->label(__('admin.settings.analytics_head'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::HEAD).' '.__('admin.helpers.analytics_extra'))
                                            ->rows(5)
                                            ->columnSpanFull(),
                                        Textarea::make('body_end')
                                            ->label(__('admin.settings.body_end'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::BODY_END))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                    ]),
                                Section::make(__('admin.settings.snippet_groups.ads'))
                                    ->description(__('admin.settings.snippet_groups.ads_help'))
                                    ->icon(Heroicon::OutlinedMegaphone)
                                    ->collapsed()
                                    ->schema([
                                        Textarea::make('header_banner')
                                            ->label(__('admin.settings.header_banner'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::HEADER_AFTER))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                        Textarea::make('ads_sidebar')
                                            ->label(__('admin.settings.ads_sidebar'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::SIDEBAR).' '.__('admin.helpers.ads_sidebar_extra'))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                        Textarea::make('ads_article_top')
                                            ->label(__('admin.settings.ads_article_top'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::ARTICLE_TOP))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                        Textarea::make('ads_article_bottom')
                                            ->label(__('admin.settings.ads_article_bottom'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::ARTICLE_BOTTOM))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                    ]),
                                Section::make(__('admin.settings.snippet_groups.misc'))
                                    ->description(__('admin.settings.snippet_groups.misc_help'))
                                    ->icon(Heroicon::OutlinedLink)
                                    ->collapsed()
                                    ->schema([
                                        Textarea::make('custom_links_html')
                                            ->label(__('admin.settings.custom_links_html'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::SIDEBAR_AFTER))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                        Textarea::make('footer_html')
                                            ->label(__('admin.settings.footer_html'))
                                            ->helperText(ThemeSlot::hint(ThemeSlot::FOOTER_BEFORE))
                                            ->rows(3)
                                            ->columnSpanFull(),
                                    ]),
                            ]),
                    ]),
            ]);
    }

    public function content(Schema $schema): Schema
    {
        return $schema->components([
            Form::make([EmbeddedSchema::make('form')])
                ->id('form')
                ->livewireSubmitHandler('save')
                ->footer([
                    Actions::make([
                        Action::make('save')
                            ->label(__('admin.actions.save'))
                            ->submit('save'),
                    ]),
                ]),
        ]);
    }

    public function save(
        GeneralSettings $general,
        SeoSettings $seo,
        AiSettings $ai,
        BlogSettings $blog,
        CommentSettings $comment,
        SnippetSettings $snippets,
    ): void {
        $data = $this->form->getState();

        $general->site_name = $data['site_name'];
        $general->site_url = $data['site_url'];
        $general->site_description = $data['site_description'] ?? null;
        $general->active_theme = $data['active_theme'];
        $general->attachments_url_prefix = $data['attachments_url_prefix'];
        $general->default_content_format = $data['default_content_format'];
        $general->import_content_format = $data['import_content_format'];
        $general->import_convert_html_to_markdown = (bool) $data['import_convert_html_to_markdown'];
        $general->save();
        config(['larablog.attachments_url_prefix' => $general->attachments_url_prefix]);

        $blog->posts_per_page = (int) $data['posts_per_page'];
        $blog->allow_comments = (bool) $data['allow_comments'];
        $blog->comment_order = $data['comment_order'];
        $blog->show_views = (bool) $data['show_views'];
        $blog->show_author = (bool) $data['show_author'];
        $blog->date_format = $data['date_format'];
        $blog->close_comments_on_old_posts = (bool) $data['close_comments_on_old_posts'];
        $blog->close_comments_days = (int) $data['close_comments_days'];
        $blog->save();

        $comment->guest_can_comment = (bool) $data['guest_can_comment'];
        $comment->require_moderation = (bool) $data['require_moderation'];
        $comment->rate_limit_per_minute = (int) $data['rate_limit_per_minute'];
        $comment->enable_website_field = (bool) $data['enable_website_field'];
        $comment->forbidden_words = (string) ($data['forbidden_words'] ?? '');
        $comment->save();

        $seo->meta_title_suffix = $data['meta_title_suffix'] ?? null;
        $seo->default_description = $data['default_description'] ?? null;
        $seo->default_keywords = $data['default_keywords'] ?? null;
        $seo->json_ld_enabled = (bool) $data['json_ld_enabled'];
        $seo->robots_index = (bool) $data['robots_index'];
        $seo->twitter_site = $data['twitter_site'] ?? null;
        $seo->canonical_force_https = (bool) $data['canonical_force_https'];
        $seo->save();

        $ai->provider = $data['ai_provider'];
        $ai->api_base_url = $data['ai_api_base_url'] ?? null;
        $ai->api_key = $data['ai_api_key'] ?? null;
        $ai->model = $data['ai_model'] ?? null;
        $ai->comment_moderation_enabled = (bool) $data['comment_moderation_enabled'];
        $ai->content_optimization_enabled = (bool) $data['content_optimization_enabled'];
        $ai->save();

        $snippets->analytics_head = (string) ($data['analytics_head'] ?? '');
        $snippets->body_end = (string) ($data['body_end'] ?? '');
        $snippets->ads_sidebar = (string) ($data['ads_sidebar'] ?? '');
        $snippets->ads_article_top = (string) ($data['ads_article_top'] ?? '');
        $snippets->ads_article_bottom = (string) ($data['ads_article_bottom'] ?? '');
        $snippets->header_banner = (string) ($data['header_banner'] ?? '');
        $snippets->custom_links_html = (string) ($data['custom_links_html'] ?? '');
        $snippets->footer_html = (string) ($data['footer_html'] ?? '');
        $snippets->save();

        Notification::make()->title(__('admin.messages.settings_saved'))->success()->send();
    }
}
