<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpProducts\RelationManagers;

use App\Business\Product\ProductSpecGroupWriter;
use App\Models\DberpProduct;
use App\Models\DberpProductSpecGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;

class ProductSpecGroupsRelationManager extends RelationManager
{
    protected static string $relationship = 'specGroups';

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

    public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
    {
        return $ownerRecord instanceof DberpProduct && $ownerRecord->spec_enabled;
    }

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

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

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('name')
                    ->label(__('dberp.fields.spec_group_name'))
                    ->required()
                    ->maxLength(120),
                TextInput::make('sort_order')
                    ->label(__('dberp.fields.sort_order'))
                    ->numeric()
                    ->default(0)
                    ->required(),
                Repeater::make('spec_value_rows')
                    ->label(__('dberp.fields.spec_value_rows'))
                    ->minItems(1)
                    ->defaultItems(1)
                    ->schema([
                        TextInput::make('id')
                            ->hidden()
                            ->numeric(),
                        TextInput::make('value_label')
                            ->label(__('dberp.fields.spec_value_label'))
                            ->required()
                            ->maxLength(160),
                        TextInput::make('sort_order')
                            ->label(__('dberp.fields.sort_order'))
                            ->numeric()
                            ->default(0)
                            ->required(),
                    ])
                    ->columns(3)
                    ->columnSpanFull(),
            ]);
    }

    public function table(Table $table): Table
    {
        return $table
            ->recordTitleAttribute('name')
            ->defaultSort('sort_order', 'asc')
            ->columns([
                TextColumn::make('name')
                    ->label(__('dberp.fields.spec_group_name'))
                    ->searchable(),
                TextColumn::make('spec_values_count')
                    ->label(__('dberp.fields.spec_value_count'))
                    ->counts('specValues'),
                TextColumn::make('sort_order')
                    ->label(__('dberp.fields.sort_order'))
                    ->sortable(),
            ])
            ->headerActions([
                CreateAction::make()
                    ->using(function (array $data): DberpProductSpecGroup {
                        return app(ProductSpecGroupWriter::class)->createGroupWithValues($this->getOwnerRecord(), $data);
                    }),
            ])
            ->recordActions([
                EditAction::make()
                    ->mutateRecordDataUsing(function (array $data): array {
                        $group = DberpProductSpecGroup::query()->find($data['id'] ?? null);
                        if ($group === null) {
                            return $data;
                        }
                        $data['spec_value_rows'] = $group->specValues()
                            ->orderBy('sort_order')
                            ->orderBy('id')
                            ->get(['id', 'value_label', 'sort_order'])
                            ->map(fn (Model $v): array => [
                                'id' => $v->getKey(),
                                'value_label' => $v->getAttribute('value_label'),
                                'sort_order' => $v->getAttribute('sort_order'),
                            ])
                            ->values()
                            ->all();

                        return $data;
                    })
                    ->using(function (array $data, Model $record): void {
                        app(ProductSpecGroupWriter::class)->updateGroupWithValues(
                            DberpProductSpecGroup::query()->findOrFail($record->getKey()),
                            $data,
                        );
                    }),
                DeleteAction::make()
                    ->modalHeading(__('dberp.headings.delete_spec_group')),
            ]);
    }
}
