<?php

declare(strict_types=1);

namespace App\Support\Navigation;

use App\Filament\Resources\AlertDestinationResource;
use App\Filament\Resources\AlertRuleResource;
use App\Filament\Resources\BackupSetResource;
use App\Filament\Resources\BaselineProfileResource;
use App\Filament\Resources\BaselineSnapshotResource;
use App\Filament\Resources\FindingExceptionResource;
use App\Filament\Resources\FindingResource;
use App\Filament\Resources\PolicyVersionResource;
use App\Filament\Resources\RestoreRunResource;
use App\Models\AuditLog;
use App\Models\BackupSet;
use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\BaselineSnapshotItem;
use App\Models\Finding;
use App\Models\FindingException;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\Policy;
use App\Models\PolicyVersion;
use App\Models\RestoreRun;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Auth\CapabilityResolver;
use App\Services\Auth\WorkspaceCapabilityResolver;
use App\Support\Auth\Capabilities;
use App\Support\OperateHub\OperateHubShell;
use App\Support\OperationRunLinks;
use App\Support\References\ReferenceClass;
use App\Support\References\ReferenceDescriptor;
use App\Support\References\ReferenceResolverRegistry;
use App\Support\References\RelatedContextReferenceAdapter;
use App\Support\Ui\DerivedState\DerivedStateFamily;
use App\Support\Ui\DerivedState\DerivedStateKey;
use App\Support\Ui\DerivedState\RequestScopedDerivedStateStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;

final class RelatedNavigationResolver
{
    public function __construct(
        private readonly CrossResourceNavigationMatrix $matrix,
        private readonly RelatedActionLabelCatalog $labels,
        private readonly CapabilityResolver $capabilityResolver,
        private readonly WorkspaceCapabilityResolver $workspaceCapabilityResolver,
        private readonly ReferenceResolverRegistry $referenceResolverRegistry,
        private readonly RelatedContextReferenceAdapter $relatedContextReferenceAdapter,
        private readonly RequestScopedDerivedStateStore $derivedStateStore,
    ) {}

    /**
     * @return list<array{
     *     key: string,
     *     label: string,
     *     value: string,
     *     secondaryValue: ?string,
     *     targetUrl: ?string,
     *     targetKind: string,
     *     availability: string,
     *     unavailableReason: ?string,
     *     contextBadge: ?string,
     *     priority: int,
     *     actionLabel: string
     * }>
     */
    public function detailEntries(string $sourceType, Model $record): array
    {
        return array_map(
            static fn (RelatedContextEntry $entry): array => $entry->toArray(),
            $this->detailEntryObjects($sourceType, $record),
        );
    }

    /**
     * @return list<array{
     *     key: string,
     *     label: string,
     *     value: string,
     *     secondaryValue: ?string,
     *     targetUrl: ?string,
     *     targetKind: string,
     *     availability: string,
     *     unavailableReason: ?string,
     *     contextBadge: ?string,
     *     priority: int,
     *     actionLabel: string
     * }>
     */
    public function detailEntriesFresh(string $sourceType, Model $record): array
    {
        return array_map(
            static fn (RelatedContextEntry $entry): array => $entry->toArray(),
            $this->detailEntryObjects($sourceType, $record, fresh: true),
        );
    }

    public function primaryListAction(string $sourceType, Model $record): ?RelatedContextEntry
    {
        return $this->resolvePrimaryListAction($sourceType, $record);
    }

    public function primaryListActionFresh(string $sourceType, Model $record): ?RelatedContextEntry
    {
        return $this->resolvePrimaryListAction($sourceType, $record, fresh: true);
    }

    /**
     * @return array<string, string>
     */
    public function operationLinks(OperationRun $run, ?ManagedEnvironment $tenant): array
    {
        $entries = array_filter(
            $this->detailEntryObjects(CrossResourceNavigationMatrix::SOURCE_OPERATION_RUN, $run),
            static fn (RelatedContextEntry $entry): bool => $entry->isAvailable(),
        );

        $links = [];

        foreach ($entries as $entry) {
            $links[$entry->actionLabel] = (string) $entry->targetUrl;
        }

        if ($tenant instanceof ManagedEnvironment) {
            $links = [OperationRunLinks::collectionLabel() => OperationRunLinks::index($tenant)] + $links;
        } else {
            $links = [OperationRunLinks::collectionLabel() => OperationRunLinks::index()] + $links;
        }

        return $links;
    }

    /**
     * @return array<string, string>
     */
    public function operationLinksFresh(OperationRun $run, ?ManagedEnvironment $tenant): array
    {
        $entries = array_filter(
            $this->detailEntryObjects(CrossResourceNavigationMatrix::SOURCE_OPERATION_RUN, $run, fresh: true),
            static fn (RelatedContextEntry $entry): bool => $entry->isAvailable(),
        );

        $links = [];

        foreach ($entries as $entry) {
            $links[$entry->actionLabel] = (string) $entry->targetUrl;
        }

        if ($tenant instanceof ManagedEnvironment) {
            return [OperationRunLinks::collectionLabel() => OperationRunLinks::index($tenant)] + $links;
        }

        return [OperationRunLinks::collectionLabel() => OperationRunLinks::index()] + $links;
    }

    /**
     * @return list<RelatedContextEntry>
     */
    public function headerEntries(string $sourceType, Model $record): array
    {
        return $this->headerEntryObjects($sourceType, $record);
    }

    /**
     * @return list<RelatedContextEntry>
     */
    public function headerEntriesFresh(string $sourceType, Model $record): array
    {
        return $this->headerEntryObjects($sourceType, $record, fresh: true);
    }

    /**
     * @return array{label: string, url: string}|null
     */
    public function auditTargetLink(AuditLog $record): ?array
    {
        $user = auth()->user();

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

        $resourceType = is_string($record->resource_type) ? $record->resource_type : null;
        $resourceId = is_numeric($record->resource_id) ? (int) $record->resource_id : null;

        if ($resourceType === null || $resourceId === null) {
            return null;
        }

        $tenant = $record->tenant;
        $workspace = $record->workspace;

        return match ($resourceType) {
            'operation_run' => $workspace instanceof Workspace
                && $this->workspaceCapabilityResolver->isMember($user, $workspace)
                && OperationRun::query()
                    ->whereKey($resourceId)
                    ->where('workspace_id', (int) $workspace->getKey())
                    ->exists()
                ? ['label' => OperationRunLinks::openLabel(), 'url' => OperationRunLinks::tenantlessView($resourceId)]
                : null,
            'baseline_profile' => $workspace instanceof Workspace
                && $this->workspaceCapabilityResolver->isMember($user, $workspace)
                && $this->workspaceCapabilityResolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_VIEW)
                && ($baselineProfile = BaselineProfile::query()
                    ->whereKey($resourceId)
                    ->where('workspace_id', (int) $workspace->getKey())
                    ->first()) instanceof BaselineProfile
                && BaselineProfileResource::canView($baselineProfile)
                ? ['label' => 'Open baseline profile', 'url' => BaselineProfileResource::getUrl('view', ['record' => $resourceId], panel: 'admin')]
                : null,
            'baseline_snapshot' => $workspace instanceof Workspace
                && $this->workspaceCapabilityResolver->isMember($user, $workspace)
                && $this->workspaceCapabilityResolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_VIEW)
                && ($baselineSnapshot = BaselineSnapshot::query()
                    ->whereKey($resourceId)
                    ->where('workspace_id', (int) $workspace->getKey())
                    ->first()) instanceof BaselineSnapshot
                && BaselineSnapshotResource::canView($baselineSnapshot)
                ? ['label' => 'Open baseline snapshot', 'url' => BaselineSnapshotResource::getUrl('view', ['record' => $resourceId], panel: 'admin')]
                : null,
            'alert_rule' => $workspace instanceof Workspace
                && $this->workspaceCapabilityResolver->isMember($user, $workspace)
                && ($alertRule = AlertRule::query()
                    ->whereKey($resourceId)
                    ->where('workspace_id', (int) $workspace->getKey())
                    ->first()) instanceof AlertRule
                && AlertRuleResource::canView($alertRule)
                ? ['label' => 'Open alert rule', 'url' => AlertRuleResource::getUrl('view', ['record' => $resourceId], panel: 'admin')]
                : null,
            'alert_destination' => $workspace instanceof Workspace
                && $this->workspaceCapabilityResolver->isMember($user, $workspace)
                && ($alertDestination = AlertDestination::query()
                    ->whereKey($resourceId)
                    ->where('workspace_id', (int) $workspace->getKey())
                    ->first()) instanceof AlertDestination
                && AlertDestinationResource::canView($alertDestination)
                ? ['label' => 'Open alert destination', 'url' => AlertDestinationResource::getUrl('view', ['record' => $resourceId], panel: 'admin')]
                : null,
            'backup_set' => $tenant instanceof ManagedEnvironment
                && $this->capabilityResolver->isMember($user, $tenant)
                && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW)
                && BackupSet::query()
                    ->whereKey($resourceId)
                    ->where('managed_environment_id', (int) $tenant->getKey())
                    ->exists()
                ? ['label' => 'Open backup set', 'url' => BackupSetResource::getUrl('view', ['record' => $resourceId], tenant: $tenant)]
                : null,
            'restore_run' => $tenant instanceof ManagedEnvironment
                && $this->capabilityResolver->isMember($user, $tenant)
                && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW)
                && RestoreRun::query()
                    ->whereKey($resourceId)
                    ->where('managed_environment_id', (int) $tenant->getKey())
                    ->exists()
                ? ['label' => 'Open restore run', 'url' => RestoreRunResource::getUrl('view', ['record' => $resourceId], tenant: $tenant)]
                : null,
            'finding' => $tenant instanceof ManagedEnvironment
                && $this->capabilityResolver->isMember($user, $tenant)
                && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW)
                && Finding::query()
                    ->whereKey($resourceId)
                    ->where('managed_environment_id', (int) $tenant->getKey())
                    ->exists()
                ? ['label' => 'Open finding', 'url' => FindingResource::getUrl('view', ['record' => $resourceId], tenant: $tenant)]
                : null,
            'finding_exception' => $tenant instanceof ManagedEnvironment
                && $this->capabilityResolver->isMember($user, $tenant)
                && $this->capabilityResolver->can($user, $tenant, Capabilities::FINDING_EXCEPTION_VIEW)
                && ($findingException = FindingException::query()
                    ->whereKey($resourceId)
                    ->where('managed_environment_id', (int) $tenant->getKey())
                    ->first()) instanceof FindingException
                ? ['label' => 'Open finding exception', 'url' => FindingExceptionResource::getUrl('view', ['record' => $findingException], tenant: $tenant)]
                : null,
            default => null,
        };
    }

    /**
     * @return list<RelatedContextEntry>
     */
    private function resolveEntries(string $sourceType, string $surface, Model $record): array
    {
        $entries = [];

        foreach ($this->matrix->rulesFor($sourceType, $surface) as $rule) {
            $entry = $this->resolveRule($rule, $record);

            if ($entry instanceof RelatedContextEntry) {
                $entries[] = $entry;
            }
        }

        usort(
            $entries,
            static fn (RelatedContextEntry $left, RelatedContextEntry $right): int => $left->priority <=> $right->priority,
        );

        return $entries;
    }

    /**
     * @return list<RelatedContextEntry>
     */
    private function detailEntryObjects(string $sourceType, Model $record, bool $fresh = false): array
    {
        return $this->memoizedEntries(
            family: DerivedStateFamily::RelatedNavigationDetail,
            sourceType: $sourceType,
            record: $record,
            surface: CrossResourceNavigationMatrix::SURFACE_DETAIL_SECTION,
            fresh: $fresh,
        );
    }

    /**
     * @return list<RelatedContextEntry>
     */
    private function headerEntryObjects(string $sourceType, Model $record, bool $fresh = false): array
    {
        return $this->memoizedEntries(
            family: DerivedStateFamily::RelatedNavigationHeader,
            sourceType: $sourceType,
            record: $record,
            surface: CrossResourceNavigationMatrix::SURFACE_DETAIL_HEADER,
            fresh: $fresh,
        );
    }

    private function resolvePrimaryListAction(string $sourceType, Model $record, bool $fresh = false): ?RelatedContextEntry
    {
        $entries = array_values(array_filter(
            $this->memoizedEntries(
                family: DerivedStateFamily::RelatedNavigationPrimary,
                sourceType: $sourceType,
                record: $record,
                surface: CrossResourceNavigationMatrix::SURFACE_LIST_ROW,
                fresh: $fresh,
            ),
            static fn (RelatedContextEntry $entry): bool => $entry->isAvailable(),
        ));

        return $entries[0] ?? null;
    }

    /**
     * @return list<RelatedContextEntry>
     */
    private function memoizedEntries(
        DerivedStateFamily $family,
        string $sourceType,
        Model $record,
        string $surface,
        bool $fresh = false,
    ): array {
        $key = DerivedStateKey::fromModel(
            family: $family,
            record: $record,
            variant: $sourceType,
            context: [
                'source_type' => $sourceType,
                'surface' => $surface,
                'active_tenant_id' => $this->activeEnvironmentId(),
                'route_name' => request()?->route()?->getName(),
                'user_id' => auth()->id(),
            ],
        );

        /** @var list<RelatedContextEntry> $entries */
        $entries = $fresh
            ? $this->derivedStateStore->resolveFresh(
                $key,
                fn (): array => $this->resolveEntries($sourceType, $surface, $record),
                $family->defaultFreshnessPolicy(),
                $family->allowsNegativeResultCache(),
            )
            : $this->derivedStateStore->resolve(
                $key,
                fn (): array => $this->resolveEntries($sourceType, $surface, $record),
                $family->defaultFreshnessPolicy(),
                $family->allowsNegativeResultCache(),
            );

        return $entries;
    }

    private function resolveRule(NavigationMatrixRule $rule, Model $record): ?RelatedContextEntry
    {
        return match ($rule->sourceType) {
            CrossResourceNavigationMatrix::SOURCE_FINDING => $record instanceof Finding ? $this->resolveFindingRule($rule, $record) : null,
            CrossResourceNavigationMatrix::SOURCE_POLICY_VERSION => $record instanceof PolicyVersion ? $this->resolvePolicyVersionRule($rule, $record) : null,
            CrossResourceNavigationMatrix::SOURCE_BASELINE_SNAPSHOT => $record instanceof BaselineSnapshot ? $this->resolveBaselineSnapshotRule($rule, $record) : null,
            CrossResourceNavigationMatrix::SOURCE_BACKUP_SET => $record instanceof BackupSet ? $this->resolveBackupSetRule($rule, $record) : null,
            CrossResourceNavigationMatrix::SOURCE_OPERATION_RUN => $record instanceof OperationRun ? $this->resolveOperationRunRule($rule, $record) : null,
            CrossResourceNavigationMatrix::SOURCE_BASELINE_PROFILE => $record instanceof BaselineProfile ? $this->resolveBaselineProfileRule($rule, $record) : null,
            default => null,
        };
    }

    private function resolveFindingRule(NavigationMatrixRule $rule, Finding $finding): ?RelatedContextEntry
    {
        return match ($rule->relationKey) {
            'baseline_snapshot' => $this->baselineSnapshotEntry(
                rule: $rule,
                snapshotId: $this->findingSnapshotId($finding),
                workspaceId: (int) $finding->workspace_id,
            ),
            'source_run' => $this->operationRunEntry(
                rule: $rule,
                runId: $this->findingRunId($finding),
                workspaceId: (int) $finding->workspace_id,
                context: $this->contextForFinding($finding, $rule->sourceSurface),
            ),
            'current_policy_version' => $this->policyVersionEntry(
                rule: $rule,
                policyVersionId: $this->findingPolicyVersionId($finding),
                tenantId: (int) $finding->managed_environment_id,
            ),
            'parent_policy' => $this->parentPolicyEntryForFinding($rule, $finding),
            'baseline_profile' => $this->baselineProfileEntry(
                rule: $rule,
                profileId: $this->findingProfileId($finding),
                workspaceId: (int) $finding->workspace_id,
            ),
            default => null,
        };
    }

    private function resolvePolicyVersionRule(NavigationMatrixRule $rule, PolicyVersion $version): ?RelatedContextEntry
    {
        return match ($rule->relationKey) {
            'parent_policy' => $this->policyEntry(
                rule: $rule,
                policy: $version->policy,
            ),
            'baseline_snapshot' => $this->policyVersionSnapshotEntry($rule, $version),
            'baseline_profile' => $this->baselineProfileEntry(
                rule: $rule,
                profileId: is_numeric($version->baseline_profile_id ?? null) ? (int) $version->baseline_profile_id : null,
                workspaceId: (int) $version->workspace_id,
            ),
            'source_run' => $this->operationRunEntry(
                rule: $rule,
                runId: is_numeric($version->operation_run_id ?? null) ? (int) $version->operation_run_id : null,
                workspaceId: (int) $version->workspace_id,
                context: $this->contextForPolicyVersion($version, $rule->sourceSurface),
            ),
            default => null,
        };
    }

    private function resolveBaselineSnapshotRule(NavigationMatrixRule $rule, BaselineSnapshot $snapshot): ?RelatedContextEntry
    {
        return match ($rule->relationKey) {
            'baseline_profile' => $this->policyProfileEntry(
                rule: $rule,
                profile: $snapshot->baselineProfile,
            ),
            'source_run' => $this->snapshotRunEntry($rule, $snapshot),
            'policy_version' => $this->snapshotPolicyVersionEntry($rule, $snapshot),
            default => null,
        };
    }

    private function resolveBackupSetRule(NavigationMatrixRule $rule, BackupSet $backupSet): ?RelatedContextEntry
    {
        return match ($rule->relationKey) {
            'source_run' => $this->backupSetRunEntry($rule, $backupSet),
            'operations' => $this->operationsEntry(
                rule: $rule,
                tenant: $backupSet->tenant,
                context: $this->contextForBackupSet($backupSet, $rule->sourceSurface),
            ),
            default => null,
        };
    }

    private function resolveOperationRunRule(NavigationMatrixRule $rule, OperationRun $run): ?RelatedContextEntry
    {
        $context = is_array($run->context) ? $run->context : [];

        return match ($rule->relationKey) {
            'backup_set' => $this->backupSetEntry(
                rule: $rule,
                backupSetId: is_numeric($context['backup_set_id'] ?? null) ? (int) $context['backup_set_id'] : null,
                tenantId: is_numeric($run->managed_environment_id ?? null) ? (int) $run->managed_environment_id : null,
            ),
            'restore_run' => $this->restoreRunEntry(
                rule: $rule,
                restoreRunId: is_numeric($context['restore_run_id'] ?? null) ? (int) $context['restore_run_id'] : null,
                tenantId: is_numeric($run->managed_environment_id ?? null) ? (int) $run->managed_environment_id : null,
            ),
            'baseline_profile' => $this->baselineProfileEntry(
                rule: $rule,
                profileId: is_numeric($context['baseline_profile_id'] ?? null) ? (int) $context['baseline_profile_id'] : null,
                workspaceId: (int) $run->workspace_id,
            ),
            'baseline_snapshot' => $this->baselineSnapshotEntry(
                rule: $rule,
                snapshotId: is_numeric($context['baseline_snapshot_id'] ?? null) ? (int) $context['baseline_snapshot_id'] : null,
                workspaceId: (int) $run->workspace_id,
            ),
            'parent_policy' => $this->operationRunPolicyEntry($rule, $run),
            'operations' => $this->operationsEntry(
                rule: $rule,
                tenant: $run->tenant,
                context: $this->contextForOperationRun($run),
            ),
            default => null,
        };
    }

    private function resolveBaselineProfileRule(NavigationMatrixRule $rule, BaselineProfile $profile): ?RelatedContextEntry
    {
        return match ($rule->relationKey) {
            'baseline_snapshot' => $this->baselineSnapshotEntry(
                rule: $rule,
                snapshotId: $profile->resolveCurrentConsumableSnapshot()?->getKey(),
                workspaceId: (int) $profile->workspace_id,
            ),
            default => null,
        };
    }

    private function findingSnapshotId(Finding $finding): ?int
    {
        $snapshotId = Arr::get($finding->evidence_jsonb ?? [], 'provenance.baseline_snapshot_id');

        if (! is_numeric($snapshotId)) {
            $snapshotId = Arr::get($finding->evidence_jsonb ?? [], 'baseline_snapshot_id');
        }

        return is_numeric($snapshotId) ? (int) $snapshotId : null;
    }

    private function findingProfileId(Finding $finding): ?int
    {
        $profileId = Arr::get($finding->evidence_jsonb ?? [], 'provenance.baseline_profile_id');

        return is_numeric($profileId) ? (int) $profileId : null;
    }

    private function findingPolicyVersionId(Finding $finding): ?int
    {
        $policyVersionId = Arr::get($finding->evidence_jsonb ?? [], 'current.policy_version_id');

        if (! is_numeric($policyVersionId)) {
            $policyVersionId = Arr::get($finding->evidence_jsonb ?? [], 'baseline.policy_version_id');
        }

        return is_numeric($policyVersionId) ? (int) $policyVersionId : null;
    }

    private function findingRunId(Finding $finding): ?int
    {
        $runId = Arr::get($finding->evidence_jsonb ?? [], 'provenance.compare_operation_run_id');

        if (is_numeric($runId)) {
            return (int) $runId;
        }

        if (is_numeric($finding->current_operation_run_id ?? null)) {
            return (int) $finding->current_operation_run_id;
        }

        return is_numeric($finding->baseline_operation_run_id ?? null)
            ? (int) $finding->baseline_operation_run_id
            : null;
    }

    private function policyVersionSnapshotEntry(NavigationMatrixRule $rule, PolicyVersion $version): ?RelatedContextEntry
    {
        $snapshotItem = BaselineSnapshotItem::query()
            ->where('meta_jsonb->version_reference->policy_version_id', (int) $version->getKey())
            ->whereHas('snapshot', fn ($query) => $query->where('workspace_id', (int) $version->workspace_id))
            ->with('snapshot.baselineProfile')
            ->latest('id')
            ->first();

        if (! $snapshotItem instanceof BaselineSnapshotItem) {
            return null;
        }

        $snapshot = $snapshotItem->snapshot;

        return $snapshot instanceof BaselineSnapshot
            ? $this->baselineSnapshotEntry($rule, (int) $snapshot->getKey(), (int) $version->workspace_id)
            : null;
    }

    private function snapshotRunEntry(NavigationMatrixRule $rule, BaselineSnapshot $snapshot): ?RelatedContextEntry
    {
        $candidate = OperationRun::query()
            ->where('workspace_id', (int) $snapshot->workspace_id)
            ->where('context->baseline_snapshot_id', (int) $snapshot->getKey())
            ->orderByDesc('completed_at')
            ->orderByDesc('id')
            ->first();

        return $candidate instanceof OperationRun
            ? $this->operationRunEntry(
                rule: $rule,
                runId: (int) $candidate->getKey(),
                workspaceId: (int) $snapshot->workspace_id,
                context: $this->contextForBaselineSnapshot($snapshot, $rule->sourceSurface),
            )
            : null;
    }

    private function snapshotPolicyVersionEntry(NavigationMatrixRule $rule, BaselineSnapshot $snapshot): ?RelatedContextEntry
    {
        $snapshotItem = BaselineSnapshotItem::query()
            ->where('baseline_snapshot_id', (int) $snapshot->getKey())
            ->whereNotNull('meta_jsonb->version_reference->policy_version_id')
            ->orderBy('id')
            ->first();

        if (! $snapshotItem instanceof BaselineSnapshotItem) {
            return null;
        }

        $policyVersionId = data_get($snapshotItem->meta_jsonb, 'version_reference.policy_version_id');

        return $this->policyVersionEntry(
            rule: $rule,
            policyVersionId: is_numeric($policyVersionId) ? (int) $policyVersionId : null,
            tenantId: $this->activeEnvironmentId(),
        );
    }

    private function backupSetRunEntry(NavigationMatrixRule $rule, BackupSet $backupSet): ?RelatedContextEntry
    {
        $candidate = OperationRun::query()
            ->where('managed_environment_id', (int) $backupSet->managed_environment_id)
            ->where('context->backup_set_id', (int) $backupSet->getKey())
            ->orderByDesc('completed_at')
            ->orderByDesc('id')
            ->first();

        return $candidate instanceof OperationRun
            ? $this->operationRunEntry(
                rule: $rule,
                runId: (int) $candidate->getKey(),
                workspaceId: (int) $backupSet->workspace_id,
                context: $this->contextForBackupSet($backupSet, $rule->sourceSurface),
            )
            : null;
    }

    private function operationRunPolicyEntry(NavigationMatrixRule $rule, OperationRun $run): ?RelatedContextEntry
    {
        $policyId = data_get($run->context, 'policy_id');

        if (! is_numeric($policyId)) {
            return null;
        }

        $policy = Policy::query()
            ->whereKey((int) $policyId)
            ->where('managed_environment_id', (int) $run->managed_environment_id)
            ->first();

        return $this->policyEntry($rule, $policy);
    }

    private function parentPolicyEntryForFinding(NavigationMatrixRule $rule, Finding $finding): ?RelatedContextEntry
    {
        $policyVersionId = $this->findingPolicyVersionId($finding);

        if ($policyVersionId === null) {
            return null;
        }

        $version = PolicyVersion::query()
            ->with('policy')
            ->whereKey($policyVersionId)
            ->where('managed_environment_id', (int) $finding->managed_environment_id)
            ->first();

        if (! $version instanceof PolicyVersion) {
            return null;
        }

        return $this->policyEntry($rule, $version->policy);
    }

    private function baselineSnapshotEntry(
        NavigationMatrixRule $rule,
        ?int $snapshotId,
        int $workspaceId,
    ): ?RelatedContextEntry {
        if ($snapshotId === null || $snapshotId <= 0) {
            return null;
        }

        return $this->resolveReferenceEntry(
            rule: $rule,
            descriptor: new ReferenceDescriptor(
                referenceClass: ReferenceClass::BaselineSnapshot,
                rawIdentifier: (string) $snapshotId,
                workspaceId: $workspaceId,
                sourceType: $rule->sourceType,
                sourceSurface: $rule->sourceSurface,
                linkedModelId: $snapshotId,
            ),
        );
    }

    private function baselineProfileEntry(
        NavigationMatrixRule $rule,
        ?int $profileId,
        int $workspaceId,
    ): ?RelatedContextEntry {
        if ($profileId === null || $profileId <= 0) {
            return null;
        }

        $profile = BaselineProfile::query()
            ->whereKey($profileId)
            ->where('workspace_id', $workspaceId)
            ->first();

        if (! $profile instanceof BaselineProfile) {
            return $this->unavailableEntry($rule, (string) $profileId, 'missing');
        }

        return $this->policyProfileEntry($rule, $profile);
    }

    private function policyProfileEntry(NavigationMatrixRule $rule, ?BaselineProfile $profile): ?RelatedContextEntry
    {
        if (! $profile instanceof BaselineProfile) {
            return null;
        }

        return $this->resolveReferenceEntry(
            rule: $rule,
            descriptor: new ReferenceDescriptor(
                referenceClass: ReferenceClass::BaselineProfile,
                rawIdentifier: (string) $profile->getKey(),
                workspaceId: (int) $profile->workspace_id,
                sourceType: $rule->sourceType,
                sourceSurface: $rule->sourceSurface,
                fallbackLabel: (string) $profile->name,
                linkedModelId: (int) $profile->getKey(),
            ),
        );
    }

    private function operationRunEntry(
        NavigationMatrixRule $rule,
        ?int $runId,
        int $workspaceId,
        ?CanonicalNavigationContext $context = null,
    ): ?RelatedContextEntry {
        if ($runId === null || $runId <= 0) {
            return null;
        }

        return $this->resolveReferenceEntry(
            rule: $rule,
            descriptor: new ReferenceDescriptor(
                referenceClass: ReferenceClass::OperationRun,
                rawIdentifier: (string) $runId,
                workspaceId: $workspaceId,
                sourceType: $rule->sourceType,
                sourceSurface: $rule->sourceSurface,
                linkedModelId: $runId,
                context: [
                    'navigation_context' => $context,
                ],
            ),
        );
    }

    private function policyVersionEntry(
        NavigationMatrixRule $rule,
        ?int $policyVersionId,
        ?int $tenantId,
    ): ?RelatedContextEntry {
        if ($policyVersionId === null || $policyVersionId <= 0 || $tenantId === null || $tenantId <= 0) {
            return null;
        }

        return $this->resolveReferenceEntry(
            rule: $rule,
            descriptor: new ReferenceDescriptor(
                referenceClass: ReferenceClass::PolicyVersion,
                rawIdentifier: (string) $policyVersionId,
                tenantId: $tenantId,
                sourceType: $rule->sourceType,
                sourceSurface: $rule->sourceSurface,
                linkedModelId: $policyVersionId,
            ),
        );
    }

    private function policyEntry(NavigationMatrixRule $rule, ?Policy $policy): ?RelatedContextEntry
    {
        if (! $policy instanceof Policy) {
            return null;
        }

        return $this->resolveReferenceEntry(
            rule: $rule,
            descriptor: new ReferenceDescriptor(
                referenceClass: ReferenceClass::Policy,
                rawIdentifier: (string) $policy->getKey(),
                tenantId: is_numeric($policy->managed_environment_id ?? null) ? (int) $policy->managed_environment_id : null,
                sourceType: $rule->sourceType,
                sourceSurface: $rule->sourceSurface,
                fallbackLabel: (string) ($policy->display_name ?: 'Policy'),
                linkedModelId: (int) $policy->getKey(),
            ),
        );
    }

    private function backupSetEntry(
        NavigationMatrixRule $rule,
        ?int $backupSetId,
        ?int $tenantId,
    ): ?RelatedContextEntry {
        if ($backupSetId === null || $backupSetId <= 0 || $tenantId === null || $tenantId <= 0) {
            return null;
        }

        return $this->resolveReferenceEntry(
            rule: $rule,
            descriptor: new ReferenceDescriptor(
                referenceClass: ReferenceClass::BackupSet,
                rawIdentifier: (string) $backupSetId,
                tenantId: $tenantId,
                sourceType: $rule->sourceType,
                sourceSurface: $rule->sourceSurface,
                linkedModelId: $backupSetId,
            ),
        );
    }

    private function resolveReferenceEntry(NavigationMatrixRule $rule, ReferenceDescriptor $descriptor): ?RelatedContextEntry
    {
        return $this->relatedContextReferenceAdapter->adapt(
            rule: $rule,
            reference: $this->referenceResolverRegistry->resolve($descriptor),
        );
    }

    private function restoreRunEntry(
        NavigationMatrixRule $rule,
        ?int $restoreRunId,
        ?int $tenantId,
    ): ?RelatedContextEntry {
        if ($restoreRunId === null || $restoreRunId <= 0 || $tenantId === null || $tenantId <= 0) {
            return null;
        }

        $restoreRun = RestoreRun::query()
            ->with('tenant')
            ->whereKey($restoreRunId)
            ->where('managed_environment_id', $tenantId)
            ->first();

        if (! $restoreRun instanceof RestoreRun) {
            return $this->unavailableEntry($rule, (string) $restoreRunId, 'missing');
        }

        if (! $this->canOpenTenantRecord($restoreRun->tenant, Capabilities::TENANT_VIEW)) {
            return $this->unavailableEntry($rule, '#'.$restoreRunId, 'unauthorized');
        }

        return RelatedContextEntry::available(
            key: $rule->relationKey,
            label: $this->labels->entryLabel($rule->relationKey),
            value: 'Restore run',
            secondaryValue: '#'.$restoreRun->getKey(),
            targetUrl: RestoreRunResource::getUrl('view', ['record' => $restoreRun], tenant: $restoreRun->tenant),
            targetKind: $rule->targetType,
            priority: $rule->priority,
            actionLabel: $this->labels->actionLabel($rule->relationKey),
            contextBadge: 'ManagedEnvironment',
        );
    }

    private function operationsEntry(
        NavigationMatrixRule $rule,
        ?ManagedEnvironment $tenant,
        ?CanonicalNavigationContext $context = null,
    ): ?RelatedContextEntry {
        if (! $tenant instanceof ManagedEnvironment) {
            return null;
        }

        if (! $this->canOpenTenantRecord($tenant, Capabilities::TENANT_VIEW)) {
            return null;
        }

        return RelatedContextEntry::available(
            key: $rule->relationKey,
            label: $this->labels->entryLabel($rule->relationKey),
            value: OperationRunLinks::collectionLabel(),
            secondaryValue: $tenant->name,
            targetUrl: OperationRunLinks::index($tenant, $context),
            targetKind: $rule->targetType,
            priority: $rule->priority,
            actionLabel: $this->labels->actionLabel($rule->relationKey),
            contextBadge: 'ManagedEnvironment context',
        );
    }

    private function unavailableEntry(NavigationMatrixRule $rule, ?string $referenceValue, string $reason): ?RelatedContextEntry
    {
        if ($rule->missingStatePolicy === 'hide') {
            return null;
        }

        return RelatedContextEntry::unavailable(
            key: $rule->relationKey,
            label: $this->labels->entryLabel($rule->relationKey),
            state: new UnavailableRelationState(
                relationKey: $rule->relationKey,
                referenceValue: $referenceValue,
                reason: $reason,
                message: $this->labels->unavailableMessage($rule->relationKey, $reason),
                showReference: $rule->missingStatePolicy === 'show_reference_only',
            ),
            targetKind: $rule->targetType,
            priority: $rule->priority,
            actionLabel: $this->labels->actionLabel($rule->relationKey),
        );
    }

    private function canOpenOperationRun(OperationRun $run): bool
    {
        $user = auth()->user();

        return $user instanceof User && $user->can('view', $run);
    }

    private function canOpenWorkspaceBaselines(int $workspaceId): bool
    {
        $user = auth()->user();

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

        $workspace = Workspace::query()->whereKey($workspaceId)->first();

        if (! $workspace instanceof Workspace) {
            return false;
        }

        return $this->workspaceCapabilityResolver->isMember($user, $workspace)
            && $this->workspaceCapabilityResolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_VIEW);
    }

    private function canOpenTenantRecord(?ManagedEnvironment $tenant, string $capability): bool
    {
        $user = auth()->user();

        return $tenant instanceof ManagedEnvironment
            && $user instanceof User
            && $this->capabilityResolver->isMember($user, $tenant)
            && $this->capabilityResolver->can($user, $tenant, $capability);
    }

    private function canOpenPolicyVersion(PolicyVersion $version): bool
    {
        $tenant = $version->tenant;

        if (! $tenant instanceof ManagedEnvironment || ! $this->canOpenTenantRecord($tenant, Capabilities::TENANT_VIEW)) {
            return false;
        }

        if (in_array((string) $version->capture_purpose?->value, ['baseline_capture', 'baseline_compare'], true)) {
            $user = auth()->user();

            return $user instanceof User
                && $this->capabilityResolver->isMember($user, $tenant)
                && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_SYNC);
        }

        return true;
    }

    private function canOpenPolicy(Policy $policy): bool
    {
        return $this->canOpenTenantRecord($policy->tenant, Capabilities::TENANT_VIEW);
    }

    private function contextForFinding(Finding $finding, string $surface): CanonicalNavigationContext
    {
        $tenant = $finding->tenant;
        $backLabel = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW ? 'Back to findings' : 'Back to finding';
        $backUrl = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW
            ? FindingResource::getUrl('index', tenant: $tenant)
            : FindingResource::getUrl('view', ['record' => $finding], tenant: $tenant);

        return new CanonicalNavigationContext(
            sourceSurface: 'finding.'.$surface,
            canonicalRouteName: 'admin.operations.view',
            tenantId: $tenant?->getKey(),
            backLinkLabel: $backLabel,
            backLinkUrl: $backUrl,
            filterPayload: $tenant instanceof ManagedEnvironment ? [
                'tableFilters' => [
                    'managed_environment_id' => ['value' => (string) $tenant->getKey()],
                ],
            ] : [],
        );
    }

    private function contextForPolicyVersion(PolicyVersion $version, string $surface): CanonicalNavigationContext
    {
        $tenant = $version->tenant;
        $backLabel = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW ? 'Back to policy versions' : 'Back to policy version';
        $backUrl = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW
            ? PolicyVersionResource::getUrl('index', tenant: $tenant)
            : PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $tenant);

        return new CanonicalNavigationContext(
            sourceSurface: 'policy_version.'.$surface,
            canonicalRouteName: 'admin.operations.view',
            tenantId: $tenant?->getKey(),
            backLinkLabel: $backLabel,
            backLinkUrl: $backUrl,
            filterPayload: $tenant instanceof ManagedEnvironment ? [
                'tableFilters' => [
                    'managed_environment_id' => ['value' => (string) $tenant->getKey()],
                ],
            ] : [],
        );
    }

    private function contextForBaselineSnapshot(BaselineSnapshot $snapshot, string $surface): CanonicalNavigationContext
    {
        $backLabel = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW ? 'Back to baseline snapshots' : 'Back to baseline snapshot';
        $backUrl = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW
            ? BaselineSnapshotResource::getUrl(panel: 'admin')
            : BaselineSnapshotResource::getUrl('view', ['record' => $snapshot], panel: 'admin');

        return new CanonicalNavigationContext(
            sourceSurface: 'baseline_snapshot.'.$surface,
            canonicalRouteName: 'admin.operations.view',
            backLinkLabel: $backLabel,
            backLinkUrl: $backUrl,
        );
    }

    private function contextForBackupSet(BackupSet $backupSet, string $surface): CanonicalNavigationContext
    {
        $tenant = $backupSet->tenant;
        $backLabel = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW ? 'Back to backup sets' : 'Back to backup set';
        $backUrl = $surface === CrossResourceNavigationMatrix::SURFACE_LIST_ROW
            ? BackupSetResource::getUrl('index', tenant: $tenant)
            : BackupSetResource::getUrl('view', ['record' => $backupSet], tenant: $tenant);

        return new CanonicalNavigationContext(
            sourceSurface: 'backup_set.'.$surface,
            canonicalRouteName: 'admin.operations.view',
            tenantId: $tenant?->getKey(),
            backLinkLabel: $backLabel,
            backLinkUrl: $backUrl,
            filterPayload: $tenant instanceof ManagedEnvironment ? [
                'tableFilters' => [
                    'managed_environment_id' => ['value' => (string) $tenant->getKey()],
                ],
            ] : [],
        );
    }

    private function contextForOperationRun(OperationRun $run): CanonicalNavigationContext
    {
        $tenant = $run->tenant;

        return new CanonicalNavigationContext(
            sourceSurface: 'operation_run.detail_section',
            canonicalRouteName: 'admin.operations.index',
            tenantId: $tenant?->getKey(),
            backLinkLabel: 'Back to operations',
            backLinkUrl: OperationRunLinks::index($tenant),
            filterPayload: $tenant instanceof ManagedEnvironment ? [
                'tableFilters' => [
                    'managed_environment_id' => ['value' => (string) $tenant->getKey()],
                ],
            ] : [],
        );
    }

    private function activeEnvironmentId(): ?int
    {
        $tenant = app(OperateHubShell::class)->activeEntitledTenant(request());

        return $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : null;
    }
}
