<?php

namespace App\Filament\Resources;

use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Resources\PurchaseResource\Pages;
use App\Models\PackagePurchase;
use App\Notifications\Customer\RefundReceipt;
use App\Notifications\Ops\RefundProcessed;
use App\Services\Audit\SuperAdminAuditLogger;
use App\Services\Paddle\PaddleTransactionService;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\DateTimePicker;
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\Schema;
use Filament\Tables\Columns\BadgeColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;

class PurchaseResource extends Resource
{
    protected static ?string $model = PackagePurchase::class;

    protected static ?string $cluster = DailyOpsCluster::class;

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-shopping-cart';

    public static function getNavigationGroup(): string
    {
        return __('admin.nav.billing');
    }

    protected static ?int $navigationSort = 10;

    public static function form(Schema $schema): Schema
    {
        return $schema
            ->schema([
                Select::make('tenant_id')
                    ->label('Tenant')
                    ->relationship('tenant', 'name')
                    ->searchable()
                    ->preload()
                    ->nullable(),
                Select::make('event_id')
                    ->label('Event')
                    ->relationship('event', 'name')
                    ->searchable()
                    ->preload()
                    ->nullable(),
                Select::make('package_id')
                    ->label('Package')
                    ->relationship('package', 'name')
                    ->searchable()
                    ->preload()
                    ->required(),
                TextInput::make('provider_id')
                    ->label('Provider ID')
                    ->required()
                    ->maxLength(255),
                TextInput::make('price')
                    ->label('Price')
                    ->numeric()
                    ->step(0.01)
                    ->prefix('€')
                    ->required(),
                Select::make('type')
                    ->label('Type')
                    ->options([
                        'endcustomer_event' => 'Endcustomer Event',
                        'reseller_subscription' => 'Reseller Subscription',
                    ])
                    ->required(),
                Textarea::make('metadata')
                    ->label('Metadata')
                    ->json()
                    ->columnSpanFull(),
                Toggle::make('refunded')
                    ->label('Refunded')
                    ->default(false),
            ])
            ->columns(2);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                BadgeColumn::make('type')
                    ->label('Type')
                    ->color(fn (string $state): string => match ($state) {
                        'endcustomer_event' => 'info',
                        'reseller_subscription' => 'success',
                        default => 'gray',
                    }),
                TextColumn::make('tenant.name')
                    ->label('Tenant')
                    ->searchable()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('event.name')
                    ->label('Event')
                    ->searchable()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('package.name')
                    ->label('Package')
                    ->badge()
                    ->color('success'),
                TextColumn::make('price')
                    ->label('Price')
                    ->money('EUR')
                    ->sortable(),
                TextColumn::make('purchased_at')
                    ->dateTime()
                    ->sortable(),
                BadgeColumn::make('refunded')
                    ->label('Status')
                    ->color(fn (bool $state): string => $state ? 'danger' : 'success'),
                TextColumn::make('provider_id')
                    ->copyable()
                    ->toggleable(),
                TextColumn::make('metadata.consents.legal_version')
                    ->label('Legal Version')
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('metadata.consents.accepted_terms_at')
                    ->label('Terms accepted')
                    ->dateTime()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('metadata.consents.accepted_withdrawal_notice_at')
                    ->label('Withdrawal notice')
                    ->dateTime()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('metadata.consents.digital_content_waiver_at')
                    ->label('Waiver (digital)')
                    ->dateTime()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('type')
                    ->options([
                        'endcustomer_event' => 'Endcustomer Event',
                        'reseller_subscription' => 'Reseller Subscription',
                    ]),
                Filter::make('purchased_at')
                    ->form([
                        DateTimePicker::make('started_from'),
                        DateTimePicker::make('ended_before'),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['started_from'],
                                fn (Builder $query, $date): Builder => $query->whereDate('purchased_at', '>=', $date),
                            )
                            ->when(
                                $data['ended_before'],
                                fn (Builder $query, $date): Builder => $query->whereDate('purchased_at', '<=', $date),
                            );
                    }),
                SelectFilter::make('tenant_id')
                    ->label('Tenant')
                    ->relationship('tenant', 'name')
                    ->searchable(),
            ])
            ->actions([
                ViewAction::make(),
                EditAction::make()
                    ->after(fn (array $data, PackagePurchase $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
                        'updated',
                        $record,
                        SuperAdminAuditLogger::fieldsMetadata($data),
                        static::class
                    )),
                Action::make('refund')
                    ->label('Refund')
                    ->color('danger')
                    ->icon('heroicon-o-arrow-uturn-left')
                    ->requiresConfirmation()
                    ->visible(fn (PackagePurchase $record): bool => ! $record->refunded)
                    ->form([
                        Textarea::make('reason')
                            ->label('Refund reason (optional)')
                            ->rows(2),
                    ])
                    ->action(function (PackagePurchase $record, array $data) {
                        $reason = $data['reason'] ?? null;
                        $refundSuccess = true;
                        $errorMessage = null;

                        if ($record->provider === 'paddle' && $record->provider_id) {
                            try {
                                /** @var PaddleTransactionService $paddle */
                                $paddle = App::make(PaddleTransactionService::class);
                                $paddle->refund($record->provider_id, ['reason' => $reason]);
                            } catch (\Throwable $exception) {
                                $refundSuccess = false;
                                $errorMessage = $exception->getMessage();
                                Log::warning('Paddle refund failed', [
                                    'purchase_id' => $record->id,
                                    'provider_id' => $record->provider_id,
                                    'error' => $exception->getMessage(),
                                ]);
                            }
                        }

                        $metadata = $record->metadata ?? [];
                        $metadata['refund_reason'] = $reason ?: ($metadata['refund_reason'] ?? null);

                        $record->update([
                            'refunded' => true,
                            'metadata' => $metadata,
                        ]);

                        Log::info('Refund processed for purchase ID: '.$record->id, [
                            'provider' => $record->provider,
                            'provider_id' => $record->provider_id,
                            'reason' => $reason,
                        ]);

                        $customerEmail = $record->tenant->contact_email ?? $record->tenant?->user?->email;
                        if ($customerEmail) {
                            Notification::route('mail', $customerEmail)->notify(new RefundReceipt($record, $reason));
                        }

                        $opsEmail = config('mail.ops_address');
                        if ($opsEmail) {
                            Notification::route('mail', $opsEmail)->notify(new RefundProcessed($record, $refundSuccess, $reason, $errorMessage));
                        }

                        app(SuperAdminAuditLogger::class)->record(
                            'purchase.refunded',
                            $record,
                            SuperAdminAuditLogger::fieldsMetadata(['refunded', 'metadata']),
                            source: static::class
                        );
                    }),
            ])
            ->bulkActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make()
                        ->after(function (Collection $records): void {
                            $logger = app(SuperAdminAuditLogger::class);

                            foreach ($records as $record) {
                                $logger->recordModelMutation(
                                    'deleted',
                                    $record,
                                    source: static::class
                                );
                            }
                        }),
                ]),
            ])
            ->emptyStateHeading('No Purchases Found')
            ->emptyStateDescription('Create your first purchase.');
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListPurchases::route('/'),
            'create' => Pages\CreatePurchase::route('/create'),
            'view' => Pages\ViewPurchase::route('/{record}'),
            'edit' => Pages\EditPurchase::route('/{record}/edit'),
        ];
    }

    public static function getRelations(): array
    {
        return [
            // Add RelationManagers if needed
        ];
    }
}
