<?php
/**
 * Licensing — the free/Pro gate.
 *
 * Platform Helm ships as ONE plugin containing every module. Which modules a
 * site may actually use is decided here, in one place:
 *
 *   - The free "Core" tier (link suggester, architect, health, schema, GTM) is
 *     always available.
 *   - Every other module is "Pro": it still appears in Helm → Modules so free
 *     users can see what they get, but it is LOCKED — it cannot be enabled and
 *     never boots (registers zero hooks) until the site has an active licence.
 *
 * Enforcement is layered (never trust the UI alone):
 *   1. Plugin::boot_modules() refuses to boot a locked module.
 *   2. SettingsPage::sanitize_settings() forces a locked module's toggle to off.
 *   3. SettingsPage renders locked modules disabled, with an "Upgrade" CTA.
 *
 * WIRING THE LICENCE CHECK
 * ------------------------
 * is_pro() is the single source of truth. Out of the box it is false (so a raw
 * .org download is the free product). To switch a site to Pro, do ONE of:
 *
 *   • Freemius (recommended): once you have wrapped the plugin with the Freemius
 *     SDK, replace the body of is_pro() with:
 *         return function_exists( 'phelm_fs' ) && phelm_fs()->can_use_premium_code();
 *     (or is_paying() / is_plan('pro')). That is the only line that changes.
 *   • A constant: define( 'PLATFORM_HELM_PRO', true ) in wp-config.php.
 *   • A filter: add_filter( 'platform_helm_is_pro', '__return_true' ) — handy for
 *     local testing and for "bundled with our managed hosting" deployments.
 *
 * @package Platform\Helm\Core
 */

declare( strict_types = 1 );

namespace Platform\Helm\Core;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Licensing {

	/**
	 * The free "Core" tier — module IDs that are ALWAYS available, licence or not.
	 * Everything not in this list is treated as Pro (so new/unknown modules are
	 * Pro by default; add-on modules can opt back out via the filters below).
	 */
	private const FREE_MODULES = [
		'link_suggester',
		'link_architect',
		'link_health',
		'schema',
		'gtm',
	];

	/**
	 * Module IDs that require Pro. Kept explicit (rather than "everything minus
	 * free") so the Modules screen can show a stable Pro list, and so companion
	 * add-on modules — which are not part of Helm's licence — are NOT locked.
	 */
	private const PRO_MODULES = [
		'persona_dashboards',
		'role_manager',
		'activity_log',
		'audit_trail',
		'activity_intelligence',
		'member_health',
		'ai_assistant',
		'aeo_check',
		'meta_gen',
		'gsc_connector',
		'content_auditor',
		'link_assassin',
		'ghost_purge',
		'uploads_vault',
		'login_branding',
	];

	/**
	 * Whether this site may use Pro modules.
	 *
	 * This is the ONE place to wire your licence provider (see the file header).
	 * Default false → a plain download is the free product.
	 */
	public static function is_pro(): bool {
		// Freemius: returns true for any site with an active paid licence.
		// phelm_fs() returns null when the SDK folder is not yet present, so
		// we guard before calling can_use_premium_code().
		if ( function_exists( 'phelm_fs' ) ) {
			$fs = phelm_fs();
			if ( $fs && $fs->can_use_premium_code() ) {
				return true;
			}
		}

		// Local override — useful for dev/staging: define( 'PLATFORM_HELM_PRO', true )
		// in wp-config.php, or add_filter( 'platform_helm_is_pro', '__return_true' ).
		$pro = defined( 'PLATFORM_HELM_PRO' ) && PLATFORM_HELM_PRO;

		/**
		 * Filter the effective licence verdict.
		 *
		 * @param bool $pro Whether Pro features are unlocked.
		 */
		return (bool) apply_filters( 'platform_helm_is_pro', $pro );
	}

	/**
	 * The list of Pro module IDs (filterable, so you can move a module between
	 * tiers without editing code).
	 *
	 * @return string[]
	 */
	public static function pro_modules(): array {
		/**
		 * Filter the Pro module-id list.
		 *
		 * @param string[] $ids
		 */
		$ids = (array) apply_filters( 'platform_helm_pro_modules', self::PRO_MODULES );
		return array_values( array_unique( array_map( 'strval', $ids ) ) );
	}

	/** Is this module part of the paid tier? */
	public static function is_pro_module( string $id ): bool {
		return in_array( $id, self::pro_modules(), true );
	}

	/** Is this module a free-core module? */
	public static function is_free_module( string $id ): bool {
		/**
		 * Filter the free-core module-id list.
		 *
		 * @param string[] $ids
		 */
		$free = (array) apply_filters( 'platform_helm_free_modules', self::FREE_MODULES );
		return in_array( $id, $free, true );
	}

	/**
	 * Is this module currently LOCKED for this site — i.e. it is a Pro module and
	 * the site is not licensed? Locked modules cannot be enabled and never boot.
	 */
	public static function is_locked( string $id ): bool {
		return self::is_pro_module( $id ) && ! self::is_pro();
	}

	/**
	 * Upgrade URL shown on locked modules. Filterable so you can point it at your
	 * sales page or the Freemius pricing/checkout screen.
	 */
	public static function upgrade_url(): string {
		$default = admin_url( 'admin.php?page=' . \Platform\Helm\Admin\SettingsPage::PAGE_SLUG );

		/**
		 * Filter the "Upgrade to Pro" destination URL.
		 *
		 * @param string $url
		 */
		$url = (string) apply_filters( 'platform_helm_upgrade_url', $default );
		return '' !== $url ? $url : $default;
	}
}
