<?php

namespace App\Policies;

use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Services\Auth\ManagedEnvironmentAccessScopeResolver;
use App\Support\Operations\OperationRunCapabilityResolver;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;

class OperationRunPolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user): bool
    {
        $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId();

        if ($workspaceId === null) {
            return false;
        }

        return WorkspaceMembership::query()
            ->where('workspace_id', (int) $workspaceId)
            ->where('user_id', (int) $user->getKey())
            ->exists();
    }

    public function view(User $user, OperationRun $run): Response|bool
    {
        $workspaceId = (int) ($run->workspace_id ?? 0);

        if ($workspaceId <= 0) {
            return Response::denyAsNotFound();
        }

        $isMember = WorkspaceMembership::query()
            ->where('workspace_id', $workspaceId)
            ->where('user_id', (int) $user->getKey())
            ->exists();

        if (! $isMember) {
            return Response::denyAsNotFound();
        }

        $tenantId = (int) ($run->managed_environment_id ?? 0);

        if ($tenantId > 0) {
            $tenant = ManagedEnvironment::query()->withTrashed()->whereKey($tenantId)->first();

            if (! $tenant instanceof ManagedEnvironment || (int) $tenant->workspace_id !== $workspaceId) {
                return Response::denyAsNotFound();
            }

            $hasTenantEntitlement = app(ManagedEnvironmentAccessScopeResolver::class)->canAccess($user, $tenant);

            if (! $hasTenantEntitlement) {
                return Response::denyAsNotFound();
            }
        }

        $requiredCapability = app(OperationRunCapabilityResolver::class)
            ->requiredCapabilityForRun($run);

        if (! is_string($requiredCapability) || $requiredCapability === '') {
            return true;
        }

        if (str_starts_with($requiredCapability, 'workspace')) {
            $workspace = Workspace::query()->whereKey($workspaceId)->first();

            if (! $workspace instanceof Workspace) {
                return Response::denyAsNotFound();
            }

            if (! Gate::forUser($user)->allows($requiredCapability, $workspace)) {
                return Response::deny();
            }

            return true;
        }

        if ($tenantId > 0) {
            $tenant = ManagedEnvironment::query()->withTrashed()->whereKey($tenantId)->first();

            if (! $tenant instanceof ManagedEnvironment) {
                return Response::denyAsNotFound();
            }

            if (! Gate::forUser($user)->allows($requiredCapability, $tenant)) {
                return Response::deny();
            }
        }

        return true;
    }
}
