<?php

namespace App\Filament\Resources\PolicyResource\Pages;

use App\Filament\Resources\PolicyResource;
use App\Jobs\SyncPoliciesJob;
use App\Models\Tenant;
use App\Models\User;
use App\Services\OperationRunService;
use App\Support\OperationRunLinks;
use App\Support\OpsUx\OperationUxPresenter;
use App\Support\OpsUx\OpsUxBrowserEvents;
use Filament\Actions;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ListRecords;

class ListPolicies extends ListRecords
{
    protected static string $resource = PolicyResource::class;

    protected function getHeaderActions(): array
    {
        return [
            Actions\Action::make('sync')
                ->label('Sync from Intune')
                ->icon('heroicon-o-arrow-path')
                ->color('primary')
                ->requiresConfirmation()
                ->visible(function (): bool {
                    $user = auth()->user();

                    if (! $user instanceof User) {
                        return false;
                    }

                    $tenant = Tenant::current();

                    return $user->canSyncTenant($tenant);
                })
                ->action(function (self $livewire): void {
                    $tenant = Tenant::current();
                    $user = auth()->user();

                    if (! $user instanceof User) {
                        abort(403);
                    }

                    if (! $user->canAccessTenant($tenant) || ! $user->canSyncTenant($tenant)) {
                        abort(403);
                    }

                    $requestedTypes = array_map(
                        static fn (array $typeConfig): string => (string) $typeConfig['type'],
                        config('tenantpilot.supported_policy_types', [])
                    );

                    sort($requestedTypes);

                    /** @var OperationRunService $opService */
                    $opService = app(OperationRunService::class);
                    $opRun = $opService->ensureRun(
                        tenant: $tenant,
                        type: 'policy.sync',
                        inputs: [
                            'scope' => 'all',
                            'types' => $requestedTypes,
                        ],
                        initiator: $user
                    );

                    if (! $opRun->wasRecentlyCreated && in_array($opRun->status, ['queued', 'running'], true)) {
                        Notification::make()
                            ->title('Policy sync already active')
                            ->body('This operation is already queued or running.')
                            ->warning()
                            ->actions([
                                Actions\Action::make('view_run')
                                    ->label('View run')
                                    ->url(OperationRunLinks::view($opRun, $tenant)),
                            ])
                            ->send();

                        return;
                    }

                    $opService->dispatchOrFail($opRun, function () use ($tenant, $requestedTypes, $opRun): void {
                        SyncPoliciesJob::dispatch(
                            tenantId: (int) $tenant->getKey(),
                            types: $requestedTypes,
                            operationRun: $opRun
                        );
                    });

                    OpsUxBrowserEvents::dispatchRunEnqueued($livewire);
                    OperationUxPresenter::queuedToast((string) $opRun->type)
                        ->actions([
                            Actions\Action::make('view_run')
                                ->label('View run')
                                ->url(OperationRunLinks::view($opRun, $tenant)),
                        ])
                        ->send();
                }),
        ];
    }
}
