<?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\Audit\AuditActionId;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;

class EditAlertDestination extends EditRecord
{
    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 getSubheading(): ?string
    {
        if ($this->lastTestStatus === null) {
            return null;
        }

        $label = ucfirst($this->lastTestStatus->status->value);
        $timestamp = $this->lastTestStatus->timestamp?->diffForHumans();

        return $timestamp !== null
            ? "Last test: {$label} ({$timestamp})"
            : "Last test: {$label}";
    }

    protected function mutateFormDataBeforeSave(array $data): array
    {
        $record = $this->record;
        $data = AlertDestinationResource::normalizePayload(
            data: $data,
            record: $record instanceof AlertDestination ? $record : null,
        );
        AlertDestinationResource::assertValidConfigPayload($data);

        return $data;
    }

    protected function afterSave(): void
    {
        $record = $this->record;

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

        AlertDestinationResource::audit($record, AuditActionId::AlertDestinationUpdated, [
            'alert_destination_id' => (int) $record->getKey(),
            'name' => (string) $record->name,
            'type' => (string) $record->type,
            'is_enabled' => (bool) $record->is_enabled,
        ]);

        Notification::make()
            ->title('Destination updated')
            ->success()
            ->send();
    }

    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;
        }

        $baseUrl = AlertDeliveryResource::getUrl('index');
        $params = http_build_query([
            'filters' => [
                'event_type' => ['value' => 'alerts.test'],
                'alert_destination_id' => ['value' => (string) $record->getKey()],
            ],
        ]);

        return "{$baseUrl}?{$params}";
    }
}
