<?php

namespace App\Filament\Resources\EntraGroupSyncRunResource\Pages;

use App\Filament\Resources\EntraGroupSyncRunResource;
use App\Jobs\EntraGroupSyncJob;
use App\Models\EntraGroupSyncRun;
use App\Models\Tenant;
use App\Models\User;
use App\Notifications\RunStatusChangedNotification;
use App\Services\Directory\EntraGroupSelection;
use Filament\Actions\Action;
use Filament\Resources\Pages\ListRecords;

class ListEntraGroupSyncRuns extends ListRecords
{
    protected static string $resource = EntraGroupSyncRunResource::class;

    protected function getHeaderActions(): array
    {
        return [
            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();

                    $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) {
                        $normalizedStatus = $existing->status === EntraGroupSyncRun::STATUS_RUNNING ? 'running' : 'queued';

                        $user->notify(new RunStatusChangedNotification([
                            'tenant_id' => (int) $tenant->getKey(),
                            'run_type' => 'directory_groups',
                            'run_id' => (int) $existing->getKey(),
                            'status' => $normalizedStatus,
                        ]));

                        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(),
                    ));

                    $user->notify(new RunStatusChangedNotification([
                        'tenant_id' => (int) $tenant->getKey(),
                        'run_type' => 'directory_groups',
                        'run_id' => (int) $run->getKey(),
                        'status' => 'queued',
                    ]));
                }),
        ];
    }
}
