<?php

namespace App\Filament\Clusters\DailyOps\Resources\Photos\Tables;

use App\Models\Event;
use App\Models\Photo;
use App\Models\Tenant;
use App\Services\Audit\SuperAdminAuditLogger;
use Filament\Actions\Action;
use Filament\Actions\BulkAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\ViewAction;
use Filament\Facades\Filament;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Textarea;
use Filament\Support\Icons\Heroicon;
use Filament\Tables;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;

class PhotosTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->defaultSort('created_at', 'desc')
            ->columns([
                ImageColumn::make('thumbnail_path')
                    ->label(__('admin.moderation.table.photo'))
                    ->disk('public')
                    ->visibility('public')
                    ->circular()
                    ->getStateUsing(fn (Photo $record) => $record->thumbnail_path ?: $record->file_path),
                Tables\Columns\TextColumn::make('event.name')
                    ->label(__('admin.moderation.table.event'))
                    ->searchable()
                    ->limit(30),
                Tables\Columns\TextColumn::make('event.tenant.name')
                    ->label(__('admin.moderation.table.tenant'))
                    ->limit(30),
                Tables\Columns\TextColumn::make('guest_name')
                    ->label(__('admin.moderation.table.uploader'))
                    ->searchable()
                    ->limit(20),
                Tables\Columns\TextColumn::make('status')
                    ->label(__('admin.moderation.table.status'))
                    ->badge()
                    ->color(fn (?string $state) => match ($state) {
                        'approved' => 'success',
                        'rejected' => 'danger',
                        'hidden' => 'gray',
                        default => 'warning',
                    })
                    ->formatStateUsing(fn (?string $state) => self::statusLabels()[$state] ?? '—')
                    ->sortable(),
                Tables\Columns\TextColumn::make('security_scan_status')
                    ->label(__('admin.moderation.table.security_scan'))
                    ->badge()
                    ->color(fn (?string $state) => match ($state) {
                        'clean', 'skipped', 'stripped' => 'success',
                        'infected' => 'danger',
                        'error' => 'warning',
                        default => 'gray',
                    })
                    ->formatStateUsing(fn (?string $state) => self::securityScanLabels()[$state] ?? '—')
                    ->toggleable(),
                Tables\Columns\TextColumn::make('ingest_source')
                    ->label(__('admin.moderation.table.ingest_source'))
                    ->badge()
                    ->color('gray')
                    ->formatStateUsing(fn (?string $state) => self::ingestSourceLabels()[$state] ?? '—')
                    ->toggleable(),
                Tables\Columns\TextColumn::make('created_at')
                    ->label(__('admin.moderation.table.uploaded_at'))
                    ->since()
                    ->sortable(),
                Tables\Columns\TextColumn::make('moderator.name')
                    ->label(__('admin.moderation.table.moderated_by'))
                    ->placeholder('—')
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('moderated_at')
                    ->label(__('admin.moderation.table.moderated_at'))
                    ->since()
                    ->placeholder('—')
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->label(__('admin.moderation.filters.status'))
                    ->options(self::statusLabels())
                    ->default('pending'),
                SelectFilter::make('ingest_source')
                    ->label(__('admin.moderation.filters.ingest_source'))
                    ->options(self::ingestSourceLabels())
                    ->default(Photo::SOURCE_GUEST_PWA),
                SelectFilter::make('security_scan_status')
                    ->label(__('admin.moderation.filters.security_scan_status'))
                    ->options(self::securityScanLabels()),
                SelectFilter::make('tenant_id')
                    ->label(__('admin.common.tenant'))
                    ->options(fn () => Tenant::query()->orderBy('name')->pluck('name', 'id')->toArray())
                    ->searchable(),
                SelectFilter::make('event_id')
                    ->label(__('admin.common.event'))
                    ->options(fn () => Event::query()->orderBy('name')->pluck('name', 'id')->toArray())
                    ->searchable(),
                Filter::make('created_at')
                    ->label(__('admin.moderation.filters.uploaded_at'))
                    ->form([
                        DatePicker::make('from')->label(__('admin.common.from')),
                        DatePicker::make('until')->label(__('admin.common.until')),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['from'] ?? null,
                                fn (Builder $query, string $date): Builder => $query->whereDate('created_at', '>=', $date)
                            )
                            ->when(
                                $data['until'] ?? null,
                                fn (Builder $query, string $date): Builder => $query->whereDate('created_at', '<=', $date)
                            );
                    }),
            ])
            ->recordActions([
                ViewAction::make(),
                Action::make('approve')
                    ->label(__('admin.moderation.actions.approve'))
                    ->color('success')
                    ->icon(Heroicon::OutlinedCheckCircle)
                    ->visible(fn (Photo $record) => $record->status === 'pending')
                    ->form([
                        self::moderationNotesField(false),
                    ])
                    ->requiresConfirmation()
                    ->action(fn (Photo $record, array $data) => self::applyModeration($record, 'approved', $data['moderation_notes'] ?? null)),
                Action::make('reject')
                    ->label(__('admin.moderation.actions.reject'))
                    ->color('danger')
                    ->icon(Heroicon::OutlinedXCircle)
                    ->visible(fn (Photo $record) => $record->status === 'pending')
                    ->form([
                        self::moderationNotesField(true),
                    ])
                    ->requiresConfirmation()
                    ->action(fn (Photo $record, array $data) => self::applyModeration($record, 'rejected', $data['moderation_notes'] ?? null)),
                Action::make('hide')
                    ->label(__('admin.moderation.actions.hide'))
                    ->color('gray')
                    ->icon(Heroicon::OutlinedEyeSlash)
                    ->visible(fn (Photo $record) => $record->status !== 'hidden')
                    ->form([
                        self::moderationNotesField(false),
                    ])
                    ->requiresConfirmation()
                    ->action(fn (Photo $record, array $data) => self::applyModeration($record, 'hidden', $data['moderation_notes'] ?? null)),
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    BulkAction::make('approve')
                        ->label(__('admin.moderation.actions.approve_selected'))
                        ->icon(Heroicon::OutlinedCheckCircle)
                        ->color('success')
                        ->form([
                            self::moderationNotesField(false),
                        ])
                        ->requiresConfirmation()
                        ->action(fn (Collection $records, array $data) => self::applyModerationToRecords($records, 'approved', $data['moderation_notes'] ?? null)),
                    BulkAction::make('reject')
                        ->label(__('admin.moderation.actions.reject_selected'))
                        ->icon(Heroicon::OutlinedXCircle)
                        ->color('danger')
                        ->form([
                            self::moderationNotesField(true),
                        ])
                        ->requiresConfirmation()
                        ->action(fn (Collection $records, array $data) => self::applyModerationToRecords($records, 'rejected', $data['moderation_notes'] ?? null)),
                    BulkAction::make('hide')
                        ->label(__('admin.moderation.actions.hide_selected'))
                        ->icon(Heroicon::OutlinedEyeSlash)
                        ->color('gray')
                        ->form([
                            self::moderationNotesField(false),
                        ])
                        ->requiresConfirmation()
                        ->action(fn (Collection $records, array $data) => self::applyModerationToRecords($records, 'hidden', $data['moderation_notes'] ?? null)),
                ]),
            ]);
    }

    private static function moderationNotesField(bool $required): Textarea
    {
        return Textarea::make('moderation_notes')
            ->label(__('admin.moderation.fields.moderation_notes'))
            ->maxLength(1000)
            ->rows(3)
            ->required($required);
    }

    private static function applyModeration(Photo $record, string $status, ?string $notes): void
    {
        $record->update([
            'status' => $status,
            'moderation_notes' => $notes,
            'moderated_at' => now(),
            'moderated_by' => Filament::auth()->id(),
        ]);

        app(SuperAdminAuditLogger::class)->record(
            'photo.'.$status,
            $record,
            SuperAdminAuditLogger::fieldsMetadata([
                'status',
                'moderation_notes',
                'moderated_at',
                'moderated_by',
            ]),
            source: self::class
        );
    }

    private static function applyModerationToRecords(Collection $records, string $status, ?string $notes): int
    {
        $moderatedAt = now();
        $moderatedBy = Filament::auth()->id();

        $updated = Photo::query()
            ->whereIn('id', $records->pluck('id'))
            ->where('status', 'pending')
            ->update([
                'status' => $status,
                'moderation_notes' => $notes,
                'moderated_at' => $moderatedAt,
                'moderated_by' => $moderatedBy,
            ]);

        $logger = app(SuperAdminAuditLogger::class);

        foreach ($records as $record) {
            $logger->record(
                'photo.'.$status,
                $record,
                SuperAdminAuditLogger::fieldsMetadata([
                    'status',
                    'moderation_notes',
                    'moderated_at',
                    'moderated_by',
                ]),
                source: self::class
            );
        }

        return $updated;
    }

    private static function statusLabels(): array
    {
        return [
            'pending' => __('admin.moderation.status.pending'),
            'approved' => __('admin.moderation.status.approved'),
            'rejected' => __('admin.moderation.status.rejected'),
            'hidden' => __('admin.moderation.status.hidden'),
        ];
    }

    private static function ingestSourceLabels(): array
    {
        return [
            Photo::SOURCE_GUEST_PWA => __('admin.moderation.ingest_sources.guest_pwa'),
            Photo::SOURCE_TENANT_ADMIN => __('admin.moderation.ingest_sources.tenant_admin'),
            Photo::SOURCE_PHOTOBOOTH => __('admin.moderation.ingest_sources.photobooth'),
            Photo::SOURCE_SPARKBOOTH => __('admin.moderation.ingest_sources.sparkbooth'),
            Photo::SOURCE_UNKNOWN => __('admin.moderation.ingest_sources.unknown'),
        ];
    }

    private static function securityScanLabels(): array
    {
        return [
            'pending' => __('admin.moderation.security_scan.pending'),
            'clean' => __('admin.moderation.security_scan.clean'),
            'infected' => __('admin.moderation.security_scan.infected'),
            'skipped' => __('admin.moderation.security_scan.skipped'),
            'stripped' => __('admin.moderation.security_scan.stripped'),
            'error' => __('admin.moderation.security_scan.error'),
        ];
    }
}
