<?php

namespace App\Support;

use App\Filament\Resources\BackupScheduleResource;
use App\Filament\Resources\BackupSetResource;
use App\Filament\Resources\BaselineSnapshotResource;
use App\Filament\Resources\EntraGroupResource;
use App\Filament\Resources\EnvironmentReviewResource;
use App\Filament\Resources\EvidenceSnapshotResource;
use App\Filament\Resources\InventoryItemResource;
use App\Filament\Resources\PolicyResource;
use App\Filament\Resources\RestoreRunResource;
use App\Filament\Resources\ReviewPackResource;
use App\Models\EnvironmentReview;
use App\Models\EvidenceSnapshot;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\ReviewPack;
use App\Models\Workspace;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\Workspaces\WorkspaceContext;

final class OperationRunLinks
{
    public static function collectionLabel(): string
    {
        return 'Operations';
    }

    public static function openCollectionLabel(): string
    {
        return 'Open operations';
    }

    public static function collectionScopeDescription(): string
    {
        return 'Broader admin view across recent and historical operations.';
    }

    public static function viewInCollectionLabel(): string
    {
        return 'View in Operations';
    }

    public static function singularLabel(): string
    {
        return 'Operation';
    }

    public static function openLabel(): string
    {
        return 'Open operation';
    }

    public static function advancedMonitoringLabel(): string
    {
        return 'Open operation in Monitoring (advanced)';
    }

    public static function advancedMonitoringDescription(): string
    {
        return 'Diagnostics-only link to the canonical admin operation viewer.';
    }

    public static function identifierLabel(): string
    {
        return 'Operation ID';
    }

    public static function identifier(OperationRun|int $run): string
    {
        $runId = $run instanceof OperationRun ? (int) $run->getKey() : (int) $run;

        return 'Operation #'.$runId;
    }

    public static function index(
        ?ManagedEnvironment $tenant = null,
        ?CanonicalNavigationContext $context = null,
        ?string $activeTab = null,
        bool $allTenants = false,
        ?string $problemClass = null,
        ?string $operationType = null,
        ?Workspace $workspace = null,
    ): string {
        $workspace = $tenant instanceof ManagedEnvironment
            ? self::resolveWorkspace($tenant)
            : ($workspace ?? self::resolveWorkspace());

        if (! $workspace instanceof Workspace) {
            return url('/admin');
        }

        $parameters = $context?->toQuery() ?? [];

        $parameters['workspace'] = $workspace;

        if ($tenant instanceof ManagedEnvironment) {
            $parameters['environment_id'] = (int) $tenant->getKey();
        }

        if (is_string($activeTab) && $activeTab !== '') {
            $parameters['activeTab'] = $activeTab;
        }

        if (
            is_string($problemClass)
            && in_array($problemClass, OperationRun::problemClasses(), true)
            && $problemClass !== OperationRun::PROBLEM_CLASS_NONE
        ) {
            $parameters['problemClass'] = $problemClass;

            if (! is_string($activeTab) || $activeTab === '') {
                $parameters['activeTab'] = $problemClass;
            }
        }

        if (is_string($operationType) && $operationType !== '') {
            $parameters['tableFilters']['type']['value'] = OperationCatalog::canonicalCode($operationType);
        }

        return route('admin.operations.index', $parameters);
    }

    public static function tenantlessView(OperationRun|int $run, ?CanonicalNavigationContext $context = null): string
    {
        $runId = $run instanceof OperationRun ? (int) $run->getKey() : (int) $run;

        $workspace = self::resolveWorkspace($run);

        if (! $workspace instanceof Workspace) {
            return url('/admin');
        }

        return route('admin.operations.view', array_merge(
            ['workspace' => $workspace, 'run' => $runId],
            $context?->toQuery() ?? [],
        ));
    }

    public static function view(OperationRun|int $run, ManagedEnvironment $tenant, ?CanonicalNavigationContext $context = null): string
    {
        return self::tenantlessView($run, $context);
    }

    /**
     * @return array<string, string>
     */
    public static function related(OperationRun $run, ?ManagedEnvironment $tenant): array
    {
        $context = is_array($run->context) ? $run->context : [];

        $links = [];

        $links[self::collectionLabel()] = self::index($tenant);

        if (! $tenant instanceof ManagedEnvironment) {
            return $links;
        }

        $providerConnectionId = $context['provider_connection_id'] ?? null;
        $canonicalType = $run->canonicalOperationType();

        if (is_numeric($providerConnectionId)) {
            $links['Provider Connections'] = ManagedEnvironmentLinks::providerConnectionsUrl($tenant);
            $links['Provider Connection'] = ManagedEnvironmentLinks::providerConnectionUrl((int) $providerConnectionId, 'edit', $tenant);
        }

        if ($canonicalType === 'inventory.sync') {
            $links['Inventory'] = InventoryItemResource::getUrl('index', tenant: $tenant);
        }

        if ($canonicalType === 'policy.sync') {
            $links['Policies'] = PolicyResource::getUrl('index', tenant: $tenant);

            $policyId = $context['policy_id'] ?? null;
            if (is_numeric($policyId)) {
                $links['Policy'] = PolicyResource::getUrl('view', ['record' => (int) $policyId], tenant: $tenant);
            }
        }

        if ($canonicalType === 'directory.groups.sync') {
            $links['Directory Groups'] = EntraGroupResource::scopedUrl('index', tenant: $tenant);
        }

        if ($canonicalType === 'baseline.compare') {
            $links['Drift'] = ManagedEnvironmentLinks::baselineCompareUrl($tenant);
        }

        if ($canonicalType === 'baseline.capture') {
            $snapshotId = data_get($context, 'result.snapshot_id');

            if (is_numeric($snapshotId)) {
                $links['Baseline Snapshot'] = BaselineSnapshotResource::getUrl('view', ['record' => (int) $snapshotId], panel: 'admin');
            }
        }

        if ($canonicalType === 'backup_set.update') {
            $links['Backup Sets'] = BackupSetResource::getUrl('index', tenant: $tenant);

            $backupSetId = $context['backup_set_id'] ?? null;
            if (is_numeric($backupSetId)) {
                $links['Backup Set'] = BackupSetResource::getUrl('view', ['record' => (int) $backupSetId], tenant: $tenant);
            }
        }

        if (in_array($canonicalType, ['backup.schedule.execute', 'backup.schedule.retention', 'backup.schedule.purge'], true)) {
            $links['Backup Schedules'] = BackupScheduleResource::getUrl('index', tenant: $tenant);
        }

        if ($canonicalType === 'restore.execute') {
            $links['Restore Runs'] = RestoreRunResource::getUrl('index', tenant: $tenant);

            $restoreRunId = $context['restore_run_id'] ?? null;
            if (is_numeric($restoreRunId)) {
                $links['Restore Run'] = RestoreRunResource::getUrl('view', ['record' => (int) $restoreRunId], tenant: $tenant);
            }
        }

        if ($canonicalType === 'tenant.evidence.snapshot.generate') {
            $snapshot = EvidenceSnapshot::query()
                ->where('operation_run_id', (int) $run->getKey())
                ->latest('id')
                ->first();

            if ($snapshot instanceof EvidenceSnapshot) {
                $links['Evidence Snapshot'] = EvidenceSnapshotResource::getUrl('view', ['record' => $snapshot], tenant: $tenant);
            }
        }

        if ($canonicalType === 'environment.review.compose') {
            $review = EnvironmentReview::query()
                ->where('operation_run_id', (int) $run->getKey())
                ->latest('id')
                ->first();

            if ($review instanceof EnvironmentReview) {
                $links['ManagedEnvironment Review'] = EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant);
            }
        }

        if ($canonicalType === 'environment.review_pack.generate') {
            $pack = ReviewPack::query()
                ->where('operation_run_id', (int) $run->getKey())
                ->latest('id')
                ->first();

            if ($pack instanceof ReviewPack) {
                $links['Review Pack'] = ReviewPackResource::getUrl('view', ['record' => $pack], tenant: $tenant);
            }
        }

        return array_filter($links, static fn (?string $url): bool => is_string($url) && $url !== '');
    }

    private static function resolveWorkspace(ManagedEnvironment|OperationRun|int|null $subject = null): ?Workspace
    {
        if ($subject instanceof ManagedEnvironment) {
            return $subject->workspace()->first();
        }

        if ($subject instanceof OperationRun) {
            return Workspace::query()->whereKey((int) $subject->workspace_id)->first();
        }

        if (is_int($subject) && $subject > 0) {
            $run = OperationRun::query()
                ->select(['id', 'workspace_id'])
                ->whereKey($subject)
                ->first();

            if ($run instanceof OperationRun) {
                return Workspace::query()->whereKey((int) $run->workspace_id)->first();
            }
        }

        return app(WorkspaceContext::class)->currentWorkspace(request());
    }
}
