<?php

declare(strict_types=1);

namespace App\Support\OperateHub;

use App\Filament\Pages\TenantDashboard;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Auth\CapabilityResolver;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Illuminate\Http\Request;

final class OperateHubShell
{
    public function __construct(
        private WorkspaceContext $workspaceContext,
        private CapabilityResolver $capabilityResolver,
    ) {}

    public function scopeLabel(?Request $request = null): string
    {
        $activeTenant = $this->activeEntitledTenant($request);

        if ($activeTenant instanceof Tenant) {
            return 'Filtered by tenant: '.$activeTenant->name;
        }

        return 'All tenants';
    }

    /**
     * @return array{label: string, url: string}|null
     */
    public function returnAffordance(?Request $request = null): ?array
    {
        $activeTenant = $this->activeEntitledTenant($request);

        if ($activeTenant instanceof Tenant) {
            return [
                'label' => 'Back to '.$activeTenant->name,
                'url' => TenantDashboard::getUrl(panel: 'tenant', tenant: $activeTenant),
            ];
        }

        return null;
    }

    /**
     * @return array<Action>
     */
    public function headerActions(
        string $scopeActionName = 'operate_hub_scope',
        string $returnActionName = 'operate_hub_return',
        ?Request $request = null,
    ): array {
        $actions = [
            Action::make($scopeActionName)
                ->label($this->scopeLabel($request))
                ->color('gray')
                ->disabled(),
        ];

        $returnAffordance = $this->returnAffordance($request);

        if (is_array($returnAffordance)) {
            $actions[] = Action::make($returnActionName)
                ->label($returnAffordance['label'])
                ->icon('heroicon-o-arrow-left')
                ->color('gray')
                ->url($returnAffordance['url']);
        }

        return $actions;
    }

    public function activeEntitledTenant(?Request $request = null): ?Tenant
    {
        return $this->resolveActiveTenant($request);
    }

    private function resolveActiveTenant(?Request $request = null): ?Tenant
    {
        $tenant = Filament::getTenant();

        if ($tenant instanceof Tenant && $this->isEntitled($tenant, $request)) {
            return $tenant;
        }

        $rememberedTenantId = $this->workspaceContext->lastTenantId($request);

        if ($rememberedTenantId === null) {
            return null;
        }

        $rememberedTenant = Tenant::query()->whereKey($rememberedTenantId)->first();

        if (! $rememberedTenant instanceof Tenant) {
            return null;
        }

        if (! $this->isEntitled($rememberedTenant, $request)) {
            return null;
        }

        return $rememberedTenant;
    }

    private function isEntitled(Tenant $tenant, ?Request $request = null): bool
    {
        if (! $tenant->isActive()) {
            return false;
        }

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

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

        $workspaceId = $this->workspaceContext->currentWorkspaceId($request);

        if ($workspaceId !== null && (int) $tenant->workspace_id !== (int) $workspaceId) {
            return false;
        }

        return $this->capabilityResolver->isMember($user, $tenant);
    }
}
