<?php

namespace App\Filament\Resources\Coupons\Tables;

use App\Enums\CouponStatus;
use App\Enums\CouponType;
use App\Jobs\SyncCouponToPaddle;
use App\Services\Audit\SuperAdminAuditLogger;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Actions\ViewAction;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Str;

class CouponsTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('name')
                    ->label(__('Name'))
                    ->searchable()
                    ->sortable(),
                TextColumn::make('code')
                    ->label(__('Code'))
                    ->badge()
                    ->copyable()
                    ->sortable(),
                TextColumn::make('type')
                    ->label(__('Type'))
                    ->badge()
                    ->formatStateUsing(fn ($state) => static::formatEnumState($state))
                    ->sortable(),
                TextColumn::make('amount')
                    ->label(__('Amount'))
                    ->formatStateUsing(fn ($state, $record) => $record->type === CouponType::PERCENTAGE
                        ? sprintf('%s%%', $record->amount)
                        : sprintf('%s %s', number_format($record->amount, 2), strtoupper($record->currency ?? 'EUR')))
                    ->sortable(),
                TextColumn::make('redemptions_count')
                    ->label(__('Redeemed'))
                    ->badge()
                    ->sortable(),
                IconColumn::make('enabled_for_checkout')
                    ->label(__('Checkout'))
                    ->boolean(),
                TextColumn::make('status')
                    ->label(__('Status'))
                    ->badge()
                    ->sortable()
                    ->formatStateUsing(fn ($state) => static::formatEnumState($state)),
                TextColumn::make('starts_at')
                    ->label(__('Starts'))
                    ->date()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('ends_at')
                    ->label(__('Ends'))
                    ->date()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->label(__('Status'))
                    ->options(
                        collect(CouponStatus::cases())->mapWithKeys(fn ($status) => [$status->value => $status->label()])->all()
                    ),
                SelectFilter::make('type')
                    ->label(__('Type'))
                    ->options(
                        collect(CouponType::cases())->mapWithKeys(fn ($type) => [$type->value => $type->label()])->all()
                    ),
                TernaryFilter::make('is_active')
                    ->label(__('Currently active'))
                    ->placeholder(__('All'))
                    ->queries(
                        true: fn ($query) => $query->active(),
                        false: fn ($query) => $query->where(function ($inner) {
                            $inner->where('status', '!=', CouponStatus::ACTIVE->value)
                                ->orWhere(function ($sub) {
                                    $sub->whereNotNull('ends_at')
                                        ->where('ends_at', '<', now());
                                });
                        }),
                    ),
                TrashedFilter::make(),
            ])
            ->recordActions([
                ViewAction::make(),
                EditAction::make()
                    ->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
                        'updated',
                        $record,
                        SuperAdminAuditLogger::fieldsMetadata($data),
                        static::class
                    )),
                Action::make('sync')
                    ->label(__('Sync to Paddle'))
                    ->icon('heroicon-m-arrow-path')
                    ->action(fn ($record) => SyncCouponToPaddle::dispatch($record))
                    ->requiresConfirmation(),
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make()
                        ->after(function (Collection $records): void {
                            $logger = app(SuperAdminAuditLogger::class);

                            foreach ($records as $record) {
                                $logger->recordModelMutation(
                                    'deleted',
                                    $record,
                                    source: static::class
                                );
                            }
                        }),
                    ForceDeleteBulkAction::make()
                        ->after(function (Collection $records): void {
                            $logger = app(SuperAdminAuditLogger::class);

                            foreach ($records as $record) {
                                $logger->recordModelMutation(
                                    'force_deleted',
                                    $record,
                                    source: static::class
                                );
                            }
                        }),
                    RestoreBulkAction::make()
                        ->after(function (Collection $records): void {
                            $logger = app(SuperAdminAuditLogger::class);

                            foreach ($records as $record) {
                                $logger->recordModelMutation(
                                    'restored',
                                    $record,
                                    source: static::class
                                );
                            }
                        }),
                ]),
            ]);
    }

    public static function formatEnumState(mixed $state): string
    {
        if ($state instanceof CouponType || $state instanceof CouponStatus) {
            return $state->label();
        }

        if ($state instanceof \BackedEnum) {
            return Str::headline($state->value);
        }

        if (is_string($state)) {
            return Str::headline($state);
        }

        return '';
    }
}
