<?php

declare(strict_types=1);

namespace App\Filament\Concerns;

use App\Services\PlanService;
use App\Support\TenantContext;

/**
 * Hides a Filament resource from the tenant sidebar AND blocks direct
 * access whenever the resource's plan feature key is EXPLICITLY set to
 * `false` for the tenant — either on its plan (SuperAdmin > Plans >
 * Features) or via a per-tenant `features.<key>` override.
 *
 * Opt-out by design: a key that is left unset keeps the resource visible,
 * so an install that never configured feature flags is unaffected. Only a
 * deliberate `false` removes the menu item (and 404s the URL, so it can't
 * be reached directly either).
 *
 * Usage — in a Resource:
 *
 *     use App\Filament\Concerns\GatedByPlanFeature;
 *
 *     class CompanyResource extends Resource
 *     {
 *         use GatedByPlanFeature;
 *
 *         protected static function planFeatureKey(): ?string
 *         {
 *             return 'companies';
 *         }
 *     }
 */
trait GatedByPlanFeature
{
    /**
     * The plan feature key that gates this resource. Return null to never
     * gate it (the trait default). Override in the resource.
     */
    protected static function planFeatureKey(): ?string
    {
        return null;
    }

    public static function shouldRegisterNavigation(): bool
    {
        return parent::shouldRegisterNavigation() && static::planFeatureAllowsAccess();
    }

    public static function canAccess(): bool
    {
        return parent::canAccess() && static::planFeatureAllowsAccess();
    }

    /**
     * False only when this resource's feature is explicitly disabled for the
     * current tenant. Null tenant (e.g. super-admin context) falls through to
     * the plan default, which likewise only hides on an explicit `false`.
     */
    public static function planFeatureAllowsAccess(): bool
    {
        $key = static::planFeatureKey();
        if ($key === null || $key === '') {
            return true;
        }

        return ! app(PlanService::class)->isFeatureExplicitlyDisabled(
            TenantContext::current(),
            $key,
        );
    }
}
