<?php

namespace App\Filament\Resources\EntraGroupResource\Pages;

use App\Filament\Resources\EntraGroupResource;
use App\Filament\Resources\EntraGroupSyncRunResource;
use App\Jobs\EntraGroupSyncJob;
use App\Models\EntraGroupSyncRun;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Directory\EntraGroupSelection;
use App\Services\OperationRunService;
use App\Support\OperationRunLinks;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ListRecords;

class ListEntraGroups extends ListRecords
{
    protected static string $resource = EntraGroupResource::class;

    protected function getHeaderActions(): array
    {
        return [
            Action::make('view_group_sync_runs')
                ->label('Group Sync Runs')
                ->icon('heroicon-o-clock')
                ->url(fn (): string => EntraGroupSyncRunResource::getUrl('index', tenant: Tenant::current()))
                ->visible(fn (): bool => (bool) Tenant::current()),

            Action::make('sync_groups')
                ->label('Sync Groups')
                ->icon('heroicon-o-arrow-path')
                ->color('warning')
                ->visible(function (): bool {
                    $user = auth()->user();

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

                    $tenant = Tenant::current();

                    if (! $tenant) {
                        return false;
                    }

                    $role = $user->tenantRole($tenant);

                    return $role?->canSync() ?? false;
                })
                ->action(function (): void {
                    $user = auth()->user();

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

                    $tenant = Tenant::current();

                    if (! $tenant) {
                        abort(403);
                    }

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

                    $role = $user->tenantRole($tenant);

                    if (! ($role?->canSync() ?? false)) {
                        abort(403);
                    }

                    $selectionKey = EntraGroupSelection::allGroupsV1();

                    // --- Phase 3: Canonical Operation Run Start ---
                    /** @var OperationRunService $opService */
                    $opService = app(OperationRunService::class);
                    $opRun = $opService->ensureRun(
                        tenant: $tenant,
                        type: 'directory_groups.sync',
                        inputs: ['selection_key' => $selectionKey],
                        initiator: $user
                    );

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

                        return;
                    }
                    // ----------------------------------------------

                    $existing = EntraGroupSyncRun::query()
                        ->where('tenant_id', $tenant->getKey())
                        ->where('selection_key', $selectionKey)
                        ->whereIn('status', [EntraGroupSyncRun::STATUS_PENDING, EntraGroupSyncRun::STATUS_RUNNING])
                        ->orderByDesc('id')
                        ->first();

                    if ($existing instanceof EntraGroupSyncRun) {
                        Notification::make()
                            ->title('Group sync already active')
                            ->body('This operation is already queued or running.')
                            ->warning()
                            ->actions([
                                Action::make('view_run')
                                    ->label('View Run')
                                    ->url(OperationRunLinks::view($opRun, $tenant)),
                            ])
                            ->sendToDatabase($user)
                            ->send();

                        return;
                    }

                    $run = EntraGroupSyncRun::query()->create([
                        'tenant_id' => $tenant->getKey(),
                        'selection_key' => $selectionKey,
                        'slot_key' => null,
                        'status' => EntraGroupSyncRun::STATUS_PENDING,
                        'initiator_user_id' => $user->getKey(),
                    ]);

                    dispatch(new EntraGroupSyncJob(
                        tenantId: (int) $tenant->getKey(),
                        selectionKey: $selectionKey,
                        slotKey: null,
                        runId: (int) $run->getKey(),
                        operationRun: $opRun
                    ));

                    Notification::make()
                        ->title('Group sync started')
                        ->body('Sync dispatched.')
                        ->success()
                        ->actions([
                            Action::make('view_run')
                                ->label('View Run')
                                ->url(OperationRunLinks::view($opRun, $tenant)),
                        ])
                        ->sendToDatabase($user)
                        ->send();
                }),
        ];
    }
}
