<?php

declare(strict_types=1);

namespace Builder\Seo\Settings;

use Builder\Core\Foundation\Definition\Field;
use Builder\Core\Foundation\Definition\FieldBuilder;
use Builder\Core\Foundation\Definition\Section;
use Builder\Core\Foundation\Enums\Icon;
use Builder\Core\Foundation\Settings\BuilderSettings;
use Builder\Core\Support\Module;

/**
 * Global SEO settings: site name, title separator, default OG image,
 * and Schema.org / structured data configuration.
 */
final class SeoSettings extends BuilderSettings
{
    public ?string $site_name = null;

    public ?string $tagline = null;

    public ?string $separator = '|';

    public ?string $favicon_url = null;

    public ?string $default_og_image_url = null;

    public string $schema_type = 'Organization';

    public ?string $schema_name = null;

    public ?string $schema_url = null;

    public ?string $schema_logo_url = null;

    public ?string $schema_description = null;

    public static function group(): string
    {
        return 'seo';
    }

    public function getLabel(): string
    {
        return (string) __('seo::seo.settings.label');
    }

    public function getIcon(): string
    {
        return Icon::Search->value;
    }

    public function getPriority(): int
    {
        return 30;
    }

    public function navGroup(): string
    {
        return '';
    }

    /** @return array<string, mixed> */
    public function settingsToArray(): array
    {
        $data = parent::settingsToArray();

        if (empty($data['site_name'])) {
            $data['site_name'] = (string) config('app.name', '');
        }

        if (empty($data['schema_url'])) {
            $data['schema_url'] = (string) config('app.url', '');
        }

        return $data;
    }

    public function seedDefaults(): void
    {
        parent::seedDefaults();

        app()->forgetInstance(self::class);
        $fresh = app(self::class);

        $dirty = false;

        if (empty($fresh->site_name)) {
            $fresh->site_name = (string) config('app.name', '');
            $dirty = true;
        }

        if (empty($fresh->schema_url)) {
            $fresh->schema_url = (string) config('app.url', '');
            $dirty = true;
        }

        if ($dirty) {
            $fresh->save();
            app()->forgetInstance(self::class);
        }
    }

    public function fields(): FieldBuilder
    {
        $imageField = Module::has('media')
            ? fn (string $name): Field => Field::make($name)->component('FieldMediaUrlInput')
            : fn (string $name): Field => Field::url($name);

        return FieldBuilder::make()
            ->add(
                Section::make('general')
                    ->label((string) __('seo::seo.section.general'))
                    ->priority(10)
                    ->fields([
                        Field::text('site_name')
                            ->label((string) __('seo::seo.fields.site_name'))
                            ->hint((string) __('seo::seo.hints.site_name')),

                        Field::text('tagline')
                            ->label((string) __('seo::seo.fields.tagline')),

                        Field::select('separator')
                            ->label((string) __('seo::seo.fields.separator'))
                            ->hint((string) __('seo::seo.hints.separator'))
                            ->options([
                                '|' => '|',
                                '-' => '-',
                                '·' => '·',
                                '–' => '–',
                                '—' => '—',
                            ]),

                        $imageField('favicon_url')
                            ->label((string) __('seo::seo.fields.favicon_url')),

                        $imageField('default_og_image_url')
                            ->label((string) __('seo::seo.fields.default_og_image_url')),
                    ]),

                Section::make('schema')
                    ->label((string) __('seo::seo.section.schema'))
                    ->priority(20)
                    ->fields([
                        Field::select('schema_type')
                            ->label((string) __('seo::seo.fields.schema_type'))
                            ->options([
                                'Organization' => (string) __('seo::seo.schema_types.Organization'),
                                'Person' => (string) __('seo::seo.schema_types.Person'),
                                'LocalBusiness' => (string) __('seo::seo.schema_types.LocalBusiness'),
                                'WebSite' => (string) __('seo::seo.schema_types.WebSite'),
                            ]),

                        Field::text('schema_name')
                            ->label((string) __('seo::seo.fields.schema_name')),

                        Field::url('schema_url')
                            ->label((string) __('seo::seo.fields.schema_url')),

                        $imageField('schema_logo_url')
                            ->label((string) __('seo::seo.fields.schema_logo_url')),

                        Field::textarea('schema_description')
                            ->label((string) __('seo::seo.fields.schema_description')),
                    ]),
            );
    }

    /** @return array<string, mixed> */
    public function rules(): array
    {
        return [
            'site_name' => ['nullable', 'string', 'max:255'],
            'tagline' => ['nullable', 'string', 'max:255'],
            'separator' => ['nullable', 'string', 'max:5', 'in:|,-,·,–,—'],
            'favicon_url' => ['nullable', 'url', 'max:2048'],
            'default_og_image_url' => ['nullable', 'url', 'max:2048'],
            'schema_type' => ['required', 'string', 'in:Organization,Person,LocalBusiness,WebSite'],
            'schema_name' => ['nullable', 'string', 'max:255'],
            'schema_url' => ['nullable', 'url', 'max:2048'],
            'schema_logo_url' => ['nullable', 'url', 'max:2048'],
            'schema_description' => ['nullable', 'string', 'max:1000'],
        ];
    }
}
