<?php

namespace App\Filament\Resources;

use App\Filament\Resources\Concerns\HasModulePermissions;
use App\Filament\Resources\Concerns\HasStandardTableFeatures;
use App\Filament\Resources\SubCategoryResource\Pages\CreateSubCategory;
use App\Filament\Resources\SubCategoryResource\Pages\EditSubCategory;
use App\Filament\Resources\SubCategoryResource\Pages\ListSubCategories;
use App\Filament\Support\RelationSelect;
use App\Models\Catalog\SubCategory;
use App\Services\AuditLog;
use App\Support\SortCodeGenerator;
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\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table;
use Illuminate\Validation\Rules\Unique;

/**
 * Ported from App\Http\Controllers\Isms\SubCategoryController
 * (docs/migration-plan.md Phase 2). The main_category_id field is the
 * canonical example of the ease-of-use pattern requested for the whole
 * migration going forward: searchable relationship select with an inline
 * "+ create" action (App\Filament\Support\RelationSelect, built on
 * Filament's native Select::relationship()->createOptionForm()), gated by
 * the SAME isms_main_categories.create permission the standalone
 * MainCategoryResource create page checks — a user who can't create a main
 * category from its own page can't sneak one in from here either.
 */
class SubCategoryResource extends Resource
{
    use HasModulePermissions;
    use HasStandardTableFeatures;

    protected static ?string $model = SubCategory::class;

    protected static string $permissionModuleKey = 'isms_sub_categories';

    protected static string|\BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleGroup;

    protected static string|\UnitEnum|null $navigationGroup = 'Master Data';

    protected static ?string $navigationLabel = 'Sub Categories';

    protected static ?int $navigationSort = 20;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            Section::make()->schema([
                RelationSelect::make(
                    name: 'main_category_id',
                    relationship: 'mainCategory',
                    titleAttribute: 'name',
                    createForm: [
                        TextInput::make('name')->required()->maxLength(100)->unique('main_categories', 'name'),
                        Textarea::make('description')->maxLength(500),
                        Toggle::make('is_active')->default(true),
                    ],
                    createPermission: 'isms_main_categories.create',
                    // Matches the source app: only active parents are offered
                    // (the edit form additionally keeps the record's current
                    // parent selectable even if it's since been deactivated).
                    modifyQueryUsing: fn ($query, $record) => $query
                        ->where('is_active', true)
                        ->when($record?->main_category_id, fn ($q, $id) => $q->orWhere('id', $id)),
                )
                    ->label('Main Category')
                    ->required(),
                TextInput::make('name')
                    ->required()
                    ->maxLength(100)
                    ->unique(
                        table: 'sub_categories',
                        column: 'name',
                        ignoreRecord: true,
                        modifyRuleUsing: fn (Unique $rule, Get $get): Unique => $rule
                            ->where('main_category_id', $get('main_category_id'))
                            ->whereNull('deleted_at'),
                    ),
                RelationSelect::make(
                    name: 'default_base_unit_id',
                    relationship: 'defaultBaseUnit',
                    titleAttribute: 'name',
                    modifyQueryUsing: fn ($query) => $query->where('is_active', true),
                )
                    ->label('Default Base Unit')
                    ->helperText('Form pre-fill convenience only — never read by stock/pricing/conversion logic.'),
                Textarea::make('description')
                    ->maxLength(500)
                    ->columnSpanFull(),
                Toggle::make('is_active')
                    ->default(true),
            ]),
        ]);
    }

    public static function table(Table $table): Table
    {
        return static::standardTableDefaults($table)
            ->recordUrl(static::standardRecordUrl())
            ->emptyStateHeading('No sub categories yet')
            ->emptyStateDescription('Refine your main categories into sub categories.')
            ->columns([
                TextColumn::make('mainCategory.name')->label('Main Category')->searchable()->sortable(),
                TextColumn::make('name')->searchable()->sortable(),
                TextColumn::make('sort_code')->label('Code')->badge(),
                TextColumn::make('defaultBaseUnit.name')->label('Default Unit')->placeholder('—'),
                TextColumn::make('products_count')->label('Products')->counts('products'),
                IconColumn::make('is_active')->boolean()->label('Active'),
            ])
            ->filters([
                SelectFilter::make('main_category_id')
                    ->label('Main Category')
                    ->relationship('mainCategory', 'name'),
                TernaryFilter::make('is_active')->label('Active'),
            ])
            ->defaultSort('is_active', 'desc')
            ->recordActions([
                EditAction::make(),
                DeleteAction::make()
                    ->before(function (SubCategory $record, DeleteAction $action): void {
                        if ($record->products()->exists()) {
                            Notification::make()
                                ->title('Cannot delete: sub category has products.')
                                ->danger()
                                ->send();
                            $action->cancel();
                        }
                    })
                    ->after(fn (SubCategory $record) => AuditLog::record('sub_category.deleted', $record, [
                        'name' => $record->name,
                        'description' => 'Deleted sub category "'.$record->name.'".',
                    ])),
            ]);
    }

    public static function getPages(): array
    {
        return [
            'index' => ListSubCategories::route('/'),
            'create' => CreateSubCategory::route('/create'),
            'edit' => EditSubCategory::route('/{record}/edit'),
        ];
    }

    public static function generateSortCode(string $name): string
    {
        return SortCodeGenerator::generate(SubCategory::class, $name, 'SUB');
    }
}
