<?php

declare(strict_types=1);

namespace App\Policies;

use App\Models\ManagedEnvironment;
use App\Models\EnvironmentReview;
use App\Models\User;
use App\Services\Auth\CapabilityResolver;
use App\Support\Auth\Capabilities;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;

class EnvironmentReviewPolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user): bool
    {
        $tenant = ManagedEnvironment::current();

        if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) {
            return false;
        }

        return app(CapabilityResolver::class)->can($user, $tenant, Capabilities::ENVIRONMENT_REVIEW_VIEW);
    }

    public function view(User $user, EnvironmentReview $review): Response|bool
    {
        $tenant = $this->authorizedTenantOrNull($user, $review);

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

        return app(CapabilityResolver::class)->can($user, $tenant, Capabilities::ENVIRONMENT_REVIEW_VIEW)
            ? true
            : Response::deny();
    }

    public function create(User $user): bool
    {
        $tenant = ManagedEnvironment::current();

        if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) {
            return false;
        }

        return app(CapabilityResolver::class)->can($user, $tenant, Capabilities::ENVIRONMENT_REVIEW_MANAGE);
    }

    public function refresh(User $user, EnvironmentReview $review): Response|bool
    {
        return $this->authorizeManageAction($user, $review);
    }

    public function publish(User $user, EnvironmentReview $review): Response|bool
    {
        return $this->authorizeManageAction($user, $review);
    }

    public function archive(User $user, EnvironmentReview $review): Response|bool
    {
        return $this->authorizeManageAction($user, $review);
    }

    public function export(User $user, EnvironmentReview $review): Response|bool
    {
        return $this->authorizeManageAction($user, $review);
    }

    public function createNextReview(User $user, EnvironmentReview $review): Response|bool
    {
        return $this->authorizeManageAction($user, $review);
    }

    private function authorizeManageAction(User $user, EnvironmentReview $review): Response|bool
    {
        $tenant = $this->authorizedTenantOrNull($user, $review);

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

        return app(CapabilityResolver::class)->can($user, $tenant, Capabilities::ENVIRONMENT_REVIEW_MANAGE)
            ? true
            : Response::deny();
    }

    private function authorizedTenantOrNull(User $user, EnvironmentReview $review): ?ManagedEnvironment
    {
        $tenant = $review->tenant;

        if (! $tenant instanceof ManagedEnvironment) {
            return null;
        }

        if (! $user->canAccessTenant($tenant)) {
            return null;
        }

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

        return $tenant;
    }
}
