<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Filament\Resources\DberpProducts\RelationManagers;

use App\Business\Product\ProductSpecGroupWriter;
use App\Filament\Resources\DberpProducts\DberpProductResource;
use App\Filament\Support\DberpProductSpecMatrixRebuildAction;
use App\Models\DberpProduct;
use App\Models\DberpProductSkuSpecValue;
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\Notifications\Notification;
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';

    private function ownerHasSpecCombos(): bool
    {
        $product = $this->getOwnerRecord();

        return $product instanceof DberpProduct && $product->skus()->exists();
    }

    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
            ->description(function (): string {
                if ($this->ownerHasSpecCombos()) {
                    return (string) __('dberp.hints.spec_groups_locked_after_combos');
                }

                return (string) __('dberp.hints.spec_groups_manage_before_combos');
            })
            ->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([
                DberpProductSpecMatrixRebuildAction::make(
                    fn (): ?DberpProduct => $this->getOwnerRecord() instanceof DberpProduct ? $this->getOwnerRecord() : null,
                    fn (): mixed => $this->redirect(DberpProductResource::getUrl('edit', ['record' => $this->getOwnerRecord()])),
                ),
                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'))
                    ->before(function (DeleteAction $action, DberpProductSpecGroup $record): void {
                        if (! DberpProductSkuSpecValue::query()->where('product_spec_group_id', $record->getKey())->exists()) {
                            return;
                        }

                        Notification::make()
                            ->title((string) __('dberp.notifications.operation_blocked'))
                            ->body((string) __('dberp.validation.product_spec_group_delete_blocked_in_use'))
                            ->danger()
                            ->send();

                        $action->halt();
                    }),
            ]);
    }
}
