<?php

declare(strict_types=1);

namespace App\Filament\System\Pages\Directory;

use App\Models\OperationRun;
use App\Models\PlatformUser;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use App\Services\Workspaces\WorkspaceLifecycleService;
use App\Support\Auth\PlatformCapabilities;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\System\SystemDirectoryLinks;
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 Filament\Pages\Page;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

class Workspaces extends Page implements HasTable
{
    use InteractsWithTable;

    protected static ?string $navigationLabel = 'Workspaces';

    protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-building-office-2';

    protected static string|\UnitEnum|null $navigationGroup = 'Directory';

    protected static ?string $slug = 'directory/workspaces';

    protected string $view = 'filament.system.pages.directory.workspaces';

    public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration
    {
        return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::ListOnlyReadOnly, ActionSurfaceType::ReadOnlyRegistryReport)
            ->exempt(ActionSurfaceSlot::ListHeader, 'System workspace directory stays scan-first and does not expose page header actions.')
            ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value)
            ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'Workspace directory rows navigate directly to the detail page and have no secondary actions.')
            ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'System workspace directory does not expose bulk actions.')
            ->satisfy(ActionSurfaceSlot::ListEmptyState, 'The empty state explains that workspaces appear here once the platform inventory is seeded.');
    }

    public static function canAccess(): bool
    {
        $user = auth('platform')->user();

        return $user instanceof PlatformUser
            && $user->hasCapability(PlatformCapabilities::DIRECTORY_VIEW);
    }

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

    public function table(Table $table): Table
    {
        return $table
            ->defaultSort('name')
            ->paginated(\App\Support\Filament\TablePaginationProfiles::customPage())
            ->query(function (): Builder {
                return Workspace::query()
                    ->withCount([
                        'tenants',
                        'tenants as onboarding_tenants_count' => fn (Builder $query): Builder => $query->where('lifecycle_status', ManagedEnvironment::STATUS_ONBOARDING),
                    ]);
            })
            ->columns([
                TextColumn::make('name')
                    ->label('Workspace')
                    ->searchable(),
                TextColumn::make('tenants_count')
                    ->label('Tenants'),
                TextColumn::make('closure_posture')
                    ->label('Lifecycle')
                    ->state(fn (Workspace $record): string => app(WorkspaceLifecycleService::class)->workspacePosture($record))
                    ->badge()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::WorkspaceClosurePosture))
                    ->color(BadgeRenderer::color(BadgeDomain::WorkspaceClosurePosture))
                    ->icon(BadgeRenderer::icon(BadgeDomain::WorkspaceClosurePosture))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::WorkspaceClosurePosture)),
                TextColumn::make('health')
                    ->label('Health')
                    ->state(fn (Workspace $record): string => $this->healthForWorkspace($record))
                    ->badge()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::SystemHealth))
                    ->color(BadgeRenderer::color(BadgeDomain::SystemHealth))
                    ->icon(BadgeRenderer::icon(BadgeDomain::SystemHealth))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::SystemHealth)),
                TextColumn::make('failed_runs_24h')
                    ->label('Failed (24h)')
                    ->state(fn (Workspace $record): int => (int) OperationRun::query()
                        ->where('workspace_id', (int) $record->getKey())
                        ->where('created_at', '>=', now()->subDay())
                        ->where('status', OperationRunStatus::Completed->value)
                        ->where('outcome', OperationRunOutcome::Failed->value)
                        ->count()),
            ])
            ->recordUrl(fn (Workspace $record): string => SystemDirectoryLinks::workspaceDetail($record))
            ->emptyStateHeading('No workspaces found')
            ->emptyStateDescription('Workspace inventory will appear here once workspaces are created.');
    }

    private function healthForWorkspace(Workspace $workspace): string
    {
        $tenantsCount = (int) ($workspace->getAttribute('tenants_count') ?? 0);
        $onboardingTenantsCount = (int) ($workspace->getAttribute('onboarding_tenants_count') ?? 0);

        if ($tenantsCount === 0) {
            return 'unknown';
        }

        $hasRecentFailures = OperationRun::query()
            ->where('workspace_id', (int) $workspace->getKey())
            ->where('created_at', '>=', now()->subDay())
            ->where('status', OperationRunStatus::Completed->value)
            ->where('outcome', OperationRunOutcome::Failed->value)
            ->exists();

        if ($hasRecentFailures) {
            return 'critical';
        }

        if ($onboardingTenantsCount > 0) {
            return 'warn';
        }

        return 'ok';
    }
}
