<?php

if (!defined('ABSPATH')) {
    die('You are not allowed to call this page directly.');
}

/**
 * Stateless helpers for MemberPress Full Site Editing (FSE) capability and mode checks.
 *
 * Two distinct questions are answered here:
 *   - {@see self::is_fse_mode_enabled()}: did the user opt in (raw toggle)?
 *   - {@see self::is_fse_mode_active()}: should FSE behavior actually run right now
 *     (toggle + WP capability + active block theme)?
 *
 * Use {@see self::is_fse_mode_active()} for runtime decisions (hook registration, asset
 * enqueue, route override) so a stale opt-in on a classic theme cannot trigger FSE-only
 * code paths and break rendering. Use {@see self::is_fse_mode_enabled()} only for admin
 * UI / settings rendering and cleanup-decision flows that intentionally inspect the
 * raw toggle.
 */
class MeprFseHelper
{
    /**
     * Whether the running WordPress version supports the Template Registration API.
     *
     * @return boolean True for WP 6.7+, false otherwise.
     */
    public static function can_run(): bool
    {
        return function_exists('wp_get_wp_version') && version_compare(wp_get_wp_version(), '6.7', '>=');
    }

    /**
     * Whether the FSE mode opt-in option is enabled.
     *
     * Reflects the user toggle only. Use this for admin UI / settings rendering and
     * for cleanup decisions that need the raw opt-in state.
     *
     * For runtime / behavior decisions, use {@see self::is_fse_mode_active()} instead.
     *
     * @return boolean
     */
    public static function is_fse_mode_enabled(): bool
    {
        if (!class_exists('MeprOptions')) {
            return false;
        }

        return ! empty(MeprOptions::fetch()->fse_mode_enabled);
    }

    /**
     * Whether MemberPress FSE behavior should run on the current request.
     *
     * Combines the user opt-in with WP capability and an actual block theme being active.
     * Returns false when any of the following is true:
     *   - {@see self::is_fse_mode_enabled()} is false (user did not opt in).
     *   - {@see self::can_run()} is false (WP < 6.7, no Template Registration API).
     *   - {@see wp_is_block_theme()} is false (active theme is classic).
     *
     * @return boolean
     */
    public static function is_fse_mode_active(): bool
    {
        if (! self::is_fse_mode_enabled()) {
            return false;
        }

        if (! self::can_run()) {
            return false;
        }

        if (! function_exists('wp_is_block_theme') || ! wp_is_block_theme()) {
            return false;
        }

        return true;
    }

    /**
     * Whether a post is assigned a MemberPress-registered FSE block template.
     *
     * Static passthrough to {@see MeprFseTemplatesCtrl::post_has_memberpress_fse_template()},
     * provided so callers (especially addons) have a single entry point and never need to
     * reach into {@see MeprCtrlFactory} for FSE registry lookups. The underlying check is
     * stateful — it inspects the controller's registered block templates config — so the
     * implementation must stay on the controller.
     *
     * @param  integer|null $post_id Post ID. Falls back to the current loop / queried object.
     * @return boolean
     */
    public static function post_has_memberpress_fse_template(?int $post_id = null): bool
    {
        if (! class_exists('MeprFseTemplatesCtrl') || ! class_exists('MeprCtrlFactory')) {
            return false;
        }

        return MeprCtrlFactory::fetch('FseTemplates')->post_has_memberpress_fse_template($post_id);
    }

    /**
     * Whether the current request maps to a MemberPress FSE template via CPT options.
     *
     * Static passthrough to {@see MeprFseTemplatesCtrl::request_uses_memberpress_fse_cpt_option_template()}.
     * Like {@see self::post_has_memberpress_fse_template()}, the underlying check is stateful
     * (it inspects the controller's registered template slugs and the CPT option mapping),
     * so the implementation must stay on the controller; this passthrough exists so callers
     * never need to reach into {@see MeprCtrlFactory} directly.
     *
     * @return boolean
     */
    public static function request_uses_memberpress_fse_cpt_option_template(): bool
    {
        if (! class_exists('MeprFseTemplatesCtrl') || ! class_exists('MeprCtrlFactory')) {
            return false;
        }

        return MeprCtrlFactory::fetch('FseTemplates')->request_uses_memberpress_fse_cpt_option_template();
    }
}
