<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpDictionaryTypes\RelationManagers;

use App\Models\DberpDictionaryItem;
use App\Models\DberpDictionaryType;
use App\Support\DberpDictionaryItemMaintenance;
use App\Support\DictionaryItemUsageChecker;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;

class ItemsRelationManager extends RelationManager
{
    protected static string $relationship = 'items';

    public static function getTitle(Model $ownerRecord, string $pageClass): string
    {
        return __('dberp.relations.dictionary_items');
    }

    protected static function getModelLabel(): ?string
    {
        return __('dberp.relations.dictionary_items');
    }

    protected static function getPluralModelLabel(): ?string
    {
        return __('dberp.relations.dictionary_items');
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make(__('dberp.relations.dictionary_items'))
                    ->description($this->getDictionaryItemsStrategyDescription())
                    ->schema([
                        TextInput::make('code')
                            ->label(__('dberp.fields.dict_item_code'))
                            ->required()
                            ->maxLength(64)
                            ->scopedUnique(
                                model: DberpDictionaryItem::class,
                                column: 'code',
                                ignoreRecord: true,
                                modifyQueryUsing: fn ($query) => $query->where('type_id', $this->getOwnerRecord()->getKey()),
                            )
                            ->disabled(fn (?DberpDictionaryItem $record): bool => $record !== null)
                            ->helperText(fn (?DberpDictionaryItem $record): ?string => $record !== null
                                ? (string) __('dberp.dictionary_item_control.item_code_immutable_after_create')
                                : null),
                        TextInput::make('label')
                            ->label(__('dberp.fields.dict_item_name'))
                            ->required()
                            ->maxLength(255),
                        TextInput::make('value')
                            ->label(__('dberp.fields.dict_item_value'))
                            ->maxLength(512),
                        TextInput::make('sort_order')
                            ->label(__('dberp.fields.sort_order'))
                            ->numeric()
                            ->default(0)
                            ->required(),
                        Toggle::make('is_enabled')
                            ->label(__('dberp.fields.is_enabled'))
                            ->default(true),
                        Textarea::make('description')
                            ->label(__('dberp.fields.dict_item_description'))
                            ->rows(2)
                            ->columnSpanFull(),
                    ])
                    ->columns(2),
            ]);
    }

    public function table(Table $table): Table
    {
        return $table
            ->recordTitleAttribute('label')
            ->defaultSort('sort_order', 'asc')
            ->columns([
                TextColumn::make('code')
                    ->label(__('dberp.fields.dict_item_code'))
                    ->searchable(),
                TextColumn::make('label')
                    ->label(__('dberp.fields.dict_item_name'))
                    ->searchable(),
                ToggleColumn::make('is_enabled')
                    ->label(__('dberp.fields.is_enabled')),
                IconColumn::make('is_system_preset')
                    ->label(__('dberp.fields.is_system_preset'))
                    ->boolean(),
                IconColumn::make('is_delete_locked')
                    ->label(__('dberp.fields.is_delete_locked'))
                    ->boolean(),
                TextColumn::make('sort_order')
                    ->label(__('dberp.fields.sort_order'))
                    ->numeric()
                    ->sortable(),
            ])
            ->filters([
                //
            ])
            ->headerActions([
                CreateAction::make()
                    ->visible(fn (): bool => DberpDictionaryItemMaintenance::isBusinessMaintainableForTypeCode($this->ownerTypeCode()))
                    ->mutateFormDataUsing(function (array $data): array {
                        return array_merge($data, [
                            'is_system_preset' => false,
                            'is_delete_locked' => false,
                        ]);
                    }),
            ])
            ->recordActions([
                EditAction::make(),
                DeleteAction::make()
                    ->visible(fn (DberpDictionaryItem $record): bool => DberpDictionaryItemMaintenance::isBusinessMaintainableForTypeCode($this->ownerTypeCode())
                        && app(DictionaryItemUsageChecker::class)->canDelete($record))
                    ->requiresConfirmation()
                    ->modalDescription(__('dberp.dictionary_item_control.delete_confirm')),
            ]);
    }

    private function ownerTypeCode(): string
    {
        /** @var DberpDictionaryType $owner */
        $owner = $this->getOwnerRecord();

        return (string) $owner->getAttribute('code');
    }

    private function getDictionaryItemsStrategyDescription(): string
    {
        $base = '';
        if (DberpDictionaryItemMaintenance::isSystemFixedForTypeCode($this->ownerTypeCode())) {
            $base = (string) __('dberp.dictionary_item_control.section_intro_system_fixed');
        } else {
            $base = (string) __('dberp.dictionary_item_control.section_intro_business_maintainable');
        }

        return $base.' '.(string) __('dberp.messages.save_dictionary_type_first_then_manage_items');
    }
}
