<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Workspace;
use App\Services\Audit\WorkspaceAuditLogger;
use App\Support\Audit\AuditActionId;
use App\Support\Workspaces\WorkspaceContext;
use App\Support\Workspaces\WorkspaceIntendedUrl;
use App\Support\Workspaces\WorkspaceRedirectResolver;
use Filament\Facades\Filament;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

final class SwitchWorkspaceController
{
    public function __invoke(Request $request): RedirectResponse
    {
        $user = auth()->user();

        if (! $user instanceof User) {
            abort(403);
        }

        $validated = $request->validate([
            'workspace_id' => ['required', 'integer'],
        ]);

        $workspace = Workspace::query()->whereKey($validated['workspace_id'])->first();

        if (! $workspace instanceof Workspace) {
            abort(404);
        }

        if (! empty($workspace->archived_at)) {
            abort(404);
        }

        $context = app(WorkspaceContext::class);

        if (! $context->isMember($user, $workspace)) {
            abort(404);
        }

        $prevWorkspaceId = $context->currentWorkspaceId($request);

        $context->setCurrentWorkspace($workspace, $user, $request);
        $context->rememberedEnvironment($request);
        Filament::setTenant(null, true);

        /** @var WorkspaceAuditLogger $auditLogger */
        $auditLogger = app(WorkspaceAuditLogger::class);

        $auditLogger->log(
            workspace: $workspace,
            action: AuditActionId::WorkspaceSelected->value,
            context: [
                'metadata' => [
                    'method' => 'manual',
                    'reason' => 'context_bar',
                    'prev_workspace_id' => $prevWorkspaceId,
                ],
            ],
            actor: $user,
            resourceType: 'workspace',
            resourceId: (string) $workspace->getKey(),
        );

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

        return redirect()->to($resolver->resolve(
            $workspace,
            $user,
            WorkspaceIntendedUrl::consume($request),
        ));
    }
}
