<?php

namespace App\Filament\Resources;

use App\Filament\Resources\CartDiscountResource\Pages\CreateCartDiscount;
use App\Filament\Resources\CartDiscountResource\Pages\EditCartDiscount;
use App\Filament\Resources\CartDiscountResource\Pages\ListCartDiscounts;
use App\Filament\Resources\Concerns\HasModulePermissions;
use App\Filament\Resources\Concerns\HasStandardTableFeatures;
use App\Filament\Support\RelationSelect;
use App\Models\Lookups\DiscountType;
use App\Models\Promotions\CartDiscount;
use App\Services\AuditLog;
use App\Services\CurrentContext;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\DatePicker;
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;

/**
 * Order-level promotional engine ("Cart Discounts" / spend-and-save — a new
 * feature; the source Inertia app has no cart-value rules). While a rule is
 * live, any checkout whose cart value (net subtotal + VAT — the same
 * eligible base vouchers use) meets `min_cart_value` automatically gets the
 * rule's discount: a percentage of the cart, or a flat amount, capped at
 * `max_discount_amount` when set. Evaluated authoritatively in
 * InvoiceService::create() via CartDiscountService — the client previews
 * from the same server lookup and can no more smuggle a rule discount than
 * it can smuggle a price.
 *
 * When several rules are live, the highest threshold the cart clears wins
 * (ties → lowest id), see CartDiscountService::bestRule().
 *
 * Schedule follows the ProductBundle/Deal 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 CartDiscountResource extends Resource
{
    use HasModulePermissions;
    use HasStandardTableFeatures;

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

    protected static string $permissionModuleKey = 'isms_cart_discounts';

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

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

    protected static ?string $navigationLabel = 'Cart Discounts';

    protected static ?int $navigationSort = 35;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            Section::make('Details')->schema([
                TextInput::make('name')->required()->maxLength(150)->columnSpanFull(),
                TextInput::make('min_cart_value')
                    ->label('Minimum cart value')
                    ->required()->numeric()->minValue(0)->prefix('Rs.')
                    ->helperText('The cart must reach at least this much (net subtotal + VAT) before the discount applies.')
                    ->columnSpan(1),
                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::PERCENTAGE
                        ? 'Percentage taken off the whole cart value.'
                        : 'Flat amount taken off the whole cart (not per unit).'),
                TextInput::make('max_discount_amount')
                    ->label('Maximum discount')
                    ->numeric()->minValue(0)->prefix('Rs.')
                    ->helperText('Optional ceiling — a percentage rule never takes more than this off a cart.')
                    ->placeholder('No limit'),
                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),
        ]);
    }

    public static function table(Table $table): Table
    {
        return static::standardTableDefaults($table)
            ->recordUrl(static::standardRecordUrl())
            ->emptyStateHeading('No cart discounts yet')
            ->emptyStateDescription('A rule that discounts the whole basket will appear here.')
            ->columns([
                TextColumn::make('name')->searchable()->sortable(),
                TextColumn::make('min_cart_value')->label('Min. cart')->money(fn () => app(CurrentContext::class)->currencyCode())->sortable(),
                TextColumn::make('discountType.name')->label('Discount type')->placeholder('—'),
                TextColumn::make('discount_value')->label('Discount'),
                TextColumn::make('max_discount_amount')->label('Max. discount')->money(fn () => app(CurrentContext::class)->currencyCode())->placeholder('—'),
                TextColumn::make('starts_at')->date()->placeholder('—'),
                TextColumn::make('ends_at')->date()->placeholder('—'),
                IconColumn::make('is_active')->boolean()->label('Active'),
            ])
            ->filters([
                TernaryFilter::make('is_active')->label('Active'),
            ])
            ->defaultSort('name')
            ->recordActions([
                EditAction::make(),
                DeleteAction::make()
                    ->after(fn (CartDiscount $record) => AuditLog::record('cart_discount.deleted', $record, [
                        'name' => $record->name,
                    ])),
            ]);
    }

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