<?php

declare(strict_types=1);

namespace Builder\Core\Extensions\Resources\Languages;

use Builder\Core\Exceptions\DeletionDeniedException;
use Builder\Core\Foundation\Concerns\HasCommandPaletteSearch;
use Builder\Core\Foundation\Concerns\HasRevisions;
use Builder\Core\Foundation\Contracts\CommandPaletteSearchable;
use Builder\Core\Foundation\Definition\Field;
use Builder\Core\Foundation\Definition\FieldBuilder;
use Builder\Core\Foundation\Definition\Hook;
use Builder\Core\Foundation\Definition\Section;
use Builder\Core\Foundation\Resources\Resource;
use Builder\Core\Foundation\Tables\Column;
use Builder\Core\Models\Language;
use Illuminate\Database\Eloquent\Model;

final class LanguageResource extends Resource implements CommandPaletteSearchable
{
    use HasCommandPaletteSearch;
    use HasRevisions;

    public static function getSlug(): string
    {
        return 'languages';
    }

    public static function getLabel(): string
    {
        return (string) __('builder::builder.nav.languages');
    }

    /** @return class-string<Model> */
    public static function getModel(): string
    {
        /** @var class-string<Model> */
        return Language::class;
    }

    public function getPermission(): string
    {
        return 'read:languages';
    }

    /** @return list<string> */
    public function getPermissionSet(): array
    {
        return ['read:languages', 'create:languages', 'update:languages', 'delete:languages'];
    }

    public function fields(): FieldBuilder
    {
        return FieldBuilder::make()
            ->add(
                Section::make('general')
                    ->label((string) __('builder::builder.sections.general'))
                    ->priority(10)
                    ->tab('main')
                    ->fields([
                        Field::text('code')->label((string) __('builder::builder.fields.language_code')),
                        Field::text('name')->label((string) __('builder::builder.fields.name')),
                        Field::number('order')->label((string) __('builder::builder.fields.order')),
                        Field::toggle('is_active')->label((string) __('builder::builder.fields.active')),
                        Field::toggle('is_default')->label((string) __('builder::builder.fields.default')),
                    ]),
            );
    }

    /** @return list<Column> */
    public function columns(): array
    {
        return [
            Column::make('name')->label((string) __('builder::builder.fields.name'))->sortable()->searchable(),
            Column::make('code')->label((string) __('builder::builder.fields.language_code'))->sortable()->searchable(),
            Column::make('is_active')
                ->label((string) __('builder::builder.fields.active'))
                ->format(fn (mixed $value): string => $value ? 'active' : 'inactive')
                ->badge([
                    'active' => ['label' => (string) __('builder::builder.fields.yes'), 'color' => 'green'],
                    'inactive' => ['label' => (string) __('builder::builder.fields.no'), 'color' => 'gray'],
                ]),
            Column::make('is_default')
                ->label((string) __('builder::builder.fields.default'))
                ->format(fn (mixed $value): string => $value ? 'default' : '')
                ->badge([
                    'default' => ['label' => (string) __('builder::builder.fields.default'), 'color' => 'blue'],
                ]),
        ];
    }

    /** @return list<string> */
    public function searchable(): array
    {
        return ['code', 'name'];
    }

    /** @return array<string, mixed> */
    public function rules(string $action): array
    {
        return [
            'code' => ['required', 'string', 'max:10'],
            'name' => ['required', 'string', 'max:255'],
            'order' => ['nullable', 'integer', 'min:0'],
            'is_active' => ['boolean'],
            'is_default' => ['boolean'],
        ];
    }

    public function canDelete(mixed $record): void
    {
        if (Language::count() <= 1) {
            throw DeletionDeniedException::withReason((string) __('builder::builder.resources.cannot_delete_last_language'));
        }
    }

    /** @return list<Hook> */
    public function hooks(): array
    {
        return [
            /**
             * Enforce is_default exclusivity: when a language is set as default,
             * clear the flag from all other languages.
             */
            Hook::on('saved', function (mixed $record, array $data): void {
                if (! empty($data['is_default'])) {
                    Language::where('id', '!=', $record->id)->update(['is_default' => false]);
                }
            }),
        ];
    }
}
