<?php

namespace App\Filament\Resources\EmailDeliveryLogs;

use App\Filament\Resources\EmailDeliveryLogs\Pages\ListEmailDeliveryLogs;
use App\Filament\Resources\EmailDeliveryLogs\Pages\ViewEmailDeliveryLog;
use App\Models\EmailDeliveryLog;
use App\Services\Email\EmailResendService;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Actions\ViewAction;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
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\Filters\SelectFilter;
use Filament\Tables\Table;
use Throwable;

class EmailDeliveryLogResource extends Resource
{
    protected static ?string $model = EmailDeliveryLog::class;

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

    protected static ?string $navigationLabel = 'Email Delivery Logs';

    protected static string|\UnitEnum|null $navigationGroup = 'Operations';

    protected static ?int $navigationSort = 10;

    public static function form(Schema $schema): Schema
    {
        return $schema;
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('recipient_email')
                    ->label('Recipient')
                    ->searchable()
                    ->sortable(),

                TextColumn::make('user.email')
                    ->label('User')
                    ->searchable()
                    ->toggleable(),

                TextColumn::make('type')
                    ->badge()
                    ->sortable(),

                TextColumn::make('provider')
                    ->badge()
                    ->sortable(),

                TextColumn::make('brevo_message_id')
                    ->label('Brevo message ID')
                    ->searchable()
                    ->copyable()
                    ->limit(28)
                    ->placeholder('Not Brevo / missing'),

                TextColumn::make('subject')
                    ->searchable()
                    ->limit(42),

                TextColumn::make('status')
                    ->badge()
                    ->sortable(),

                IconColumn::make('resendable')
                    ->boolean()
                    ->sortable(),

                TextColumn::make('sent_at')
                    ->dateTime()
                    ->sortable(),

                TextColumn::make('opened_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(),

                TextColumn::make('clicked_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(),
            ])
            ->filters([
                SelectFilter::make('type')
                    ->options([
                        EmailDeliveryLog::TYPE_JOB_ALERT => 'Job alert',
                        EmailDeliveryLog::TYPE_APPLICATION_FOLLOW_UP => 'Application follow-up',
                        EmailDeliveryLog::TYPE_PASSWORD_RESET_OTP => 'Password reset OTP',
                        'transactional' => 'Transactional',
                    ]),

                SelectFilter::make('status')
                    ->options([
                        EmailDeliveryLog::STATUS_PENDING => 'Pending',
                        EmailDeliveryLog::STATUS_SENT => 'Sent',
                        EmailDeliveryLog::STATUS_DELIVERED => 'Delivered',
                        EmailDeliveryLog::STATUS_OPENED => 'Opened',
                        EmailDeliveryLog::STATUS_CLICKED => 'Clicked',
                        EmailDeliveryLog::STATUS_UNSUBSCRIBED => 'Unsubscribed',
                        EmailDeliveryLog::STATUS_BOUNCED => 'Bounced',
                        EmailDeliveryLog::STATUS_FAILED => 'Failed',
                    ]),

                SelectFilter::make('provider')
                    ->options([
                        'brevo' => 'Brevo',
                        'laravel' => 'Laravel mailer',
                    ]),
            ])
            ->recordActions([
                ViewAction::make(),
                Action::make('resend')
                    ->label('Resend')
                    ->icon(Heroicon::ArrowPath)
                    ->requiresConfirmation()
                    ->visible(fn (EmailDeliveryLog $record): bool => $record->canBeResent())
                    ->action(function (EmailDeliveryLog $record): void {
                        try {
                            app(EmailResendService::class)->resend($record);

                            Notification::make()
                                ->success()
                                ->title('Email resent')
                                ->body('A new delivery log was created for the resend attempt.')
                                ->send();
                        } catch (Throwable $exception) {
                            report($exception);

                            Notification::make()
                                ->danger()
                                ->title('Resend failed')
                                ->body(str($exception->getMessage())->limit(220)->toString())
                                ->send();
                        }
                    }),
            ])
            ->recordUrl(fn (EmailDeliveryLog $record): string => static::getUrl('view', ['record' => $record]))
            ->defaultSort('created_at', 'desc');
    }

    public static function infolist(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make('Delivery')
                    ->schema([
                        TextEntry::make('recipient_email')->copyable(),
                        TextEntry::make('recipient_name')->placeholder('No name'),
                        TextEntry::make('subject')->columnSpanFull(),
                        TextEntry::make('type')->badge(),
                        TextEntry::make('provider')->badge(),
                        TextEntry::make('status')->badge(),
                        TextEntry::make('brevo_message_id')->copyable()->placeholder('Not available'),
                        TextEntry::make('provider_message_id')->copyable()->placeholder('Not available'),
                        TextEntry::make('failure_reason')->placeholder('No failure')->columnSpanFull(),
                    ])
                    ->columns(3),

                Section::make('Timeline')
                    ->schema([
                        TextEntry::make('sent_at')->dateTime()->placeholder('Not sent'),
                        TextEntry::make('delivered_at')->dateTime()->placeholder('No event'),
                        TextEntry::make('opened_at')->dateTime()->placeholder('No event'),
                        TextEntry::make('clicked_at')->dateTime()->placeholder('No event'),
                        TextEntry::make('unsubscribed_at')->dateTime()->placeholder('No event'),
                        TextEntry::make('bounced_at')->dateTime()->placeholder('No event'),
                    ])
                    ->columns(3),

                Section::make('Metadata')
                    ->schema([
                        TextEntry::make('headers')
                            ->formatStateUsing(fn (mixed $state): ?string => is_array($state) ? json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) : $state)
                            ->placeholder('No headers')
                            ->copyable()
                            ->columnSpanFull(),
                        TextEntry::make('metadata')
                            ->formatStateUsing(fn (mixed $state): ?string => is_array($state) ? json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) : $state)
                            ->placeholder('No metadata')
                            ->copyable()
                            ->columnSpanFull(),
                        TextEntry::make('event_counts')
                            ->formatStateUsing(fn (mixed $state): ?string => is_array($state) ? json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) : $state)
                            ->placeholder('No events')
                            ->copyable()
                            ->columnSpanFull(),
                    ]),
            ]);
    }

    public static function getPages(): array
    {
        return [
            'index' => ListEmailDeliveryLogs::route('/'),
            'view' => ViewEmailDeliveryLog::route('/{record}'),
        ];
    }
}
