<?php

namespace App\Filament\Resources\Workspaces;

use App\Filament\Resources\Workspaces\RelationManagers\WorkspaceMembershipsRelationManager;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Auth\WorkspaceCapabilityResolver;
use App\Services\Workspaces\WorkspaceLifecycleService;
use App\Support\Auth\Capabilities;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use App\Support\Rbac\WorkspaceUiEnforcement;
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\Workspaces\WorkspaceContext;
use BackedEnum;
use Filament\Actions;
use Filament\Actions\ActionGroup;
use Filament\Forms;
use Filament\Infolists;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use UnitEnum;

class WorkspaceResource extends Resource
{
    protected static ?string $model = Workspace::class;

    protected static bool $isDiscovered = false;

    protected static bool $isScopedToTenant = false;

    protected static ?string $recordTitleAttribute = 'name';

    protected static bool $shouldRegisterNavigation = false;

    protected static ?string $breadcrumb = 'Manage workspaces';

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-squares-2x2';

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

    public static function canCreate(): bool
    {
        $user = auth()->user();

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

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

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

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

            if ($workspace instanceof Workspace) {
                return $resolver->isMember($user, $workspace)
                    && $resolver->can($user, $workspace, Capabilities::WORKSPACE_MANAGE);
            }
        }

        foreach ($user->workspaces()->get() as $workspace) {
            if (! $workspace instanceof Workspace) {
                continue;
            }

            if ($resolver->can($user, $workspace, Capabilities::WORKSPACE_MANAGE)) {
                return true;
            }
        }

        return false;
    }

    public static function canEdit(Model $record): bool
    {
        $user = auth()->user();

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

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

        return $resolver->isMember($user, $record)
            && ! $record->isClosed()
            && $resolver->can($user, $record, Capabilities::WORKSPACE_MANAGE);
    }

    public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration
    {
        return ActionSurfaceDeclaration::forResource(ActionSurfaceProfile::CrudListAndView, ActionSurfaceType::CrudListFirstResource)
            ->satisfy(ActionSurfaceSlot::ListHeader, 'List page provides a capability-gated create action.')
            ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value)
            ->satisfy(ActionSurfaceSlot::ListRowMoreMenu, 'Clickable-row inspection stays primary while the secondary Edit shortcut lives under "More".')
            ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'Workspace list intentionally omits bulk actions.')
            ->satisfy(ActionSurfaceSlot::ListEmptyState, 'List page defines a capability-gated empty-state create CTA.')
            ->satisfy(ActionSurfaceSlot::DetailHeader, 'Workspace view page exposes a capability-gated edit action.');
    }

    public static function getEloquentQuery(): Builder
    {
        $query = parent::getEloquentQuery();

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

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

        return $query
            ->whereNull('archived_at')
            ->whereIn('id', function ($subQuery) use ($user): void {
                $subQuery->from('workspace_memberships')
                    ->select('workspace_id')
                    ->where('user_id', $user->getKey());
            });
    }

    public static function form(Schema $schema): Schema
    {
        return $schema
            ->schema([
                Forms\Components\TextInput::make('name')
                    ->required()
                    ->maxLength(255),
                Forms\Components\TextInput::make('slug')
                    ->required()
                    ->maxLength(255)
                    ->unique(ignoreRecord: true),
            ]);
    }

    public static function makeCreateAction(): Actions\CreateAction
    {
        return Actions\CreateAction::make()
            ->label('New workspace')
            ->disabled(fn (): bool => ! static::canCreate())
            ->tooltip(fn (): ?string => static::canCreate()
                ? null
                : 'You do not have permission to create workspaces.');
    }

    public static function table(Table $table): Table
    {
        return $table
            ->defaultSort('name')
            ->paginated(\App\Support\Filament\TablePaginationProfiles::resource())
            ->recordUrl(fn (Workspace $record): string => static::getUrl('view', ['record' => $record]))
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->searchable()
                    ->sortable(),
                Tables\Columns\TextColumn::make('slug')
                    ->searchable()
                    ->sortable(),
                Tables\Columns\TextColumn::make('closure_posture')
                    ->label('Lifecycle')
                    ->badge()
                    ->state(fn (Workspace $record): string => app(WorkspaceLifecycleService::class)->workspacePosture($record))
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::WorkspaceClosurePosture))
                    ->color(BadgeRenderer::color(BadgeDomain::WorkspaceClosurePosture))
                    ->icon(BadgeRenderer::icon(BadgeDomain::WorkspaceClosurePosture))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::WorkspaceClosurePosture))
                    ->description(fn (Workspace $record): ?string => $record->isClosed()
                        ? 'Read-only; tenant context selection is disabled.'
                        : null),
            ])
            ->actions([
                ActionGroup::make([
                    WorkspaceUiEnforcement::forTableAction(
                        Actions\EditAction::make()
                            ->visible(fn (Workspace $record): bool => static::canEdit($record)),
                        fn (): ?Workspace => null,
                    )
                        ->preserveVisibility()
                        ->requireCapability(Capabilities::WORKSPACE_MANAGE)
                        ->apply(),
                ])
                    ->label('More')
                    ->icon('heroicon-o-ellipsis-vertical'),
            ])
            ->emptyStateHeading('No workspaces')
            ->emptyStateDescription('Create your first workspace.')
            ->emptyStateIcon('heroicon-o-squares-2x2')
            ->emptyStateActions([
                static::makeCreateAction(),
            ]);
    }

    public static function infolist(Schema $schema): Schema
    {
        return $schema
            ->schema([
                Infolists\Components\TextEntry::make('name'),
                Infolists\Components\TextEntry::make('slug'),
                Infolists\Components\TextEntry::make('closure_posture')
                    ->label('Lifecycle')
                    ->badge()
                    ->state(fn (Workspace $record): string => app(WorkspaceLifecycleService::class)->workspacePosture($record))
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::WorkspaceClosurePosture))
                    ->color(BadgeRenderer::color(BadgeDomain::WorkspaceClosurePosture))
                    ->icon(BadgeRenderer::icon(BadgeDomain::WorkspaceClosurePosture))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::WorkspaceClosurePosture)),
                Infolists\Components\TextEntry::make('closed_at')
                    ->label('Closed at')
                    ->dateTime()
                    ->placeholder('Not closed'),
                Infolists\Components\TextEntry::make('closure_reason')
                    ->label('Closure reason')
                    ->state(fn (Workspace $record): ?string => $record->closureReason())
                    ->placeholder('Not closed')
                    ->columnSpanFull(),
            ])
            ->columns(2);
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListWorkspaces::route('/'),
            'create' => Pages\CreateWorkspace::route('/create'),
            'view' => Pages\ViewWorkspace::route('/{record}'),
            'edit' => Pages\EditWorkspace::route('/{record}/edit'),
        ];
    }

    public static function getRelations(): array
    {
        return [
            WorkspaceMembershipsRelationManager::class,
        ];
    }
}
