<?php

declare(strict_types=1);

namespace App\Filament\System\Pages\Directory;

use App\Models\PlatformUser;
use App\Models\Tenant;
use App\Support\Auth\PlatformCapabilities;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use App\Support\System\SystemDirectoryLinks;
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 Tenants extends Page implements HasTable
{
    use InteractsWithTable;

    protected static ?string $navigationLabel = 'Tenants';

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

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

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

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

    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 Tenant::query()
                    ->with('workspace')
                    ->withCount([
                        'providerConnections',
                        'providerConnections as unhealthy_connections_count' => fn (Builder $query): Builder => $query->where('health_status', 'unhealthy'),
                        'permissions as missing_permissions_count' => fn (Builder $query): Builder => $query->where('status', '!=', 'granted'),
                    ]);
            })
            ->columns([
                TextColumn::make('name')
                    ->label('Tenant')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('workspace.name')
                    ->label('Workspace')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('status')
                    ->badge()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::TenantStatus))
                    ->color(BadgeRenderer::color(BadgeDomain::TenantStatus))
                    ->icon(BadgeRenderer::icon(BadgeDomain::TenantStatus))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::TenantStatus)),
                TextColumn::make('health')
                    ->label('Health')
                    ->state(fn (Tenant $record): string => $this->healthForTenant($record))
                    ->badge()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::SystemHealth))
                    ->color(BadgeRenderer::color(BadgeDomain::SystemHealth))
                    ->icon(BadgeRenderer::icon(BadgeDomain::SystemHealth))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::SystemHealth)),
            ])
            ->recordUrl(fn (Tenant $record): string => SystemDirectoryLinks::tenantDetail($record))
            ->emptyStateHeading('No tenants found')
            ->emptyStateDescription('Tenants will appear here as inventory is onboarded.');
    }

    private function healthForTenant(Tenant $tenant): string
    {
        if ((string) $tenant->status === Tenant::STATUS_ARCHIVED) {
            return 'unknown';
        }

        if ((int) ($tenant->getAttribute('unhealthy_connections_count') ?? 0) > 0) {
            return 'critical';
        }

        if ((int) ($tenant->getAttribute('missing_permissions_count') ?? 0) > 0) {
            return 'warn';
        }

        if ((string) $tenant->status === Tenant::STATUS_ONBOARDING) {
            return 'warn';
        }

        return 'ok';
    }
}
