<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Filament\Resources\BaselineProfileResource;
use App\Filament\Resources\FindingResource;
use App\Models\BaselineProfile;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Auth\CapabilityResolver;
use App\Services\Baselines\BaselineCompareService;
use App\Support\Auth\Capabilities;
use App\Support\Baselines\BaselineCaptureMode;
use App\Support\Baselines\BaselineCompareEvidenceGapDetails;
use App\Support\Baselines\BaselineCompareStats;
use App\Support\Baselines\TenantGovernanceAggregate;
use App\Support\Baselines\TenantGovernanceAggregateResolver;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\Navigation\NavigationScope;
use App\Support\OperationRunLinks;
use App\Support\OperationRunType;
use App\Support\OpsUx\OperationUxPresenter;
use App\Support\OpsUx\OpsUxBrowserEvents;
use App\Support\Rbac\UiEnforcement;
use App\Support\ReasonTranslation\ReasonPresenter;
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
use App\Support\Workspaces\WorkspaceContext;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Database\Eloquent\Model;
use Livewire\Attributes\Locked;
use UnitEnum;

class BaselineCompareLanding extends Page
{
    protected const MONITORING_PAGE_STATE_CONTRACT = [
        'surfaceKey' => 'baseline_compare_landing',
        'surfaceType' => 'launch_context_support',
        'stateFields' => [
            [
                'stateKey' => 'baseline_profile_id',
                'stateClass' => 'contextual_prefilter',
                'carrier' => 'query_param',
                'queryRole' => 'scoped_deeplink',
                'shareable' => true,
                'restorableOnRefresh' => true,
                'tenantSensitive' => false,
                'invalidFallback' => 'discard_and_continue',
            ],
            [
                'stateKey' => 'subject_key',
                'stateClass' => 'contextual_prefilter',
                'carrier' => 'query_param',
                'queryRole' => 'scoped_deeplink',
                'shareable' => true,
                'restorableOnRefresh' => true,
                'tenantSensitive' => false,
                'invalidFallback' => 'discard_and_continue',
            ],
            [
                'stateKey' => 'nav',
                'stateClass' => 'contextual_prefilter',
                'carrier' => 'query_param',
                'queryRole' => 'durable_restorable',
                'shareable' => true,
                'restorableOnRefresh' => true,
                'tenantSensitive' => false,
                'invalidFallback' => 'discard_and_continue',
            ],
        ],
        'hydrationRule' => [
            'precedenceOrder' => ['query', 'default'],
            'appliesOnInitialMountOnly' => true,
            'activeStateBecomesAuthoritativeAfterMount' => true,
            'clearsOnTenantSwitch' => ['baseline_profile_id', 'subject_key', 'nav'],
            'invalidRequestedStateFallback' => 'discard_and_continue',
        ],
        'inspectContract' => [
            'primaryModel' => 'none',
            'selectedStateKey' => null,
            'openedBy' => ['launch_context'],
            'presentation' => 'none',
            'shareable' => true,
            'invalidSelectionFallback' => 'discard_and_continue',
        ],
        'shareableStateKeys' => ['baseline_profile_id', 'subject_key', 'nav'],
        'localOnlyStateKeys' => [],
    ];

    private const LEGACY_SCOPE_QUERY_KEYS = [
        'environment_id',
        'tenant',
        'tenant_id',
        'managed_environment_id',
        'environment',
        'tenant_scope',
        'tableFilters',
    ];

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-scale';

    protected static string|UnitEnum|null $navigationGroup = 'Governance';

    protected static ?string $navigationLabel = 'Baseline Compare';

    protected static ?int $navigationSort = 10;

    protected static ?string $title = 'Baseline Compare';

    protected static ?string $slug = 'workspaces/{workspace}/environments/{environment}/baseline-compare';

    protected string $view = 'filament.pages.baseline-compare-landing';

    public static function shouldRegisterNavigation(): bool
    {
        return NavigationScope::shouldRegisterEnvironmentNavigation()
            && parent::shouldRegisterNavigation();
    }

    public ?string $state = null;

    public ?string $message = null;

    public ?string $reasonCode = null;

    public ?string $reasonMessage = null;

    public ?string $profileName = null;

    public ?int $profileId = null;

    public ?int $snapshotId = null;

    public ?int $duplicateNamePoliciesCount = null;

    public ?int $duplicateNameSubjectsCount = null;

    public ?int $operationRunId = null;

    public ?int $findingsCount = null;

    /** @var array<string, int>|null */
    public ?array $severityCounts = null;

    public ?string $lastComparedAt = null;

    public ?string $lastComparedIso = null;

    public ?string $failureReason = null;

    public ?string $coverageStatus = null;

    public ?int $uncoveredTypesCount = null;

    /** @var list<string>|null */
    public ?array $uncoveredTypes = null;

    public ?string $fidelity = null;

    public ?int $evidenceGapsCount = null;

    /** @var array<string, int>|null */
    public ?array $evidenceGapsTopReasons = null;

    /** @var array<string, mixed>|null */
    public ?array $evidenceGapSummary = null;

    /** @var list<array<string, mixed>>|null */
    public ?array $evidenceGapBuckets = null;

    /** @var array<string, mixed>|null */
    public ?array $baselineCompareDiagnostics = null;

    /** @var array<string, int>|null */
    public ?array $rbacRoleDefinitionSummary = null;

    /** @var array<string, mixed>|null */
    public ?array $operatorExplanation = null;

    /** @var array<string, mixed>|null */
    public ?array $summaryAssessment = null;

    /** @var array<string, mixed>|null */
    public ?array $navigationContextPayload = null;

    public ?int $matrixBaselineProfileId = null;

    public ?string $matrixSubjectKey = null;

    #[Locked]
    public ?int $scopedEnvironmentId = null;

    /**
     * @param  array<mixed>  $parameters
     */
    public static function getUrl(array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null): string
    {
        $panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';

        if ($panelId !== 'admin') {
            return parent::getUrl($parameters, $isAbsolute, $panelId, $tenant);
        }

        $environment = static::resolveAdminUrlEnvironment($parameters, $tenant);

        if (! $environment instanceof ManagedEnvironment) {
            return url('/admin');
        }

        $workspace = static::resolveAdminUrlWorkspace($environment, $parameters);

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

        $parameters = static::withoutLegacyScopeQuery($parameters);
        $parameters['environment'] = $environment;
        $parameters['workspace'] = $workspace instanceof Workspace
            ? static::workspaceRouteKey($workspace)
            : $workspace;

        return parent::getUrl($parameters, $isAbsolute, $panelId, null);
    }

    public static function canAccess(): bool
    {
        return static::hasEnvironmentAccess(static::resolveRouteOwnedEnvironment());
    }

    /**
     * @return array<string, mixed>
     */
    public static function monitoringPageStateContract(): array
    {
        return self::MONITORING_PAGE_STATE_CONTRACT;
    }

    public function mount(ManagedEnvironment|string|null $environment = null): void
    {
        $tenant = static::resolveRouteOwnedEnvironment($environment);

        if (! $tenant instanceof ManagedEnvironment || ! static::hasEnvironmentAccess($tenant)) {
            abort(404);
        }

        $this->scopedEnvironmentId = (int) $tenant->getKey();
        $this->navigationContextPayload = is_array(request()->query('nav')) ? request()->query('nav') : null;
        $baselineProfileId = request()->query('baseline_profile_id');
        $subjectKey = request()->query('subject_key');

        $this->matrixBaselineProfileId = is_numeric($baselineProfileId) ? (int) $baselineProfileId : null;
        $this->matrixSubjectKey = is_string($subjectKey) && trim($subjectKey) !== '' ? trim($subjectKey) : null;
        $this->refreshStatsForEnvironment($tenant);
    }

    public function refreshStats(): void
    {
        $this->refreshStatsForEnvironment($this->currentEnvironment());
    }

    private function refreshStatsForEnvironment(?ManagedEnvironment $tenant): void
    {
        $stats = BaselineCompareStats::forTenant($tenant);
        $aggregate = $tenant instanceof ManagedEnvironment
            ? $this->governanceAggregate($tenant, $stats)
            : null;

        $this->state = $stats->state;
        $this->message = $stats->message;
        $this->profileName = $stats->profileName;
        $this->profileId = $stats->profileId;
        $this->snapshotId = $stats->snapshotId;
        $this->duplicateNamePoliciesCount = $stats->duplicateNamePoliciesCount;
        $this->duplicateNameSubjectsCount = $stats->duplicateNameSubjectsCount;
        $this->operationRunId = $stats->operationRunId;
        $this->findingsCount = $stats->findingsCount;
        $this->severityCounts = $stats->severityCounts !== [] ? $stats->severityCounts : null;
        $this->lastComparedAt = $stats->lastComparedHuman;
        $this->lastComparedIso = $stats->lastComparedIso;
        $this->failureReason = $stats->failureReason;
        $this->reasonCode = $stats->reasonCode;
        $this->reasonMessage = $stats->reasonMessage;

        $this->coverageStatus = $stats->coverageStatus;
        $this->uncoveredTypesCount = $stats->uncoveredTypesCount;
        $this->uncoveredTypes = $stats->uncoveredTypes !== [] ? $stats->uncoveredTypes : null;
        $this->fidelity = $stats->fidelity;

        $this->evidenceGapsCount = $stats->evidenceGapsCount;
        $this->evidenceGapsTopReasons = $stats->evidenceGapsTopReasons !== [] ? $stats->evidenceGapsTopReasons : null;
        $this->evidenceGapSummary = is_array($stats->evidenceGapDetails['summary'] ?? null)
            ? $stats->evidenceGapDetails['summary']
            : null;
        $this->evidenceGapBuckets = is_array($stats->evidenceGapDetails['buckets'] ?? null) && $stats->evidenceGapDetails['buckets'] !== []
            ? $stats->evidenceGapDetails['buckets']
            : null;
        $this->baselineCompareDiagnostics = $stats->baselineCompareDiagnostics !== []
            ? $stats->baselineCompareDiagnostics
            : null;
        $this->rbacRoleDefinitionSummary = $stats->rbacRoleDefinitionSummary !== [] ? $stats->rbacRoleDefinitionSummary : null;
        $this->operatorExplanation = $stats->operatorExplanation()->toArray();
        $this->summaryAssessment = $aggregate?->summaryAssessment->toArray();
    }

    /**
     * Computed view data exposed to the Blade template.
     *
     * Moves presentational logic out of Blade `@php` blocks so the
     * template only receives ready-to-render values.
     *
     * @return array<string, mixed>
     */
    protected function getViewData(): array
    {
        $evidenceGapSummary = is_array($this->evidenceGapSummary) ? $this->evidenceGapSummary : [];
        $reasonPresenter = app(ReasonPresenter::class);
        $reasonSemantics = $reasonPresenter->semantics(
            $reasonPresenter->forArtifactTruth($this->reasonCode, 'baseline_compare_landing'),
        );
        $hasCoverageWarnings = in_array($this->coverageStatus, ['warning', 'unproven'], true);
        $evidenceGapsCountValue = is_numeric($evidenceGapSummary['count'] ?? null)
            ? (int) $evidenceGapSummary['count']
            : (int) ($this->evidenceGapsCount ?? 0);
        $hasEvidenceGaps = $evidenceGapsCountValue > 0;
        $hasWarnings = $hasCoverageWarnings || $hasEvidenceGaps;
        $hasRbacRoleDefinitionSummary = is_array($this->rbacRoleDefinitionSummary)
            && array_sum($this->rbacRoleDefinitionSummary) > 0;
        $evidenceGapDetailState = is_string($evidenceGapSummary['detail_state'] ?? null)
            ? (string) $evidenceGapSummary['detail_state']
            : 'no_gaps';
        $hasEvidenceGapDetailSection = $evidenceGapDetailState !== 'no_gaps';
        $hasEvidenceGapDiagnostics = is_array($this->baselineCompareDiagnostics) && $this->baselineCompareDiagnostics !== [];

        $evidenceGapsSummary = null;
        $evidenceGapsTooltip = null;

        if ($hasEvidenceGaps) {
            $parts = array_map(
                static fn (array $reason): string => $reason['reason_label'].' ('.$reason['count'].')',
                BaselineCompareEvidenceGapDetails::topReasons(
                    is_array($evidenceGapSummary['by_reason'] ?? null) ? $evidenceGapSummary['by_reason'] : [],
                    5,
                ),
            );

            if ($parts !== []) {
                $evidenceGapsSummary = implode(', ', $parts);
                $evidenceGapsTooltip = __('baseline-compare.evidence_gaps_tooltip', ['summary' => $evidenceGapsSummary]);
            }
        }

        // Derive the colour class for the findings-count stat card.
        // Only show danger-red when high-severity findings exist;
        // use warning-orange for low/medium-only, and success-green for zero.
        $findingsColorClass = $this->resolveFindingsColorClass($hasWarnings);

        // "Why no findings" explanation when count is zero.
        $whyNoFindingsMessage = filled($this->reasonMessage) ? (string) $this->reasonMessage : null;
        $whyNoFindingsFallback = ! $hasWarnings
            ? __('baseline-compare.no_findings_all_clear')
            : ($hasCoverageWarnings
                ? __('baseline-compare.no_findings_coverage_warnings')
                : ($hasEvidenceGaps
                    ? __('baseline-compare.no_findings_evidence_gaps')
                    : __('baseline-compare.no_findings_default')));
        $whyNoFindingsColor = $hasWarnings
            ? 'text-warning-600 dark:text-warning-400'
            : 'text-success-600 dark:text-success-400';

        if ($this->reasonCode === 'no_subjects_in_scope') {
            $whyNoFindingsColor = 'text-gray-600 dark:text-gray-400';
        }

        return [
            'navigationContext' => $this->navigationContext()?->toQuery()['nav'] ?? null,
            'matrixBaselineProfileId' => $this->matrixBaselineProfileId,
            'matrixSubjectKey' => $this->matrixSubjectKey,
            'openCompareMatrixUrl' => $this->openCompareMatrixUrl(),
            'hasCoverageWarnings' => $hasCoverageWarnings,
            'evidenceGapsCountValue' => $evidenceGapsCountValue,
            'hasEvidenceGaps' => $hasEvidenceGaps,
            'hasWarnings' => $hasWarnings,
            'hasRbacRoleDefinitionSummary' => $hasRbacRoleDefinitionSummary,
            'evidenceGapDetailState' => $evidenceGapDetailState,
            'hasEvidenceGapDetailSection' => $hasEvidenceGapDetailSection,
            'hasEvidenceGapDiagnostics' => $hasEvidenceGapDiagnostics,
            'evidenceGapsSummary' => $evidenceGapsSummary,
            'evidenceGapsTooltip' => $evidenceGapsTooltip,
            'findingsColorClass' => $findingsColorClass,
            'whyNoFindingsMessage' => $whyNoFindingsMessage,
            'whyNoFindingsFallback' => $whyNoFindingsFallback,
            'whyNoFindingsColor' => $whyNoFindingsColor,
            'summaryAssessment' => is_array($this->summaryAssessment) ? $this->summaryAssessment : null,
            'reasonSemantics' => $reasonSemantics,
        ];
    }

    /**
     * Resolve the Tailwind colour class for the Total Findings stat.
     *
     * - Red (danger) only when high-severity findings exist
     * - Orange (warning) for medium/low-only findings or when warnings present
     * - Green (success) when fully clear
     */
    private function resolveFindingsColorClass(bool $hasWarnings): string
    {
        $count = (int) ($this->findingsCount ?? 0);

        if ($count === 0) {
            return $hasWarnings
                ? 'text-warning-600 dark:text-warning-400'
                : 'text-success-600 dark:text-success-400';
        }

        $hasHigh = ($this->severityCounts['high'] ?? 0) > 0;

        return $hasHigh
            ? 'text-danger-600 dark:text-danger-400'
            : 'text-warning-600 dark:text-warning-400';
    }

    public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration
    {
        return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::ListOnlyReadOnly)
            ->satisfy(ActionSurfaceSlot::ListHeader, 'Header action: Compare Now (confirmation modal, capability-gated).')
            ->exempt(ActionSurfaceSlot::InspectAffordance, 'This is a tenant-scoped landing page, not a record inspect surface.')
            ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'This page does not render table rows with secondary actions.')
            ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'This page has no bulk actions.')
            ->satisfy(ActionSurfaceSlot::ListEmptyState, 'Page renders explicit empty states for missing tenant, missing assignment, and missing snapshot, with guidance messaging.')
            ->exempt(ActionSurfaceSlot::DetailHeader, 'This page does not have a record detail header; it uses a page header action instead.');
    }

    /**
     * @return array<Action>
     */
    protected function getHeaderActions(): array
    {
        $actions = [];
        $navigationContext = $this->navigationContext();

        if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) {
            $actions[] = Action::make('backToOrigin')
                ->label($navigationContext->backLinkLabel)
                ->color('gray')
                ->url($navigationContext->backLinkUrl);
        }

        $actions[] = $this->compareNowAction();

        return $actions;
    }

    private function compareNowAction(): Action
    {
        $isFullContent = false;

        if (is_int($this->profileId) && $this->profileId > 0) {
            $profile = \App\Models\BaselineProfile::query()->find($this->profileId);
            $mode = $profile?->capture_mode instanceof BaselineCaptureMode
                ? $profile->capture_mode
                : (is_string($profile?->capture_mode) ? BaselineCaptureMode::tryFrom($profile->capture_mode) : null);

            $isFullContent = $mode === BaselineCaptureMode::FullContent;
        }

        $label = $isFullContent ? 'Compare now (full content)' : 'Compare now';
        $modalDescription = $isFullContent
            ? 'This will refresh content evidence on demand (redacted) before comparing the current tenant inventory against the assigned baseline snapshot.'
            : 'This will compare the current tenant inventory against the assigned baseline snapshot and generate drift findings.';

        $action = Action::make('compareNow')
            ->label($label)
            ->icon('heroicon-o-play')
            ->requiresConfirmation()
            ->modalHeading($label)
            ->modalDescription($modalDescription)
            ->disabled(fn (): bool => ! in_array($this->state, ['idle', 'ready', 'failed'], true))
            ->action(function (): void {
                $user = auth()->user();

                if (! $user instanceof User) {
                    Notification::make()->title('Not authenticated')->danger()->send();

                    return;
                }

                $tenant = $this->currentEnvironment();

                if (! $tenant instanceof ManagedEnvironment) {
                    Notification::make()->title('Open an environment to compare baselines')->danger()->send();

                    return;
                }

                $service = app(BaselineCompareService::class);
                $result = $service->startCompare($tenant, $user);

                if (! ($result['ok'] ?? false)) {
                    $reasonCode = is_string($result['reason_code'] ?? null) ? (string) $result['reason_code'] : 'unknown';
                    $translation = is_array($result['reason_translation'] ?? null) ? $result['reason_translation'] : [];

                    $message = is_string($translation['short_explanation'] ?? null) && trim((string) $translation['short_explanation']) !== ''
                        ? trim((string) $translation['short_explanation'])
                        : match ($reasonCode) {
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_ROLLOUT_DISABLED => 'Full-content baseline compare is currently disabled for controlled rollout.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_PROFILE_NOT_ACTIVE => 'The assigned baseline profile is not active.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_NO_ACTIVE_SNAPSHOT,
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_NO_CONSUMABLE_SNAPSHOT => 'No complete baseline snapshot is currently available for compare.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_SNAPSHOT_BUILDING => 'The latest baseline capture is still building. Compare will be available after it completes.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_SNAPSHOT_INCOMPLETE => 'The latest baseline capture is incomplete. Capture a new baseline before comparing.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_SNAPSHOT_SUPERSEDED => 'A newer complete baseline snapshot is current. Compare uses the latest complete baseline only.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_INVALID_SCOPE => 'The assigned baseline scope is invalid and must be reviewed before compare can start.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_UNSUPPORTED_SCOPE => 'The selected governed subjects are not supported by any compare strategy.',
                            \App\Support\Baselines\BaselineReasonCodes::COMPARE_MIXED_SCOPE => 'The selected governed subjects span multiple compare strategy families and must be narrowed before compare can start.',
                            default => 'Reason: '.$reasonCode,
                        };

                    Notification::make()
                        ->title('Cannot start comparison')
                        ->body($message)
                        ->danger()
                        ->send();

                    return;
                }

                $run = $result['run'] ?? null;

                if ($run instanceof OperationRun) {
                    $this->operationRunId = (int) $run->getKey();
                }

                $this->state = 'comparing';

                OpsUxBrowserEvents::dispatchRunEnqueued($this);

                OperationUxPresenter::queuedToast($run instanceof OperationRun ? (string) $run->type : OperationRunType::BaselineCompare->value)
                    ->actions($run instanceof OperationRun ? [
                        Action::make('view_run')
                            ->label('Open operation')
                            ->url(OperationRunLinks::view($run, $tenant, $this->navigationContext())),
                    ] : [])
                    ->send();
            });

        return UiEnforcement::forAction($action)
            ->requireCapability(Capabilities::TENANT_SYNC)
            ->preserveDisabled()
            ->apply();
    }

    public function getFindingsUrl(): ?string
    {
        $tenant = $this->currentEnvironment();

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

        return FindingResource::getUrl('index', tenant: $tenant);
    }

    public function getRunUrl(): ?string
    {
        if ($this->operationRunId === null) {
            return null;
        }

        $tenant = $this->currentEnvironment();

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

        return OperationRunLinks::view($this->operationRunId, $tenant);
    }

    public function openCompareMatrixUrl(): ?string
    {
        $profile = $this->resolveCompareMatrixProfile();

        if (! $profile instanceof BaselineProfile) {
            return null;
        }

        $url = BaselineProfileResource::compareMatrixUrl($profile);
        $query = array_filter([
            'subject_key' => $this->matrixSubjectKey,
        ], static fn (mixed $value): bool => $value !== null && $value !== '');

        if ($query === []) {
            return $url;
        }

        return $url.(str_contains($url, '?') ? '&' : '?').http_build_query($query);
    }

    private function governanceAggregate(ManagedEnvironment $tenant, BaselineCompareStats $stats): TenantGovernanceAggregate
    {
        /** @var TenantGovernanceAggregateResolver $resolver */
        $resolver = app(TenantGovernanceAggregateResolver::class);

        /** @var TenantGovernanceAggregate $aggregate */
        $aggregate = $resolver->fromStats($tenant, $stats);

        return $aggregate;
    }

    private function navigationContext(): ?CanonicalNavigationContext
    {
        if (! is_array($this->navigationContextPayload)) {
            return CanonicalNavigationContext::fromRequest(request());
        }

        return CanonicalNavigationContext::fromPayload($this->navigationContextPayload);
    }

    private function resolveCompareMatrixProfile(): ?BaselineProfile
    {
        $tenant = $this->currentEnvironment();

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

        $candidateIds = array_values(array_filter([
            $this->matrixBaselineProfileId,
            $this->profileId,
        ], static fn (mixed $value): bool => is_int($value) && $value > 0));

        foreach ($candidateIds as $profileId) {
            $profile = BaselineProfile::query()
                ->whereKey($profileId)
                ->where('workspace_id', (int) $tenant->workspace_id)
                ->first();

            if ($profile instanceof BaselineProfile) {
                return $profile;
            }
        }

        return null;
    }

    private function currentEnvironment(): ?ManagedEnvironment
    {
        if ($this->scopedEnvironmentId !== null) {
            $tenant = ManagedEnvironment::query()->whereKey($this->scopedEnvironmentId)->first();

            return $tenant instanceof ManagedEnvironment && static::hasEnvironmentAccess($tenant)
                ? $tenant
                : null;
        }

        $tenant = static::resolveRouteOwnedEnvironment();

        return $tenant instanceof ManagedEnvironment && static::hasEnvironmentAccess($tenant)
            ? $tenant
            : null;
    }

    protected static function resolveRouteOwnedEnvironment(ManagedEnvironment|string|null $environment = null): ?ManagedEnvironment
    {
        if ($environment instanceof ManagedEnvironment) {
            return $environment;
        }

        if (is_string($environment) && $environment !== '') {
            return ManagedEnvironment::query()
                ->where('slug', $environment)
                ->first();
        }

        $routeEnvironment = request()->route('environment');

        if ($routeEnvironment instanceof ManagedEnvironment) {
            return $routeEnvironment;
        }

        if (is_string($routeEnvironment) && $routeEnvironment !== '') {
            return ManagedEnvironment::query()
                ->where('slug', $routeEnvironment)
                ->first();
        }

        return static::resolveRefererOwnedEnvironment();
    }

    private static function hasEnvironmentAccess(?ManagedEnvironment $environment): bool
    {
        $user = auth()->user();

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

        $routeWorkspace = request()->route('workspace');

        if ($routeWorkspace instanceof Workspace && (int) $routeWorkspace->getKey() !== (int) $environment->workspace_id) {
            return false;
        }

        if (is_string($routeWorkspace) && $routeWorkspace !== '') {
            $workspace = $environment->workspace instanceof Workspace
                ? $environment->workspace
                : $environment->workspace()->first();

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

            if ($routeWorkspace !== static::workspaceRouteKey($workspace) && $routeWorkspace !== (string) $workspace->getKey()) {
                return false;
            }
        }

        $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request());

        if ($workspaceId !== null && (int) $workspaceId !== (int) $environment->workspace_id) {
            return false;
        }

        /** @var CapabilityResolver $resolver */
        $resolver = app(CapabilityResolver::class);

        return $resolver->isMember($user, $environment)
            && $resolver->can($user, $environment, Capabilities::TENANT_VIEW);
    }

    /**
     * @param  array<mixed>  $parameters
     */
    private static function resolveAdminUrlEnvironment(array $parameters, ?Model $tenant = null): ?ManagedEnvironment
    {
        $parameterEnvironment = $parameters['tenant'] ?? $parameters['environment'] ?? null;

        if ($parameterEnvironment instanceof ManagedEnvironment) {
            return $parameterEnvironment;
        }

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

        $routeEnvironment = static::resolveRouteOwnedEnvironment();

        if ($routeEnvironment instanceof ManagedEnvironment) {
            return $routeEnvironment;
        }

        $filamentTenant = Filament::getTenant();

        return $filamentTenant instanceof ManagedEnvironment ? $filamentTenant : null;
    }

    /**
     * @param  array<mixed>  $parameters
     */
    private static function resolveAdminUrlWorkspace(ManagedEnvironment $environment, array $parameters): Workspace|string|int|null
    {
        $workspace = $parameters['workspace'] ?? null;

        if ($workspace instanceof Workspace || is_string($workspace) || is_int($workspace)) {
            return $workspace;
        }

        $environmentWorkspace = $environment->workspace;

        if ($environmentWorkspace instanceof Workspace) {
            return $environmentWorkspace;
        }

        return $environment->workspace()->first();
    }

    /**
     * @param  array<mixed>  $parameters
     * @return array<mixed>
     */
    private static function withoutLegacyScopeQuery(array $parameters): array
    {
        foreach (self::LEGACY_SCOPE_QUERY_KEYS as $key) {
            unset($parameters[$key]);
        }

        return $parameters;
    }

    private static function workspaceRouteKey(Workspace $workspace): string
    {
        $slug = $workspace->getAttribute('slug');

        return is_string($slug) && $slug !== ''
            ? $slug
            : (string) $workspace->getKey();
    }

    private static function resolveRefererOwnedEnvironment(): ?ManagedEnvironment
    {
        $referer = request()->headers->get('referer');

        if (! is_string($referer) || $referer === '') {
            return null;
        }

        $path = parse_url($referer, PHP_URL_PATH);

        if (! is_string($path)) {
            return null;
        }

        if (preg_match('#^/admin/workspaces/([^/]+)/environments/([^/]+)/baseline-compare$#', $path, $matches) !== 1) {
            return null;
        }

        $workspaceRouteKey = rawurldecode($matches[1]);
        $environmentRouteKey = rawurldecode($matches[2]);

        $environment = ManagedEnvironment::query()
            ->where('slug', $environmentRouteKey)
            ->first();

        if (! $environment instanceof ManagedEnvironment) {
            return null;
        }

        $workspace = $environment->workspace;

        if (! $workspace instanceof Workspace) {
            $workspace = $environment->workspace()->first();
        }

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

        if ($workspaceRouteKey !== static::workspaceRouteKey($workspace) && $workspaceRouteKey !== (string) $workspace->getKey()) {
            return null;
        }

        return $environment;
    }
}
