<?php

namespace App\Filament\Resources;

use App\Filament\Resources\Concerns\HasModulePermissions;
use App\Filament\Resources\Concerns\HasStandardTableFeatures;
use App\Filament\Resources\DealResource\Pages\CreateDeal;
use App\Filament\Resources\DealResource\Pages\EditDeal;
use App\Filament\Resources\DealResource\Pages\ListDeals;
use App\Filament\Support\ProductSelect;
use App\Filament\Support\RelationSelect;
use App\Models\Lookups\DiscountType;
use App\Models\Promotions\Deal;
use App\Services\AuditLog;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
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\TernaryFilter;
use Filament\Tables\Table;

/**
 * Item-level promotional engine (new feature — the source Inertia app has no
 * deals; see docs/migration-plan.md Decisions Log). While a deal is active,
 * every sale of its target products gets an automatic per-line discount,
 * evaluated authoritatively in InvoiceService::create() via DealService.
 *
 * Schedule follows the ProductBundle convention: starts_at/ends_at are
 * optional day-level bounds (blank = open-ended), inclusive on both ends,
 * and ends_at must be on/after starts_at.
 */
class DealResource extends Resource
{
    use HasModulePermissions;
    use HasStandardTableFeatures;

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

    protected static string $permissionModuleKey = 'isms_deals';

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

    protected static string|\UnitEnum|null $navigationGroup = 'Promotions & Loyalty';

    protected static ?string $navigationLabel = 'Deals';

    protected static ?int $navigationSort = 40;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            Section::make('Details')->schema([
                TextInput::make('name')->required()->maxLength(150)->columnSpanFull(),
                RelationSelect::standalone(
                    name: 'discount_type_id',
                    modelClass: DiscountType::class,
                    titleAttribute: 'name',
                )
                    ->label('Discount type')
                    ->required()
                    ->live(),
                TextInput::make('discount_value')
                    ->label('Discount')
                    ->required()->numeric()->minValue(0)
                    ->suffix(fn (Get $get): ?string => $get('discount_type_id')
                        ? (DiscountType::find((int) $get('discount_type_id'))?->code === DiscountType::PERCENTAGE ? '%' : null)
                        : null)
                    ->helperText(fn (Get $get): string => $get('discount_type_id') && DiscountType::find((int) $get('discount_type_id'))?->code === DiscountType::FIXED
                        ? 'Fixed amount off per unit sold (applied to each unit of the quantity).'
                        : 'Percentage off the line total.'),
                Toggle::make('is_active')->default(true),
                DatePicker::make('starts_at'),
                DatePicker::make('ends_at')
                    ->rule(function (Get $get) {
                        return function (string $attribute, $value, \Closure $fail) use ($get): void {
                            if (blank($value) || blank($get('starts_at'))) {
                                return;
                            }
                            if ($value < $get('starts_at')) {
                                $fail('End date must be on or after the start date.');
                            }
                        };
                    }),
                Textarea::make('description')->maxLength(1000)->columnSpanFull(),
            ])->columns(3),

            Section::make('Target Products')->schema([
                Select::make('products')
                    ->relationship('products', 'name')
                    ->multiple()
                    ->searchable(ProductSelect::searchColumns())
                    ->preload()
                    ->label('Products this deal applies to')
                    ->helperText('Every sale of a selected product gets the deal discount while the deal is active.')
                    ->columnSpanFull(),
            ]),
        ]);
    }

    public static function table(Table $table): Table
    {
        return static::standardTableDefaults($table)
            ->recordUrl(static::standardRecordUrl())
            ->emptyStateHeading('No deals yet')
            ->emptyStateDescription('Start a promotion to fill this board.')
            ->columns([
                TextColumn::make('name')->searchable()->sortable(),
                TextColumn::make('discountType.name')->label('Discount type')->placeholder('—'),
                TextColumn::make('discount_value')->label('Discount'),
                TextColumn::make('starts_at')->date()->placeholder('—'),
                TextColumn::make('ends_at')->date()->placeholder('—'),
                TextColumn::make('products_count')->label('Products')->counts('products'),
                IconColumn::make('is_active')->boolean()->label('Active'),
            ])
            ->filters([
                TernaryFilter::make('is_active')->label('Active'),
            ])
            ->defaultSort('name')
            ->recordActions([
                EditAction::make(),
                DeleteAction::make()
                    ->after(fn (Deal $record) => AuditLog::record('deal.deleted', $record, [
                        'name' => $record->name,
                    ])),
            ]);
    }

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