<?php

declare(strict_types=1);

namespace App\Filament\Pages\Reviews;

use App\Filament\Resources\TenantReviewResource;
use App\Models\EvidenceSnapshot;
use App\Models\FindingException;
use App\Models\ReviewPack;
use App\Models\Tenant;
use App\Models\TenantReview;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Audit\WorkspaceAuditLogger;
use App\Services\TenantReviews\TenantReviewRegisterService;
use App\Support\Audit\AuditActionId;
use App\Support\Auth\Capabilities;
use App\Support\Findings\FindingOutcomeSemantics;
use App\Support\Filament\TablePaginationProfiles;
use App\Support\Governance\Controls\ComplianceEvidenceMappingV1;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\ReviewPackStatus;
use App\Support\TenantReviewCompletenessState;
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceInspectAffordance;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceType;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
use App\Support\Workspaces\WorkspaceContext;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Pages\Page;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use UnitEnum;

class CustomerReviewWorkspace extends Page implements HasTable
{
    use InteractsWithTable;

    public const string DETAIL_CONTEXT_QUERY_KEY = 'customer_workspace';

    public const string SOURCE_SURFACE = 'customer_review_workspace';

    protected static bool $isDiscovered = false;

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

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

    protected static ?string $navigationLabel = 'Customer reviews';

    protected static ?int $navigationSort = 44;

    protected static ?string $title = 'Customer Review Workspace';

    protected static ?string $slug = 'reviews/workspace';

    protected string $view = 'filament.pages.reviews.customer-review-workspace';

    public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration
    {
        return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::RunLog, ActionSurfaceType::ReadOnlyRegistryReport)
            ->satisfy(ActionSurfaceSlot::ListHeader, 'Header actions provide a single Clear filters action for the customer review workspace.')
            ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::PrimaryLinkColumn->value)
            ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'The customer review workspace remains scan-first and does not expose bulk actions.')
            ->satisfy(ActionSurfaceSlot::ListEmptyState, 'The empty state keeps exactly one Clear filters CTA when filters are active.')
            ->exempt(ActionSurfaceSlot::DetailHeader, 'The dedicated open link column opens the latest published review detail instead of an inline canonical detail panel.');
    }

    public static function getNavigationGroup(): string
    {
        return __('localization.review.reporting');
    }

    public static function getNavigationLabel(): string
    {
        return __('localization.review.customer_reviews');
    }

    public function getTitle(): string
    {
        return __('localization.review.customer_review_workspace');
    }

    public static function tenantPrefilterUrl(Tenant $tenant): string
    {
        $tenantIdentifier = filled($tenant->external_id)
            ? (string) $tenant->external_id
            : (string) $tenant->getKey();

        return static::getUrl(panel: 'admin').'?'.http_build_query([
            'tenant' => $tenantIdentifier,
        ]);
    }

    /**
     * @var array<int, Tenant>|null
     */
    private ?array $authorizedTenants = null;

    public function mount(): void
    {
        $this->authorizePageAccess();
        $this->applyRequestedTenantPrefilter();
        $this->mountInteractsWithTable();
        $this->auditWorkspaceOpen();
    }

    protected function getHeaderActions(): array
    {
        $actions = [];

        $governanceContext = $this->incomingGovernanceContext();

        if ($governanceContext?->backLinkUrl !== null) {
            $actions[] = Action::make('return_to_governance_inbox')
                ->label($governanceContext->backLinkLabel ?? 'Back to governance inbox')
                ->icon('heroicon-o-arrow-left')
                ->color('gray')
                ->url($governanceContext->backLinkUrl);
        }

        $actions[] = Action::make('clear_filters')
            ->label(__('localization.review.clear_filters'))
            ->icon('heroicon-o-x-mark')
            ->color('gray')
            ->visible(fn (): bool => $this->hasActiveFilters())
            ->action(function (): void {
                $this->clearWorkspaceFilters();
            });

        return $actions;
    }

    public function table(Table $table): Table
    {
        return $table
            ->query(fn (): Builder => $this->workspaceQuery())
            ->defaultSort('name')
            ->paginated(TablePaginationProfiles::customPage())
            ->persistFiltersInSession()
            ->persistSearchInSession()
            ->persistSortInSession()
            ->recordUrl(null)
            ->columns([
                TextColumn::make('name')->label(__('localization.review.tenant'))->searchable(),
                TextColumn::make('package_availability')
                    ->label(__('localization.review.governance_package'))
                    ->width('9rem')
                    ->extraHeaderAttributes(['class' => 'whitespace-normal'])
                    ->badge()
                    ->getStateUsing(fn (Tenant $record): string => $this->governancePackageAvailabilityLabel($record))
                    ->color(fn (Tenant $record): string => $this->governancePackageAvailabilityColor($record))
                    ->tooltip(fn (Tenant $record): string => $this->governancePackageAvailability($record)['description']),
                TextColumn::make('latest_review')
                    ->label(__('localization.review.status'))
                    ->width('9rem')
                    ->badge()
                    ->getStateUsing(fn (Tenant $record): string => $this->latestReviewStateLabel($record))
                    ->color(fn (Tenant $record): string => $this->latestReviewStateColor($record)),
                TextColumn::make('evidence_proof_state')
                    ->label(__('localization.review.evidence_status'))
                    ->width('8rem')
                    ->badge()
                    ->getStateUsing(fn (Tenant $record): string => $this->evidenceStatusLabel($record))
                    ->color(fn (Tenant $record): string => $this->evidenceStatusColor($record)),
                TextColumn::make('recommended_next_action')
                    ->label(__('localization.review.next_step'))
                    ->width('10rem')
                    ->extraHeaderAttributes(['class' => 'whitespace-normal'])
                    ->getStateUsing(fn (Tenant $record): string => $this->controlRecommendedNextAction($record))
                    ->wrap(),
                TextColumn::make('open_review')
                    ->label(__('localization.review.open'))
                    ->width('8rem')
                    ->getStateUsing(fn (): string => __('localization.review.open_review'))
                    ->url(fn (Tenant $record): ?string => $this->latestReviewUrl($record))
                    ->color('primary'),
            ])
            ->filters([
                SelectFilter::make('tenant_id')
                    ->label(__('localization.review.tenant'))
                    ->options(fn (): array => $this->tenantFilterOptions())
                    ->default(fn (): ?string => $this->defaultTenantFilter())
                    ->query(function (Builder $query, array $data): Builder {
                        $tenantId = $data['value'] ?? null;

                        return is_numeric($tenantId)
                            ? $query->whereKey((int) $tenantId)
                            : $query;
                    })
                    ->searchable(),
            ])
            ->actions([])
            ->bulkActions([])
            ->emptyStateHeading(__('localization.review.no_released_customer_reviews'))
            ->emptyStateDescription(fn (): string => $this->hasActiveFilters()
                ? __('localization.review.clear_filters_description')
                : __('localization.review.no_released_customer_reviews_description'))
            ->emptyStateActions([
                Action::make('clear_filters_empty')
                    ->label(__('localization.review.clear_filters'))
                    ->icon('heroicon-o-x-mark')
                    ->color('gray')
                    ->visible(fn (): bool => $this->hasActiveFilters())
                    ->action(fn (): mixed => $this->clearWorkspaceFilters()),
            ]);
    }

    /**
     * @return array<int, Tenant>
     */
    public function authorizedTenants(): array
    {
        if ($this->authorizedTenants !== null) {
            return $this->authorizedTenants;
        }

        $user = auth()->user();
        $workspace = $this->workspace();

        if (! $user instanceof User || ! $workspace instanceof Workspace) {
            return $this->authorizedTenants = [];
        }

        return $this->authorizedTenants = app(TenantReviewRegisterService::class)->authorizedTenants($user, $workspace);
    }

    private function authorizePageAccess(): void
    {
        $user = auth()->user();
        $workspace = $this->workspace();

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

        if (! $workspace instanceof Workspace) {
            throw new NotFoundHttpException;
        }

        $service = app(TenantReviewRegisterService::class);

        if (! $service->canAccessWorkspace($user, $workspace)) {
            throw new NotFoundHttpException;
        }

        if ($this->authorizedTenants() === []) {
            throw new NotFoundHttpException;
        }
    }

    private function auditWorkspaceOpen(): void
    {
        $user = auth()->user();
        $workspace = $this->workspace();

        if (! $user instanceof User || ! $workspace instanceof Workspace) {
            return;
        }

        app(WorkspaceAuditLogger::class)->log(
            workspace: $workspace,
            action: AuditActionId::CustomerReviewWorkspaceOpened,
            context: [
                'metadata' => [
                    'source_surface' => self::SOURCE_SURFACE,
                    'tenant_filter_id' => $this->currentTenantFilterId(),
                    'entitled_tenant_count' => count($this->authorizedTenants()),
                    'interpretation_version' => $this->currentTenantFilterInterpretationVersion(),
                    'interpretation_versions' => $this->visibleInterpretationVersions(),
                ],
            ],
            actor: $user,
            resourceType: 'customer_review_workspace',
            resourceId: (string) $workspace->getKey(),
            targetLabel: __('localization.review.customer_review_workspace'),
        );
    }

    private function workspaceQuery(): Builder
    {
        $user = auth()->user();
        $workspace = $this->workspace();

        if (! $user instanceof User || ! $workspace instanceof Workspace) {
            return Tenant::query()->whereRaw('1 = 0');
        }

        return app(TenantReviewRegisterService::class)->customerWorkspaceTenantQuery($user, $workspace);
    }

    /**
     * @return array<string, string>
     */
    private function tenantFilterOptions(): array
    {
        return collect($this->authorizedTenants())
            ->mapWithKeys(static fn (Tenant $tenant): array => [
                (string) $tenant->getKey() => $tenant->name,
            ])
            ->all();
    }

    private function defaultTenantFilter(): ?string
    {
        $tenantId = app(WorkspaceContext::class)->lastTenantId(request());

        return is_int($tenantId) && array_key_exists($tenantId, $this->authorizedTenants())
            ? (string) $tenantId
            : null;
    }

    private function applyRequestedTenantPrefilter(): void
    {
        $requestedTenant = request()->query('tenant', request()->query('tenant_id'));

        if (! is_string($requestedTenant) && ! is_numeric($requestedTenant)) {
            return;
        }

        foreach ($this->authorizedTenants() as $tenant) {
            if ((string) $tenant->getKey() !== (string) $requestedTenant && (string) $tenant->external_id !== (string) $requestedTenant) {
                continue;
            }

            $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey();
            $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey();

            return;
        }

        throw new NotFoundHttpException;
    }

    private function hasActiveFilters(): bool
    {
        return $this->currentTenantFilterId() !== null;
    }

    private function clearWorkspaceFilters(): void
    {
        app(WorkspaceContext::class)->clearLastTenantId(request());
        $this->removeTableFilters();
    }

    private function currentTenantFilterId(): ?int
    {
        $tenantFilter = data_get($this->tableFilters, 'tenant_id.value');

        if (! is_numeric($tenantFilter)) {
            $tenantFilter = data_get(session()->get($this->getTableFiltersSessionKey(), []), 'tenant_id.value');
        }

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

    private function workspace(): ?Workspace
    {
        $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request());

        return is_numeric($workspaceId)
            ? Workspace::query()->whereKey((int) $workspaceId)->first()
            : null;
    }

    private function latestPublishedReview(Tenant $tenant): ?TenantReview
    {
        $review = $tenant->tenantReviews->first();

        return $review instanceof TenantReview ? $review : null;
    }

    private function latestReviewUrl(Tenant $tenant): ?string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return null;
        }

        $query = array_filter(
            array_replace(
                [self::DETAIL_CONTEXT_QUERY_KEY => 1],
                [
                    'source_surface' => self::SOURCE_SURFACE,
                    'tenant_filter_id' => $this->currentTenantFilterId(),
                ],
                $this->navigationContext()?->toQuery() ?? [],
            ),
            static fn (mixed $value): bool => $value !== null && $value !== '',
        );

        return $this->appendQuery(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant, 'tenant'), $query);
    }

    private function latestPublishedAt(Tenant $tenant): ?\Illuminate\Support\Carbon
    {
        return $this->latestPublishedReview($tenant)?->published_at;
    }

    private function reviewTruth(Tenant $tenant): ?ArtifactTruthEnvelope
    {
        $review = $this->latestPublishedReview($tenant);

        return $review instanceof TenantReview
            ? app(ArtifactTruthPresenter::class)->forTenantReview($review)
            : null;
    }

    private function reviewOutcome(Tenant $tenant): ?CompressedGovernanceOutcome
    {
        $presenter = app(ArtifactTruthPresenter::class);
        $review = $this->latestPublishedReview($tenant);
        $truth = $this->reviewTruth($tenant);

        if (! $review instanceof TenantReview || ! $truth instanceof ArtifactTruthEnvelope) {
            return null;
        }

        return $presenter->compressedOutcomeFor($review, SurfaceCompressionContext::reviewRegister())
            ?? $presenter->compressedOutcomeFromEnvelope($truth, SurfaceCompressionContext::reviewRegister());
    }

    private function latestReviewStateLabel(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return __('localization.review.no_published_review');
        }

        return $this->workspaceReviewNeedsAttention($tenant)
            ? __('localization.review.review_requires_attention')
            : __('localization.review.ready_for_release');
    }

    private function latestReviewStateColor(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return 'gray';
        }

        $packageState = $this->governancePackageAvailability($tenant)['state'];

        if (! $this->workspaceReviewNeedsAttention($tenant)) {
            return 'success';
        }

        return in_array($packageState, ['blocked', 'expired'], true)
            ? 'danger'
            : 'warning';
    }

    private function latestReviewStateIcon(Tenant $tenant): ?string
    {
        return $this->reviewOutcome($tenant)?->primaryBadge->icon;
    }

    private function latestReviewStateIconColor(Tenant $tenant): ?string
    {
        return $this->reviewOutcome($tenant)?->primaryBadge->iconColor;
    }

    private function reviewOutcomeDescription(Tenant $tenant): ?string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return __('localization.review.no_published_review_available');
        }

        $primaryReason = $this->reviewOutcome($tenant)?->primaryReason;
        $summary = is_array($review->summary) ? $review->summary : [];
        $findingOutcomes = $summary['finding_outcomes'] ?? null;

        if (! is_array($findingOutcomes)) {
            return $primaryReason;
        }

        $findingOutcomeSummary = app(FindingOutcomeSemantics::class)->compactOutcomeSummary($findingOutcomes);

        if ($findingOutcomeSummary === null) {
            return $primaryReason;
        }

        return trim($primaryReason.' '.__('localization.review.terminal_outcomes').': '.$findingOutcomeSummary.'.');
    }

    private function controlReadinessLabel(Tenant $tenant): string
    {
        $control = $this->primaryControlSummary($tenant);

        if ($control === null) {
            return __('localization.review.control_readiness_unmapped');
        }

        $label = $control['readiness_label'] ?? null;

        return is_string($label) && trim($label) !== ''
            ? $label
            : ComplianceEvidenceMappingV1::readinessLabel((string) ($control['readiness_bucket'] ?? 'review_recommended'));
    }

    /**
     * @return array<string, mixed>
     */
    private function governancePackageSummary(Tenant $tenant): array
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return [];
        }

        $summary = is_array($review->summary) ? $review->summary : [];
        $package = is_array($summary['governance_package'] ?? null) ? $summary['governance_package'] : [];

        return $package;
    }

    /**
     * @return array{state:string,label:string,description:string}
     */
    private function governancePackageAvailability(Tenant $tenant): array
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return [
                'state' => 'unavailable',
                'label' => __('localization.review.governance_package_unavailable'),
                'description' => __('localization.review.no_published_review_available'),
            ];
        }

        $pack = $review->currentExportReviewPack;
        $user = auth()->user();
        $limitations = is_array($review->controlInterpretation()['limitations'] ?? null) ? $review->controlInterpretation()['limitations'] : [];
        $isPartialReview = in_array((string) $review->completeness_state, [
            TenantReviewCompletenessState::Partial->value,
            TenantReviewCompletenessState::Stale->value,
        ], true) || $limitations !== [];

        if (! $pack instanceof ReviewPack) {
            return [
                'state' => 'unavailable',
                'label' => __('localization.review.governance_package_unavailable'),
                'description' => __('localization.review.governance_package_unavailable_description'),
            ];
        }

        if (! $user instanceof User || ! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) {
            return [
                'state' => 'blocked',
                'label' => __('localization.review.governance_package_blocked'),
                'description' => __('localization.review.governance_package_blocked_description'),
            ];
        }

        if ($pack->status === ReviewPackStatus::Expired->value || ($pack->expires_at !== null && $pack->expires_at->isPast())) {
            return [
                'state' => 'expired',
                'label' => __('localization.review.governance_package_expired'),
                'description' => __('localization.review.governance_package_expired_description'),
            ];
        }

        if ($pack->status !== ReviewPackStatus::Ready->value) {
            return [
                'state' => 'unavailable',
                'label' => __('localization.review.governance_package_unavailable'),
                'description' => __('localization.review.governance_package_not_ready_description'),
            ];
        }

        if ($isPartialReview) {
            return [
                'state' => 'partial',
                'label' => __('localization.review.governance_package_partial'),
                'description' => __('localization.review.governance_package_partial_description'),
            ];
        }

        return [
            'state' => 'available',
            'label' => __('localization.review.governance_package_available'),
            'description' => __('localization.review.governance_package_available_description'),
        ];
    }

    private function governancePackageAvailabilityLabel(Tenant $tenant): string
    {
        return match ($this->governancePackageAvailability($tenant)['state']) {
            'available' => __('localization.review.available'),
            'partial' => __('localization.review.partial'),
            'blocked' => __('localization.review.blocked'),
            'expired' => __('localization.review.expired'),
            default => __('localization.review.unavailable'),
        };
    }

    private function governancePackageAvailabilityColor(Tenant $tenant): string
    {
        return match ($this->governancePackageAvailability($tenant)['state']) {
            'available' => 'success',
            'partial' => 'warning',
            'blocked', 'expired' => 'danger',
            default => 'gray',
        };
    }

    private function governancePackageTeaser(Tenant $tenant): string
    {
        $package = $this->governancePackageSummary($tenant);

        $executiveSummary = $package['executive_summary'] ?? null;

        if (is_string($executiveSummary) && trim($executiveSummary) !== '') {
            return $executiveSummary;
        }

        return $this->governancePackageAvailability($tenant)['description'];
    }

    private function controlReadinessColor(Tenant $tenant): string
    {
        return match ((string) ($this->primaryControlSummary($tenant)['readiness_bucket'] ?? 'unmapped')) {
            'follow_up_required' => 'warning',
            'review_recommended' => 'info',
            'evidence_on_record' => 'success',
            default => 'gray',
        };
    }

    private function controlReadinessDescription(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return __('localization.review.no_published_review_available');
        }

        $controls = $review->controlInterpretationControls();

        if ($controls === []) {
            return __('localization.review.control_readiness_unmapped_description');
        }

        $summary = collect($controls)
            ->take(2)
            ->map(function (array $control): string {
                $name = is_string($control['control_name'] ?? null) ? $control['control_name'] : __('localization.review.control');
                $label = is_string($control['readiness_label'] ?? null)
                    ? $control['readiness_label']
                    : ComplianceEvidenceMappingV1::readinessLabel((string) ($control['readiness_bucket'] ?? 'review_recommended'));

                return $name.': '.$label;
            })
            ->implode(' · ');

        $remaining = count($controls) - 2;

        if ($remaining > 0) {
            $summary .= ' · '.__('localization.review.additional_controls', ['count' => $remaining]);
        }

        $limitations = $this->controlLimitationSummary($review);

        return trim($summary.($limitations !== null ? ' '.$limitations : ''));
    }

    private function controlEvidenceBasisSummary(Tenant $tenant): string
    {
        $control = $this->primaryControlSummary($tenant);

        if ($control === null) {
            return __('localization.review.control_evidence_unmapped');
        }

        $summary = $control['evidence_basis_summary'] ?? null;

        return is_string($summary) && trim($summary) !== ''
            ? $summary
            : __('localization.review.control_evidence_unavailable');
    }

    private function controlRecommendedNextAction(Tenant $tenant): string
    {
        if ($this->primaryControlSummary($tenant) === null) {
            return __('localization.review.workspace_next_step_control_mapping');
        }

        if ($this->evidenceStatusState($tenant) !== 'available') {
            return __('localization.review.workspace_next_step_evidence_review');
        }

        return match ($this->governancePackageAvailability($tenant)['state']) {
            'available', 'partial' => __('localization.review.workspace_next_step_package_review'),
            default => __('localization.review.workspace_next_step_review_open'),
        };
    }

    private function workspaceReviewNeedsAttention(Tenant $tenant): bool
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return true;
        }

        if ($this->primaryControlSummary($tenant) === null) {
            return true;
        }

        if ($this->evidenceStatusState($tenant) !== 'available') {
            return true;
        }

        return $this->governancePackageAvailability($tenant)['state'] !== 'available';
    }

    private function evidenceStatusState(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return 'pending';
        }

        $snapshot = $review->evidenceSnapshot;
        $user = auth()->user();

        if (! $snapshot instanceof EvidenceSnapshot) {
            return 'pending';
        }

        if (! $user instanceof User || ! $user->can(Capabilities::EVIDENCE_VIEW, $tenant)) {
            return 'restricted';
        }

        if ((string) $snapshot->status === 'expired' || ($snapshot->expires_at !== null && $snapshot->expires_at->isPast())) {
            return 'expired';
        }

        return 'available';
    }

    private function evidenceStatusLabelForState(string $state): string
    {
        return match ($state) {
            'available' => __('localization.review.available'),
            'restricted' => __('localization.review.restricted'),
            'expired' => __('localization.review.expired'),
            default => __('localization.review.pending'),
        };
    }

    private function evidenceStatusColorForState(string $state): string
    {
        return match ($state) {
            'available' => 'success',
            'restricted', 'expired' => 'danger',
            default => 'gray',
        };
    }

    private function controlRecommendedNextActionDescription(Tenant $tenant): string
    {
        $control = $this->primaryControlSummary($tenant);

        if ($control === null) {
            return __('localization.review.control_recommendation_unmapped');
        }

        $action = $control['recommended_next_action'] ?? null;

        return is_string($action) && trim($action) !== ''
            ? $action
            : __('localization.review.no_action_needed');
    }

    /**
     * @return array<string, mixed>|null
     */
    private function primaryControlSummary(Tenant $tenant): ?array
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return null;
        }

        $controls = collect($review->controlInterpretationControls());

        return $controls
            ->sortBy(static fn (array $control): int => match ((string) ($control['readiness_bucket'] ?? '')) {
                'follow_up_required' => 0,
                'review_recommended' => 1,
                'evidence_on_record' => 2,
                default => 3,
            })
            ->first();
    }

    private function controlLimitationSummary(TenantReview $review): ?string
    {
        $counts = $review->controlInterpretationLimitationCounts();

        if ($counts === []) {
            return null;
        }

        $labels = collect($counts)
            ->filter(static fn (int $count): bool => $count > 0)
            ->keys()
            ->map(static fn (string $flag): string => ComplianceEvidenceMappingV1::limitationLabel($flag))
            ->values()
            ->all();

        return $labels === []
            ? null
            : __('localization.review.control_limitations_summary', ['limitations' => implode(', ', $labels)]);
    }

    private function findingSummary(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return __('localization.review.no_published_review_available');
        }

        $summary = is_array($review->summary) ? $review->summary : [];
        $findingCount = (int) ($summary['finding_count'] ?? 0);
        $findingOutcomes = is_array($summary['finding_outcomes'] ?? null) ? $summary['finding_outcomes'] : [];
        $terminalOutcomes = app(FindingOutcomeSemantics::class)->compactOutcomeSummary($findingOutcomes);

        if ($findingCount === 0) {
            return __('localization.review.no_findings_recorded');
        }

        if ($terminalOutcomes === null) {
            return __('localization.review.findings_count_summary', ['count' => $findingCount]);
        }

        return __('localization.review.findings_count_with_outcomes', [
            'count' => $findingCount,
            'outcomes' => $terminalOutcomes,
        ]);
    }

    private function acceptedRiskSummary(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return __('localization.review.no_published_review_available');
        }

        $summary = is_array($review->summary) ? $review->summary : [];
        $riskAcceptance = is_array($summary['risk_acceptance'] ?? null) ? $summary['risk_acceptance'] : [];
        $statusMarkedCount = (int) ($riskAcceptance['status_marked_count'] ?? 0);
        $validGovernedCount = (int) ($riskAcceptance['valid_governed_count'] ?? 0);
        $warningCount = (int) ($riskAcceptance['warning_count'] ?? 0);

        $countSummary = match (true) {
            $statusMarkedCount === 0 => __('localization.review.no_accepted_risks_recorded'),
            $warningCount > 0 => __('localization.review.accepted_risks_need_follow_up', ['warnings' => $warningCount, 'total' => $statusMarkedCount]),
            $validGovernedCount > 0 => __('localization.review.accepted_risks_governed', ['count' => $validGovernedCount]),
            default => __('localization.review.accepted_risks_on_record', ['count' => $statusMarkedCount]),
        };

        $accountability = $this->acceptedRiskAccountability($tenant);

        return $accountability === null
            ? $countSummary
            : $countSummary.' '.$accountability;
    }

    private function evidenceProofAvailability(Tenant $tenant): string
    {
        $review = $this->latestPublishedReview($tenant);

        if (! $review instanceof TenantReview) {
            return __('localization.review.no_published_review_available');
        }

        $snapshot = $review->evidenceSnapshot;
        $user = auth()->user();

        if (! $snapshot instanceof EvidenceSnapshot) {
            return __('localization.review.evidence_proof_absent');
        }

        if (! $user instanceof User || ! $user->can(Capabilities::EVIDENCE_VIEW, $tenant)) {
            return __('localization.review.evidence_proof_access_unavailable');
        }

        if ((string) $snapshot->status === 'expired' || ($snapshot->expires_at !== null && $snapshot->expires_at->isPast())) {
            return __('localization.review.evidence_proof_expired');
        }

        return __('localization.review.evidence_proof_available');
    }

    private function evidenceStatusLabel(Tenant $tenant): string
    {
        return $this->evidenceStatusLabelForState($this->evidenceStatusState($tenant));
    }

    private function evidenceStatusColor(Tenant $tenant): string
    {
        return $this->evidenceStatusColorForState($this->evidenceStatusState($tenant));
    }

    /**
     * @return list<string>
     */
    private function visibleInterpretationVersions(): array
    {
        $user = auth()->user();
        $workspace = $this->workspace();

        if (! $user instanceof User || ! $workspace instanceof Workspace) {
            return [];
        }

        return app(TenantReviewRegisterService::class)
            ->latestPublishedQuery($user, $workspace)
            ->get()
            ->map(static fn (TenantReview $review): ?string => $review->controlInterpretationVersion())
            ->filter()
            ->unique()
            ->values()
            ->all();
    }

    private function currentTenantFilterInterpretationVersion(): ?string
    {
        $tenantId = $this->currentTenantFilterId();

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

        $tenant = $this->authorizedTenants()[$tenantId] ?? null;

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

        return $tenant->tenantReviews()->published()
            ->latest('published_at')
            ->latest('generated_at')
            ->latest('id')
            ->first()
            ?->controlInterpretationVersion();
    }

    private function acceptedRiskAccountability(Tenant $tenant): ?string
    {
        $exception = FindingException::query()
            ->with(['owner', 'approver', 'currentDecision'])
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->where('tenant_id', (int) $tenant->getKey())
            ->current()
            ->orderByRaw("case when current_validity_state in ('valid', 'expiring') then 0 else 1 end")
            ->latest('approved_at')
            ->latest('requested_at')
            ->latest('id')
            ->first();

        if (! $exception instanceof FindingException) {
            return null;
        }

        $accountable = $exception->owner?->name
            ?? $exception->approver?->name;
        $decisionType = $exception->currentDecision?->decision_type;
        $reviewDue = $exception->review_due_at ?? $exception->expires_at;
        $reason = is_string($exception->request_reason) ? trim($exception->request_reason) : '';
        $parts = [];

        if (is_string($accountable) && trim($accountable) !== '') {
            $parts[] = $reviewDue === null
                ? __('localization.review.accepted_risk_accountable', ['name' => $accountable])
                : __('localization.review.accepted_risk_accountable_until', [
                    'name' => $accountable,
                    'date' => $reviewDue->toDateString(),
                ]);
        } elseif (is_string($decisionType) && trim($decisionType) !== '') {
            $parts[] = __('localization.review.accepted_risk_partial_accountability');
        }

        if ($reason !== '') {
            $parts[] = __('localization.review.accepted_risk_reason', [
                'reason' => Str::limit($reason, 160),
            ]);
        }

        return $parts === [] ? null : implode(' ', $parts);
    }

    private function navigationContext(): ?CanonicalNavigationContext
    {
        return CanonicalNavigationContext::fromRequest(request());
    }

    private function incomingGovernanceContext(): ?CanonicalNavigationContext
    {
        $context = $this->navigationContext();

        return $context?->sourceSurface === 'governance.inbox'
            ? $context
            : null;
    }

    /**
     * @param  array<string, mixed>  $query
     */
    private function appendQuery(string $url, array $query): string
    {
        if ($query === []) {
            return $url;
        }

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