<?php

declare(strict_types=1);

namespace App\Filament\Resources\AlertDestinationResource\Pages;

use App\Filament\Resources\AlertDeliveryResource;
use App\Filament\Resources\AlertDestinationResource;
use App\Models\AlertDestination;
use App\Models\User;
use App\Services\Alerts\AlertDestinationLastTestResolver;
use App\Services\Alerts\AlertDestinationTestMessageService;
use App\Support\Alerts\AlertDestinationLastTestStatus;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ViewRecord;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

class ViewAlertDestination extends ViewRecord
{
    protected static string $resource = AlertDestinationResource::class;

    private ?AlertDestinationLastTestStatus $lastTestStatus = null;

    public function mount(int|string $record): void
    {
        parent::mount($record);
        $this->resolveLastTestStatus();
    }

    protected function getHeaderActions(): array
    {
        $user = auth()->user();
        $record = $this->record;
        $canManage = $user instanceof User
            && $record instanceof AlertDestination
            && $user->can('update', $record);

        return [
            Action::make('send_test_message')
                ->label('Send test message')
                ->icon('heroicon-o-paper-airplane')
                ->requiresConfirmation()
                ->modalHeading('Send test message')
                ->modalDescription('A test delivery will be queued for this destination. This verifies the delivery pipeline is working.')
                ->modalSubmitActionLabel('Send')
                ->visible(fn (): bool => $record instanceof AlertDestination)
                ->disabled(fn (): bool => ! $canManage)
                ->action(function () use ($record): void {
                    $user = auth()->user();

                    if (! $user instanceof User || ! $record instanceof AlertDestination) {
                        return;
                    }

                    $service = app(AlertDestinationTestMessageService::class);
                    $result = $service->sendTest($record, $user);

                    if ($result['success']) {
                        Notification::make()
                            ->title($result['message'])
                            ->success()
                            ->send();
                    } else {
                        Notification::make()
                            ->title($result['message'])
                            ->warning()
                            ->send();
                    }

                    $this->resolveLastTestStatus();
                }),

            Action::make('view_last_delivery')
                ->label('View last delivery')
                ->icon('heroicon-o-arrow-top-right-on-square')
                ->url(fn (): ?string => $this->buildDeepLinkUrl())
                ->openUrlInNewTab()
                ->visible(fn (): bool => $this->lastTestStatus?->deliveryId !== null),
        ];
    }

    public function infolist(Schema $schema): Schema
    {
        $lastTest = $this->lastTestStatus ?? AlertDestinationLastTestStatus::never();

        return $schema
            ->schema([
                Section::make('Last test')
                    ->schema([
                        TextEntry::make('last_test_status')
                            ->label('Status')
                            ->badge()
                            ->state($lastTest->status->value)
                            ->formatStateUsing(BadgeRenderer::label(BadgeDomain::AlertDestinationLastTestStatus))
                            ->color(BadgeRenderer::color(BadgeDomain::AlertDestinationLastTestStatus))
                            ->icon(BadgeRenderer::icon(BadgeDomain::AlertDestinationLastTestStatus)),
                        TextEntry::make('last_test_timestamp')
                            ->label('Timestamp')
                            ->state($lastTest->timestamp?->toDateTimeString())
                            ->placeholder('—'),
                    ])
                    ->columns(2),
                Section::make('Details')
                    ->schema([
                        TextEntry::make('name'),
                        TextEntry::make('type')
                            ->badge()
                            ->formatStateUsing(fn (?string $state): string => AlertDestinationResource::typeLabel((string) $state)),
                        TextEntry::make('is_enabled')
                            ->label('Enabled')
                            ->badge()
                            ->formatStateUsing(fn (bool $state): string => $state ? 'Yes' : 'No')
                            ->color(fn (bool $state): string => $state ? 'success' : 'gray'),
                        TextEntry::make('created_at')
                            ->dateTime(),
                        TextEntry::make('updated_at')
                            ->dateTime(),
                    ])
                    ->columns(2),
            ]);
    }

    private function resolveLastTestStatus(): void
    {
        $record = $this->record;

        if (! $record instanceof AlertDestination) {
            return;
        }

        $this->lastTestStatus = app(AlertDestinationLastTestResolver::class)->resolve($record);
    }

    private function buildDeepLinkUrl(): ?string
    {
        $record = $this->record;

        if (! $record instanceof AlertDestination || $this->lastTestStatus?->deliveryId === null) {
            return null;
        }

        return AlertDeliveryResource::getUrl(panel: 'admin').'?'.http_build_query([
            'filters' => [
                'event_type' => ['value' => 'alerts.test'],
                'alert_destination_id' => ['value' => (string) $record->getKey()],
            ],
        ]);
    }
}
