<?php

/**
 * Feature Gate - Modular plan detection (Dialogue + Memory axes)
 *
 * @package SlideMind
 * @since 2.1.0
 */
namespace SlideMind\Core;

if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class FeatureGate {
    /**
     * Plan hierarchy: higher level = more features.
     * 'personal' kept as legacy alias (level 1) for backward compat.
     */
    const PLAN_LEVELS = [
        'free'            => 0,
        'personal'        => 1,
        'memory'          => 1,
        'dialogue'        => 1,
        'dialogue+memory' => 2,
        'pro'             => 3,
        'agency'          => 4,
    ];

    /**
     * Feature-to-axis mapping (replaces FEATURE_PLANS).
     * Values are axis slugs resolved by is_enabled().
     */
    const FEATURE_REQUIREMENTS = [
        'courses'             => 'dialogue',
        'modules'             => 'dialogue',
        'unlimited_content'   => 'dialogue',
        'custom_templates'    => 'dialogue',
        'full_sandbox'        => 'dialogue',
        'unlimited_vars'      => 'memory',
        'full_profile'        => 'memory',
        'analytics'           => 'pro',
        'comparison'          => 'pro',
        'api_key_per_course'  => 'pro',
        'scope_course_module' => 'pro',
        'api_key_cascade'     => 'agency',
        'capture_mode'        => 'free',
        'learner_memory'      => 'memory',
        'profile_variables'   => 'memory',
    ];

    /**
     * Cached plan slug for the current request
     *
     * @var string|null
     */
    private static ?string $cached_plan = null;

    /**
     * Cached axis flags for the current request (computed once per axis)
     *
     * @var array<string, bool>
     */
    private static array $cached_axes = [];

    // ── Axis detection ────────────────────────────────────
    /**
     * Checks if the Dialogue axis is active.
     *
     * Active when: SLIDEMIND_PRO_ENABLED, parent pro/agency plan or trial, or slidemind_dialogue add-on paying/trial.
     *
     * @return bool
     */
    public static function has_dialogue() : bool {
        return false;
    }

    /**
     * Checks if the Memory axis is active.
     *
     * @return bool
     */
    public static function has_memory() : bool {
        return false;
    }

    /**
     * Checks if the Pro tier is active (parent plan only).
     *
     * @return bool
     */
    public static function has_pro() : bool {
        return false;
    }

    /**
     * Checks if the Agency tier is active.
     *
     * @return bool
     */
    public static function has_agency() : bool {
        return false;
    }

    // ── Feature gating ────────────────────────────────────
    /**
     * Checks if a feature is enabled for the active plan/axes
     *
     * @param string $feature Feature name (ex: 'comparison')
     * @return bool
     */
    public static function is_enabled( string $feature ) : bool {
        // Unknown feature = allowed (free-tier default behavior)
        if ( !isset( self::FEATURE_REQUIREMENTS[$feature] ) ) {
            return (bool) apply_filters( 'slidemind_pro_feature_enabled', true, $feature );
        }
        $axis = self::FEATURE_REQUIREMENTS[$feature];
        switch ( $axis ) {
            case 'free':
                $enabled = true;
                break;
            case 'dialogue':
                $enabled = self::has_dialogue();
                break;
            case 'memory':
                $enabled = self::has_memory();
                break;
            case 'pro':
                $enabled = self::has_pro();
                break;
            case 'agency':
                $enabled = self::has_agency();
                break;
            default:
                $enabled = false;
                break;
        }
        /**
         * Filters a feature's enabled state
         *
         * @param bool   $enabled  Current state
         * @param string $feature  Feature name
         */
        return (bool) apply_filters( 'slidemind_pro_feature_enabled', $enabled, $feature );
    }

    // ── Plan detection ────────────────────────────────────
    /**
     * Returns the active plan slug (memoized per request)
     *
     * Resolution order: SLIDEMIND_PRO_ENABLED → parent agency → parent pro → parent trial → add-ons → free.
     *
     * @return string free|dialogue|memory|dialogue+memory|pro|agency
     */
    public static function get_plan() : string {
        if ( self::$cached_plan !== null ) {
            return self::$cached_plan;
        }
        self::$cached_plan = 'free';
        return 'free';
    }

    /**
     * Returns the numeric level for the active plan
     *
     * @return int
     */
    public static function get_plan_level() : int {
        return self::PLAN_LEVELS[self::get_plan()] ?? 0;
    }

    /**
     * Checks if the active plan is equal to or higher than the given plan
     *
     * @param string $plan Plan slug to compare against
     * @return bool
     */
    public static function is_plan_or_higher( string $plan ) : bool {
        $required_level = self::PLAN_LEVELS[$plan] ?? 0;
        return self::get_plan_level() >= $required_level;
    }

    // ── URLs ──────────────────────────────────────────────
    /**
     * Returns the external pricing page URL
     *
     * @return string
     */
    public static function get_upgrade_url() : string {
        return 'https://slidemind.app/pricing/';
    }

    /**
     * Returns the Freemius checkout URL (direct payment flow)
     *
     * Routes to add-on Freemius instances for dialogue/memory slugs.
     *
     * @param string $plan_slug Plan slug (dialogue, memory, pro, agency).
     * @param bool   $is_trial  Whether to start a free trial.
     * @return string
     */
    public static function get_checkout_url( string $plan_slug = '', bool $is_trial = true ) : string {
        return '';
    }

    // ── Plan metadata ─────────────────────────────────────
    /**
     * Returns the minimum required plan/axis slug for a feature
     *
     * @param string $feature Feature name
     * @return string Axis slug (free if not gated)
     */
    public static function get_required_plan( string $feature ) : string {
        return self::FEATURE_REQUIREMENTS[$feature] ?? 'free';
    }

    /**
     * Returns the license status
     *
     * @return string active|expired|trial|free
     */
    public static function get_license_status() : string {
        return 'free';
    }

    // ── Private helpers ───────────────────────────────────
    /**
     * Checks if the active parent plan (paying or trial) matches one of the given slugs.
     *
     * Consolidates the SLIDEMIND_PRO_ENABLED + Freemius paying/trial logic shared by all has_*() methods.
     *
     * @param string[] $plans Accepted plan slugs (e.g. ['pro', 'agency']).
     * @return bool
     */
    private static function check_parent_plan( array $plans ) : bool {
        return false;
    }

    /**
     * Checks if an add-on Freemius instance is active (paying or trial).
     *
     * @param string $function_name Global function returning the add-on Freemius instance (e.g. 'slidemind_dialogue_fs').
     * @return bool
     */
    private static function check_addon( string $function_name ) : bool {
        return false;
    }

    /**
     * Resolves the plan slug from the site's trial_plan_id.
     *
     * During a trial, Freemius keeps plan_id = free and stores the trialed
     * plan in trial_plan_id. We look it up in fs_accounts to get the slug.
     *
     * @param \Freemius $fs Freemius instance.
     * @return string|null Plan slug or null if unresolvable.
     */
    private static function resolve_trial_plan( $fs ) : ?string {
        return null;
    }

    /**
     * Resolves a Freemius numeric plan ID from a plan slug.
     *
     * Freemius stores plans in fs_accounts with base64-encoded fields.
     *
     * @param string $slug Plan slug (pro, agency).
     * @return int|null
     */
    private static function get_freemius_plan_id( string $slug ) : ?int {
        return null;
    }

}
