<?php

declare(strict_types=1);

namespace App\Filament\Resources\ManagedEnvironmentResource\Pages;

use App\Filament\Resources\ManagedEnvironmentResource;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Onboarding\OnboardingDraftResolver;
use App\Support\Tenants\TenantRecoveryTriagePresentation;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

class ListManagedEnvironments extends ListRecords
{
    protected static string $resource = ManagedEnvironmentResource::class;

    public function mount(): void
    {
        parent::mount();
        $this->applyRequestedTriageIntent();
    }

    protected function getHeaderActions(): array
    {
        return [
            $this->makeOnboardingEntryAction()
                ->visible(fn (): bool => $this->getTableRecords()->count() > 0),
        ];
    }

    protected function getTableEmptyStateActions(): array
    {
        $actions = [
            $this->makeOnboardingEntryAction(),
        ];

        if ($this->hasActiveTriageEmptyState()) {
            array_unshift($actions, $this->clearTriageFiltersAction());
        }

        return $actions;
    }

    protected function getTableEmptyStateHeading(): ?string
    {
        if ($this->hasActiveTriageEmptyState()) {
            return 'No visible tenants match this triage slice';
        }

        return parent::getTableEmptyStateHeading();
    }

    protected function getTableEmptyStateDescription(): ?string
    {
        if ($this->hasActiveTriageEmptyState()) {
            return 'Try a different backup posture, recovery evidence, or review-state filter, or return to the default calm-browsing order.';
        }

        return parent::getTableEmptyStateDescription();
    }

    private function makeOnboardingEntryAction(): Actions\Action
    {
        $descriptor = ManagedEnvironmentResource::tenantActionPolicy()->onboardingEntryDescriptor($this->accessibleResumableDraftCount());

        return Actions\Action::make('add_tenant')
            ->label($descriptor->label)
            ->icon($descriptor->icon)
            ->url(route('admin.onboarding'));
    }

    private function clearTriageFiltersAction(): Actions\Action
    {
        return Actions\Action::make('clear_triage_filters')
            ->label('Clear filters')
            ->icon('heroicon-o-funnel')
            ->color('gray')
            ->action('resetTableFiltersForm');
    }

    private function applyRequestedTriageIntent(): void
    {
        $hasIntent = request()->query->has('backup_posture')
            || request()->query->has('recovery_evidence')
            || request()->query->has('review_state')
            || request()->query->has('triage_sort');

        if (! $hasIntent) {
            return;
        }

        $backupPostures = ManagedEnvironmentResource::sanitizeBackupPostures(request()->query('backup_posture'));
        $recoveryEvidence = ManagedEnvironmentResource::sanitizeRecoveryEvidenceStates(request()->query('recovery_evidence'));
        $reviewStates = ManagedEnvironmentResource::sanitizeReviewStates(request()->query('review_state'));
        $triageSort = ManagedEnvironmentResource::sanitizeTriageSort(request()->query('triage_sort'));

        foreach (['backup_posture', 'recovery_evidence', 'review_state', 'triage_sort'] as $filterName) {
            data_forget($this->tableFilters, $filterName);
            data_forget($this->tableDeferredFilters, $filterName);
        }

        if ($backupPostures !== []) {
            $this->tableFilters['backup_posture']['values'] = $backupPostures;
            $this->tableDeferredFilters['backup_posture']['values'] = $backupPostures;
        }

        if ($recoveryEvidence !== []) {
            $this->tableFilters['recovery_evidence']['values'] = $recoveryEvidence;
            $this->tableDeferredFilters['recovery_evidence']['values'] = $recoveryEvidence;
        }

        if ($reviewStates !== []) {
            $this->tableFilters['review_state']['values'] = $reviewStates;
            $this->tableDeferredFilters['review_state']['values'] = $reviewStates;
        }

        if ($triageSort !== null) {
            $this->tableFilters['triage_sort']['value'] = $triageSort;
            $this->tableDeferredFilters['triage_sort']['value'] = $triageSort;
        }
    }

    private function hasActiveTriageEmptyState(): bool
    {
        $state = $this->currentPortfolioTriageReturnState();

        return $state['backup_posture'] !== []
            || $state['recovery_evidence'] !== []
            || $state['review_state'] !== []
            || $state['triage_sort'] === TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST;
    }

    /**
     * @return array{backup_posture: list<string>, recovery_evidence: list<string>, review_state: list<string>, triage_sort: string|null}
     */
    public function currentPortfolioTriageReturnState(): array
    {
        return [
            'backup_posture' => ManagedEnvironmentResource::sanitizeBackupPostures(data_get($this->tableFilters, 'backup_posture.values', [])),
            'recovery_evidence' => ManagedEnvironmentResource::sanitizeRecoveryEvidenceStates(data_get($this->tableFilters, 'recovery_evidence.values', [])),
            'review_state' => ManagedEnvironmentResource::sanitizeReviewStates(data_get($this->tableFilters, 'review_state.values', [])),
            'triage_sort' => ManagedEnvironmentResource::sanitizeTriageSort(data_get($this->tableFilters, 'triage_sort.value')),
        ];
    }

    private function accessibleResumableDraftCount(): int
    {
        $user = auth()->user();

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

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

        if (! is_int($workspaceId)) {
            return 0;
        }

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

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

        return app(OnboardingDraftResolver::class)->resumableDraftsFor($user, $workspace)->count();
    }
}
