<?php

declare(strict_types=1);

namespace App\Filament\Resources\Packages;

use App\Filament\Resources\Packages\Pages\ListPackages;
use App\Models\Package;
use BackedEnum;
use Filament\Actions\CreateAction;
use Filament\Actions\EditAction;
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\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use UnitEnum;

/**
 * The five packages.
 *
 * Note that studio hours and engineer hours are separate fields rather than
 * one number. Start Strong is the reason: ten studio hours but an engineer
 * for only five of them, so an artist must be able to book five engineer-led
 * hours and five self-serve, and be stopped at exactly the right point.
 */
class PackageResource extends Resource
{
    protected static ?string $model = Package::class;

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

    protected static string|UnitEnum|null $navigationGroup = 'Studio setup';

    protected static ?string $recordTitleAttribute = 'name';

    protected static ?int $navigationSort = 3;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            Section::make('The offer')
                ->schema([
                    TextInput::make('name')->required(),
                    TextInput::make('slug')->required()->unique(ignoreRecord: true),
                    TextInput::make('price')->numeric()->prefix('£')->step(0.01)->required(),
                    TextInput::make('validity_days')
                        ->label('Valid for')->numeric()->suffix('days')->required(),
                    Textarea::make('summary')->rows(2)->columnSpanFull(),
                ])
                ->columns(4),

            Section::make('What it grants')
                ->description('Three separate balances. Engineer hours may be fewer than studio hours.')
                ->schema([
                    TextInput::make('studio_hours')->numeric()->suffix('hours')->required(),
                    TextInput::make('engineer_hours')->numeric()->suffix('hours')->required()
                        ->helperText('Start Strong grants 10 studio hours but only 5 with an engineer.'),
                    TextInput::make('mixmaster_credits')->label('Mix & master')->numeric()->suffix('tracks')->required(),
                    TextInput::make('staff_per_session')
                        ->label('People per session')
                        ->numeric()->default(1)->required()
                        ->helperText('2 for Label Ready and Industry VIP — they include a second person.'),
                ])
                ->columns(4),

            Section::make('Rules')
                ->schema([
                    Toggle::make('skips_lead_time')
                        ->label('Priority booking')
                        ->helperText('Exempt from the 24 hour notice rule. Label Ready only.'),
                    Toggle::make('is_active')->label('On sale')->default(true),
                    TextInput::make('min_age')->numeric()->placeholder('No limit')
                        ->helperText('Young Creators is 16 to 25.'),
                    TextInput::make('max_age')->numeric()->placeholder('No limit'),
                    Toggle::make('allows_group')
                        ->label('Can be shared')
                        ->helperText('Young Creators offers a group version.'),
                    TextInput::make('group_surcharge')->numeric()->prefix('£')->step(0.01)->placeholder('—'),
                    TextInput::make('max_participants')->numeric()->default(1)->required(),
                    TextInput::make('sort_order')->numeric()->default(0),
                ])
                ->columns(4),
        ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->defaultSort('sort_order')
            ->columns([
                TextColumn::make('name')->searchable()->weight('bold')
                    ->description(fn (Package $record) => $record->summary),
                TextColumn::make('price')->money('GBP')->sortable(),
                TextColumn::make('studio_hours')->label('Studio')->suffix('h')->alignCenter(),
                TextColumn::make('engineer_hours')
                    ->label('Engineer')->suffix('h')->alignCenter()
                    // Worth flagging: this is the field that is easy to set
                    // equal to studio hours by mistake and quietly give away
                    // engineer time the package never promised.
                    ->color(fn (Package $record) => $record->engineer_hours < $record->studio_hours ? 'warning' : null),
                TextColumn::make('mixmaster_credits')->label('Tracks')->alignCenter(),
                TextColumn::make('validity_days')->label('Valid')->suffix(' days')->alignCenter(),
                TextColumn::make('staff_per_session')->label('Staff')->alignCenter(),
                IconColumn::make('skips_lead_time')->label('Priority')->boolean(),
                IconColumn::make('is_active')->label('On sale')->boolean(),
            ])
            ->headerActions([CreateAction::make()])
            ->recordActions([EditAction::make()])
            ->toolbarActions([]);
    }

    public static function getPages(): array
    {
        return ['index' => ListPackages::route('/')];
    }
}
