<?php

namespace App\Filament\Resources;

use App\Filament\Resources\Concerns\HasModulePermissions;
use App\Filament\Resources\Concerns\HasStandardTableFeatures;
use App\Filament\Resources\LoyaltyProgramResource\Pages\CreateLoyaltyProgram;
use App\Filament\Resources\LoyaltyProgramResource\Pages\EditLoyaltyProgram;
use App\Filament\Resources\LoyaltyProgramResource\Pages\ListLoyaltyPrograms;
use App\Models\Loyalty\LoyaltyProgram;
use App\Services\CurrentContext;
use Filament\Actions\EditAction;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;

/**
 * Ported from App\Http\Controllers\Isms\LoyaltyProgramController
 * (docs/migration-plan.md Phase 7).
 *
 * The module's catalog actions are `access` and `manage` only — there are no
 * create/edit/delete verbs — so create and edit both resolve to
 * `isms_loyalty.manage` (same shape as TillResource's `pos.access`, Decisions
 * Log #32). There is no destroy route in the source, so no delete surface.
 *
 * Tier handling reproduces the source's update() exactly: every tier row is
 * deleted and recreated on save rather than diffed, which is why the tiers
 * repeater is deliberately NOT ->relationship()-bound.
 */
class LoyaltyProgramResource extends Resource
{
    use HasModulePermissions;
    use HasStandardTableFeatures;

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

    protected static string $permissionModuleKey = 'isms_loyalty';

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

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

    protected static ?string $navigationLabel = 'Loyalty Programs';

    protected static ?int $navigationSort = 10;

    protected static ?string $recordTitleAttribute = 'name';

    public static function canCreate(): bool
    {
        return static::hasModulePermission('manage');
    }

    public static function canEdit(Model $record): bool
    {
        return static::hasModulePermission('manage');
    }

    public static function canDelete(Model $record): bool
    {
        return false;
    }

    public static function canDeleteAny(): bool
    {
        return false;
    }

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            Section::make()->schema([
                TextInput::make('name')->required()->maxLength(100),
                TextInput::make('base_earn_rate')
                    ->numeric()->required()->minValue(0)
                    ->helperText('Points earned per currency unit spent.'),
                TextInput::make('redemption_rate')
                    ->numeric()->required()->minValue(0.0001)
                    ->helperText('Points per currency unit when redeeming.'),
                TextInput::make('minimum_purchase_to_earn')->numeric()->minValue(0)->default(0)->prefix('Rs.'),
                TextInput::make('minimum_points_to_redeem')->numeric()->minValue(0)->default(0),
                TextInput::make('points_validity_days')->numeric()->integer()->minValue(1),
                Toggle::make('is_active')->default(true),
            ])->columns(3),

            Section::make('Tiers')->schema([
                Repeater::make('tiers')
                    ->schema([
                        TextInput::make('name')->required()->maxLength(50),
                        TextInput::make('code')->required()->maxLength(20),
                        TextInput::make('min_lifetime_points')->numeric()->required()->minValue(0),
                        TextInput::make('earn_multiplier')->numeric()->minValue(0)->default(1),
                        TextInput::make('color')->maxLength(20),
                    ])
                    // This Section is one of two side by side on the page, so 5
                    // columns only had roughly half the viewport to work with.
                    ->columns(3)
                    ->defaultItems(0)
                    ->addActionLabel('Add tier')
                    ->columnSpanFull(),
            ]),
        ]);
    }

    public static function table(Table $table): Table
    {
        return static::standardTableDefaults($table)
            ->recordUrl(static::standardRecordUrl())
            ->emptyStateHeading('No loyalty programs yet')
            ->emptyStateDescription('Create a program to start rewarding customers.')
            ->columns([
                TextColumn::make('name')->searchable()->sortable(),
                TextColumn::make('base_earn_rate')->label('Earn rate'),
                TextColumn::make('redemption_rate')->label('Redemption rate'),
                TextColumn::make('minimum_purchase_to_earn')->money(fn () => app(CurrentContext::class)->currencyCode()),
                TextColumn::make('minimum_points_to_redeem'),
                TextColumn::make('points_validity_days')->label('Validity (days)')->placeholder('∞'),
                TextColumn::make('tiers_count')->label('Tiers')->counts('tiers'),
                IconColumn::make('is_active')->boolean(),
            ])
            // Matches the source's orderByDesc('is_active').
            ->defaultSort('is_active', 'desc')
            ->recordActions([
                EditAction::make(),
            ]);
    }

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