<?php

namespace App\Filament\Pages\Tenancy;

use App\Models\Tenant;
use App\Models\User;
use App\Models\WorkspaceMembership;
use App\Services\Auth\CapabilityResolver;
use App\Services\Intune\AuditLogger;
use App\Support\Auth\Capabilities;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Forms;
use Filament\Pages\Tenancy\RegisterTenant as BaseRegisterTenant;
use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Model;

class RegisterTenant extends BaseRegisterTenant
{
    public static function getLabel(): string
    {
        return 'Register tenant';
    }

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

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

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

        if ($workspaceId !== null) {
            $canRegisterInWorkspace = WorkspaceMembership::query()
                ->where('workspace_id', $workspaceId)
                ->where('user_id', $user->getKey())
                ->whereIn('role', ['owner', 'manager'])
                ->exists();

            if ($canRegisterInWorkspace) {
                return true;
            }
        }

        $tenantIds = $user->tenants()->withTrashed()->pluck('tenants.id');

        if ($tenantIds->isEmpty()) {
            return false;
        }

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

        foreach (Tenant::query()->whereIn('id', $tenantIds)->cursor() as $tenant) {
            if ($resolver->can($user, $tenant, Capabilities::TENANT_MANAGE)) {
                return true;
            }
        }

        return false;
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->schema([
                Forms\Components\TextInput::make('name')
                    ->required()
                    ->maxLength(255),
                Forms\Components\Select::make('environment')
                    ->options([
                        'prod' => 'PROD',
                        'dev' => 'DEV',
                        'staging' => 'STAGING',
                        'other' => 'Other',
                    ])
                    ->default('other')
                    ->required(),
                Forms\Components\TextInput::make('tenant_id')
                    ->label('Tenant ID (GUID)')
                    ->required()
                    ->maxLength(255)
                    ->unique(ignoreRecord: true),
                Forms\Components\TextInput::make('domain')
                    ->label('Primary domain')
                    ->maxLength(255)
                    ->helperText('Credentials are managed after tenant creation in Provider connections.'),
            ]);
    }

    /**
     * @param  array<string, mixed>  $data
     */
    protected function handleRegistration(array $data): Model
    {
        if (! static::canView()) {
            abort(403);
        }

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

        if ($workspaceId !== null) {
            $data['workspace_id'] = $workspaceId;
        }

        $tenant = Tenant::create($data);

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

        if ($user instanceof User) {
            $user->tenants()->syncWithoutDetaching([
                $tenant->getKey() => [
                    'role' => 'owner',
                    'source' => 'manual',
                    'created_by_user_id' => $user->getKey(),
                ],
            ]);

            app(AuditLogger::class)->log(
                tenant: $tenant,
                action: 'tenant_membership.bootstrap_assign',
                context: [
                    'metadata' => [
                        'user_id' => (int) $user->getKey(),
                        'role' => 'owner',
                        'source' => 'manual',
                    ],
                ],
                actorId: (int) $user->getKey(),
                actorEmail: $user->email,
                actorName: $user->name,
                status: 'success',
                resourceType: 'tenant',
                resourceId: (string) $tenant->getKey(),
            );
        }

        return $tenant;
    }
}
