<?php
/**
 * Plugin Name: Site Toolkit by WP PowerSuite
 * Plugin URI: https://wppowersuite.com/
 * Description: A modular WordPress plugin system with 150+ modules. Zero runtime cost for disabled modules.
 * Version: 1.0.8
 * Author: Muhammad Muzammil
 * Author URI: https://wppowersuite.com
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: wp-powersuite
 * Domain Path: /languages
 * Requires at least: 6.8
 * Requires PHP: 8.1
 * Network: true
 *
 * @package WP_PowerSuite
 * @version 1.0.8
 * @since 1.0.0
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

define( 'WP_POWERSUITE_VERSION', '1.0.8' );
define( 'WP_POWERSUITE_MIN_PHP_VERSION', '8.1' );
define( 'WP_POWERSUITE_MIN_WP_VERSION', '6.8' );
define( 'WP_POWERSUITE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'WP_POWERSUITE_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'WP_POWERSUITE_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
define( 'WP_POWERSUITE_PLUGIN_FILE', __FILE__ );
define( 'WP_POWERSUITE_SRC_DIR', WP_POWERSUITE_PLUGIN_DIR . 'src' . DIRECTORY_SEPARATOR );
define( 'WP_POWERSUITE_MODULES_DIR', WP_POWERSUITE_PLUGIN_DIR . 'modules' . DIRECTORY_SEPARATOR );
define( 'WP_POWERSUITE_MODULES_MANIFEST', WP_POWERSUITE_PLUGIN_DIR . 'data' . DIRECTORY_SEPARATOR . 'modules-manifest.json' );
define( 'WP_POWERSUITE_OPTION_PREFIX', 'wp_powersuite_' );
define( 'WP_POWERSUITE_TRANSIENT_PREFIX', 'wp_powersuite_' );
define( 'WP_POWERSUITE_PRODUCT_URL', 'https://wppowersuite.com/' );
define( 'WP_POWERSUITE_RENEW_URL', 'https://wppowersuite.com/renew' );
define( 'WP_POWERSUITE_SUPPORT_URL', 'https://wppowersuite.com/support' );
define( 'WP_POWERSUITE_DOCS_URL', 'https://wppowersuite.com/docs' );
// Optional: override in wp-config.php to receive deactivation feedback by email or webhook.
if ( ! defined( 'WP_POWERSUITE_DEACTIVATION_FEEDBACK_WEBHOOK' ) ) {
	define( 'WP_POWERSUITE_DEACTIVATION_FEEDBACK_WEBHOOK', 'https://wppowersuite.com/wp-json/licensor/deactivation-feedback' );
}

/** @var list<array{title_id: string, message_id: string, message_args: list<string|int|float>}> */
$GLOBALS['wp_powersuite_admin_notices'] = [];

/**
 * HTML attribute marking a notice as owned by WP PowerSuite (excluded from hide-notices).
 *
 * @since 1.0.0
 */
function wp_powersuite_plugin_notice_attr(): string {
	return ' data-wpps-plugin="true"';
}

/**
 * Queue an admin error notice for deferred translation and display.
 *
 * @since 1.0.0
 * @param string               $message_id   English message (gettext msgid).
 * @param list<string|int|float> $message_args Optional sprintf args applied after translation.
 * @param string               $title_id     English title (gettext msgid).
 */
function wp_powersuite_queue_admin_notice( string $message_id, array $message_args = [], string $title_id = 'WP PowerSuite Error' ): void {
	$GLOBALS['wp_powersuite_admin_notices'][] = [
		'title_id'     => $title_id,
		'message_id'   => $message_id,
		'message_args' => $message_args,
	];

	wp_powersuite_register_deferred_admin_notices();
}

/**
 * Register the init hook that renders queued admin notices after textdomain load.
 *
 * @since 1.0.0
 */
function wp_powersuite_register_deferred_admin_notices(): void {
	static $registered = false;
	if ( $registered ) {
		return;
	}

	$registered = true;
	add_action( 'init', 'wp_powersuite_render_deferred_admin_notices', 1 );
}

/**
 * Translate queued notices and attach them to admin_notices.
 *
 * @since 1.0.0
 */
function wp_powersuite_render_deferred_admin_notices(): void {
	if ( empty( $GLOBALS['wp_powersuite_admin_notices'] ) ) {
		return;
	}

	$notices = $GLOBALS['wp_powersuite_admin_notices'];

	add_action(
		'admin_notices',
		static function () use ( $notices ): void {
			foreach ( $notices as $notice ) {
				// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText -- msgid is an English literal queued at the call site.
				$title = __( $notice['title_id'], 'wp-powersuite' );
				// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText -- msgid is an English literal queued at the call site.
				$message = __( $notice['message_id'], 'wp-powersuite' );
				if ( ! empty( $notice['message_args'] ) ) {
					$message = vsprintf( $message, $notice['message_args'] );
				}

				printf(
					'<div class="notice notice-error"%1$s><p><strong>%2$s</strong>: %3$s</p></div>',
					' data-wpps-plugin="true"',
					esc_html( $title ),
					esc_html( $message )
				);
			}
		}
	);
}

/**
 * Check PHP Version Compatibility
 *
 * Exits with an admin notice if PHP version is below minimum requirement.
 *
 * @since 1.0.0
 */
function wp_powersuite_check_php_version() {
	if ( version_compare( PHP_VERSION, WP_POWERSUITE_MIN_PHP_VERSION, '<' ) ) {
		wp_powersuite_queue_admin_notice(
			'WP PowerSuite requires PHP %2$s or higher. You are running PHP %1$s.',
			[ PHP_VERSION, WP_POWERSUITE_MIN_PHP_VERSION ]
		);
		return false;
	}
	return true;
}

/**
 * Check WordPress Version Compatibility
 *
 * Exits with an admin notice if WordPress version is below minimum requirement.
 *
 * @since 1.0.0
 */
function wp_powersuite_check_wp_version() {
	global $wp_version;
	if ( version_compare( $wp_version, WP_POWERSUITE_MIN_WP_VERSION, '<' ) ) {
		wp_powersuite_queue_admin_notice(
			'WP PowerSuite requires WordPress %2$s or higher. You are running WordPress %1$s.',
			[ $wp_version, WP_POWERSUITE_MIN_WP_VERSION ]
		);
		return false;
	}
	return true;
}

/**
 * Bootstrap Directory Path
 *
 * Absolute path to the bootstrap directory (with trailing slash).
 *
 * @var string
 */
define( 'WP_POWERSUITE_BOOTSTRAP_DIR', WP_POWERSUITE_PLUGIN_DIR . 'bootstrap' . DIRECTORY_SEPARATOR );

/**
 * Licensing Directory Path
 *
 * Absolute path to the licensing directory (with trailing slash).
 *
 * @var string
 */
define( 'WP_POWERSUITE_LICENSING_DIR', WP_POWERSUITE_PLUGIN_DIR . 'includes' . DIRECTORY_SEPARATOR . 'licensing' . DIRECTORY_SEPARATOR );

/**
 * Distribution edition. The Lite zip rewrites this to `lite` at pack time.
 * `full` is the all-in-one commercial/dev tree. wordpress.org ships `lite`.
 *
 * @since 1.1.0
 */
if ( ! defined( 'WP_POWERSUITE_EDITION' ) ) {
	define( 'WP_POWERSUITE_EDITION', 'lite' );
}

/**
 * Required licensing class files (relative to {@see wp_powersuite_licensing_dir()}).
 *
 * @since 1.0.0
 * @return list<string>
 */
function wp_powersuite_licensing_required_files(): array {
	return [
		'license-bootstrap.php',
		'class-wpps-elite-licenser-client.php',
		'class-w-p-power-suite-premium-base.php',
		'class-wpps-license-manager.php',
	];
}

/**
 * Whether this install is the wordpress.org Lite edition.
 *
 * @since 1.1.0
 */
function wp_powersuite_is_lite_edition(): bool {
	$marker = defined( 'WP_POWERSUITE_PLUGIN_DIR' )
		? WP_POWERSUITE_PLUGIN_DIR . 'data' . DIRECTORY_SEPARATOR . 'edition.lite'
		: '';
	if ( $marker !== '' && is_readable( $marker ) ) {
		return true;
	}

	$edition = defined( 'WP_POWERSUITE_EDITION' ) ? (string) WP_POWERSUITE_EDITION : 'full';
	/**
	 * Filter the running edition. Tests may force `lite` without rebuilding.
	 * A packed `data/edition.lite` marker always wins (wordpress.org builds).
	 *
	 * @since 1.1.0
	 * @param string $edition `full` or `lite`.
	 */
	$edition = (string) apply_filters( 'wp_powersuite_edition', $edition );

	return $edition === 'lite';
}

/**
 * Whether the WP PowerSuite Pro add-on plugin is loaded.
 *
 * @since 1.1.0
 */
function wp_powersuite_is_pro_addon_active(): bool {
	return defined( 'WP_POWERSUITE_PRO_ACTIVE' ) && WP_POWERSUITE_PRO_ACTIVE;
}

/**
 * Whether a freemium module's Pro overlay may run.
 *
 * @since 1.0.9
 */
function wp_powersuite_freemium_unlocked( string $module_id ): bool {
	return \WP_PowerSuite\Core\Freemium::unlocked( $module_id );
}

/**
 * Absolute path to a freemium premium file, or empty when it is not shipped.
 *
 * @since 1.0.9
 */
function wp_powersuite_locate_freemium_file( string $module_id, string $relative ): string {
	return \WP_PowerSuite\Core\Freemium::locateFile( $module_id, $relative );
}

/**
 * Load a freemium premium file from the Pro overlay or Full module tree.
 *
 * @since 1.0.9
 */
function wp_powersuite_require_freemium_file( string $module_id, string $relative ): bool {
	return \WP_PowerSuite\Core\Freemium::requireFile( $module_id, $relative );
}

/**
 * Whether the license UI exists (Pro add-on or Full edition).
 *
 * Lite without Pro has no license page — send buyers to the product URL.
 */
function wp_powersuite_can_activate_license(): bool {
	return class_exists( 'WPPS_License_Manager', false );
}

/**
 * License page when Pro is installed, otherwise the public purchase URL.
 */
function wp_powersuite_premium_upsell_url(): string {
	if ( wp_powersuite_can_activate_license() ) {
		return admin_url( 'admin.php?page=powersuite-license' );
	}

	return defined( 'WP_POWERSUITE_PRODUCT_URL' ) ? WP_POWERSUITE_PRODUCT_URL : 'https://wppowersuite.com/';
}

/**
 * Directory that actually contains Elite Licenser files.
 *
 * Lite has no licensing PHP. The Pro add-on defines
 * {@see WP_POWERSUITE_PRO_LICENSING_DIR} before `plugins_loaded`.
 *
 * @since 1.1.0
 */
function wp_powersuite_licensing_dir(): string {
	if ( defined( 'WP_POWERSUITE_PRO_LICENSING_DIR' ) && is_string( WP_POWERSUITE_PRO_LICENSING_DIR ) && WP_POWERSUITE_PRO_LICENSING_DIR !== '' ) {
		return WP_POWERSUITE_PRO_LICENSING_DIR;
	}

	return WP_POWERSUITE_LICENSING_DIR;
}

/**
 * Plugin bootstrap file that owns the active licensing directory.
 *
 * Lite + Pro: the add-on. Full: this plugin (even if the add-on is also present
 * and its licensing dir is preferred, Full still ships the same CSS).
 *
 * @since 1.0.8
 */
function wp_powersuite_licensing_plugin_file(): string {
	$dir = wp_powersuite_licensing_dir();
	if ( $dir !== '' && defined( 'WP_POWERSUITE_PRO_LICENSING_DIR' ) && defined( 'WP_POWERSUITE_PRO_FILE' ) ) {
		$pro = (string) WP_POWERSUITE_PRO_LICENSING_DIR;
		if ( rtrim( str_replace( '\\', '/', $dir ), '/' ) === rtrim( str_replace( '\\', '/', $pro ), '/' ) ) {
			return (string) WP_POWERSUITE_PRO_FILE;
		}
	}

	return defined( 'WP_POWERSUITE_PLUGIN_FILE' ) ? WP_POWERSUITE_PLUGIN_FILE : '';
}

/**
 * Public URL for a file inside the active licensing directory.
 *
 * @since 1.0.8
 * @param string $relative Path relative to includes/licensing/. No parent segments.
 */
function wp_powersuite_licensing_url( string $relative ): string {
	$relative = ltrim( str_replace( '\\', '/', $relative ), '/' );
	if ( $relative === '' || str_contains( $relative, '..' ) ) {
		return '';
	}

	$plugin_file = wp_powersuite_licensing_plugin_file();
	if ( $plugin_file === '' ) {
		return '';
	}

	return plugins_url( 'includes/licensing/' . $relative, $plugin_file );
}

/**
 * Cache-busting version for a licensing asset.
 *
 * @since 1.0.8
 */
function wp_powersuite_licensing_asset_version( string $relative ): string {
	$relative = ltrim( str_replace( '\\', '/', $relative ), '/' );
	$dir      = wp_powersuite_licensing_dir();
	$path     = $dir !== '' ? $dir . $relative : '';
	if ( $path !== '' && is_readable( $path ) ) {
		$mtime = filemtime( $path );
		if ( is_int( $mtime ) && $mtime > 0 ) {
			return (string) $mtime;
		}
	}

	return defined( 'WP_POWERSUITE_VERSION' ) ? WP_POWERSUITE_VERSION : '1.0.0';
}

/**
 * Public directory for hub/settings/license CSS and JS.
 *
 * Hosts often block HTTP access to /src/. Prefer assets/admin/ when present.
 *
 * @since 1.0.8
 */
function wp_powersuite_admin_assets_rel(): string {
	$dir = defined( 'WP_POWERSUITE_PLUGIN_DIR' ) ? WP_POWERSUITE_PLUGIN_DIR : '';
	if ( $dir !== '' && is_readable( $dir . 'assets/admin/app.css' ) ) {
		return 'assets/admin/';
	}

	return 'src/Admin/Assets/';
}

/**
 * @since 1.0.8
 * @param string $filename File in the admin assets directory. No parent segments.
 */
function wp_powersuite_admin_asset_url( string $filename ): string {
	$filename = ltrim( str_replace( '\\', '/', $filename ), '/' );
	if ( $filename === '' || str_contains( $filename, '..' ) ) {
		return '';
	}

	$base = defined( 'WP_POWERSUITE_PLUGIN_URL' ) ? WP_POWERSUITE_PLUGIN_URL : '';
	return $base === '' ? '' : $base . wp_powersuite_admin_assets_rel() . $filename;
}

/**
 * @since 1.0.8
 * @param string $filename File in the admin assets directory. No parent segments.
 */
function wp_powersuite_admin_asset_path( string $filename ): string {
	$filename = ltrim( str_replace( '\\', '/', $filename ), '/' );
	if ( $filename === '' || str_contains( $filename, '..' ) ) {
		return '';
	}

	$base = defined( 'WP_POWERSUITE_PLUGIN_DIR' ) ? WP_POWERSUITE_PLUGIN_DIR : '';
	if ( $base === '' ) {
		return '';
	}

	return $base . str_replace( '/', DIRECTORY_SEPARATOR, wp_powersuite_admin_assets_rel() . $filename );
}

/**
 * Public URL for a file next to a module bootstrap (core or Pro add-on).
 *
 * @since 1.0.8
 * @param string $module_file Absolute path to that module's module.php (or sibling).
 * @param string $relative    Path relative to that file. No parent segments.
 */
function wp_powersuite_module_asset_url( string $module_file, string $relative ): string {
	$relative = ltrim( str_replace( '\\', '/', $relative ), '/' );
	if ( $relative === '' || str_contains( $relative, '..' ) || $module_file === '' ) {
		return '';
	}

	return plugins_url( $relative, $module_file );
}

/**
 * Absolute filesystem path for a file next to a module bootstrap.
 *
 * @since 1.0.8
 * @param string $module_file Absolute path to that module's module.php (or sibling).
 * @param string $relative    Path relative to that file. No parent segments.
 */
function wp_powersuite_module_asset_path( string $module_file, string $relative ): string {
	$relative = ltrim( str_replace( '\\', '/', $relative ), '/' );
	if ( $relative === '' || str_contains( $relative, '..' ) || $module_file === '' ) {
		return '';
	}

	return dirname( $module_file ) . DIRECTORY_SEPARATOR . str_replace( '/', DIRECTORY_SEPARATOR, $relative );
}

/**
 * Trailing-slash URL of a module's assets/ directory (core or Pro add-on).
 *
 * @since 1.0.8
 */
function wp_powersuite_module_assets_url( string $module_file ): string {
	$url = wp_powersuite_module_asset_url( $module_file, 'assets' );

	return $url === '' ? '' : trailingslashit( $url );
}

/**
 * Plugin file the license and commercial updater attach to.
 *
 * Lite + Pro: the add-on (wordpress.org must keep updating Lite).
 * Full: this plugin, unchanged for existing customers.
 *
 * @since 1.1.0
 */
function wp_powersuite_licensed_plugin_file(): string {
	if ( wp_powersuite_is_lite_edition() ) {
		return ( defined( 'WP_POWERSUITE_PRO_FILE' ) && is_string( WP_POWERSUITE_PRO_FILE ) )
			? WP_POWERSUITE_PRO_FILE
			: '';
	}

	return defined( 'WP_POWERSUITE_PLUGIN_FILE' ) ? WP_POWERSUITE_PLUGIN_FILE : '';
}

/**
 * Whether this build ships with premium licensing infrastructure.
 *
 * Licensing is expected when the bootstrap file and all required class files exist.
 *
 * @since 1.0.0
 * @return bool True when licensing files are present in this distribution.
 */
function wp_powersuite_is_licensing_expected(): bool {
	if ( wp_powersuite_is_lite_edition() && ! wp_powersuite_is_pro_addon_active() ) {
		/**
		 * Leftover licensing PHP after a Full→Lite overwrite must not entitle Lite.
		 *
		 * @since 1.1.0
		 * @param bool $expected File-based detection result.
		 */
		return (bool) apply_filters( 'wp_powersuite_is_licensing_expected', false );
	}

	$dir      = wp_powersuite_licensing_dir();
	$expected = true;
	foreach ( wp_powersuite_licensing_required_files() as $file ) {
		if ( ! file_exists( $dir . $file ) ) {
			$expected = false;
			break;
		}
	}

	/**
	 * Filter whether licensing files are treated as present.
	 *
	 * @since 1.1.0
	 * @param bool $expected File-based detection result.
	 */
	return (bool) apply_filters( 'wp_powersuite_is_licensing_expected', $expected );
}

/**
 * Load License Bootstrap
 *
 * Loads Elite Licenser base class and LicenseManager. Must be called
 * before plugin init to perform license validation.
 *
 * @since 1.0.0
 * @return bool True if licensing files loaded, false otherwise.
 */
function wp_powersuite_load_license_bootstrap(): bool {
	if ( ! wp_powersuite_is_licensing_expected() ) {
		return false;
	}

	require_once wp_powersuite_licensing_dir() . 'license-bootstrap.php';
	return class_exists( 'W_P_Power_Suite_Premium_Base', false ) && class_exists( 'WPPS_License_Manager', false );
}

/**
 * Check if license is valid (for premium module gating).
 *
 * Entitlement: activated on this site and not revoked. Expired subscriptions
 * remain entitled to premium features.
 *
 * Full builds without licensing files stay ungated (historical contract).
 * Lite builds without the Pro add-on are not entitled. Freemium premium
 * PHP is packed only in the Pro add-on (wordpress.org guideline 5).
 *
 * @since 1.0.0
 * @return bool True when premium features may run, false otherwise.
 */
function wp_powersuite_is_license_valid(): bool {
	if ( ! wp_powersuite_is_licensing_expected() ) {
		return ! wp_powersuite_is_lite_edition();
	}

	if ( ! class_exists( 'WPPS_License_Manager', false ) ) {
		return false;
	}

	return WPPS_License_Manager::get_instance()->is_valid();
}

/**
 * Whether the license is current for plugin updates and support.
 *
 * Requires entitlement via {@see wp_powersuite_is_license_valid()} and a
 * non-expired license period.
 *
 * @since 1.0.0
 */
function wp_powersuite_is_license_current(): bool {
	if ( ! wp_powersuite_is_licensing_expected() ) {
		return ! wp_powersuite_is_lite_edition();
	}

	if ( ! class_exists( 'WPPS_License_Manager', false ) ) {
		return false;
	}

	return WPPS_License_Manager::get_instance()->is_current();
}

/**
 * Whether the site has an Agency / white-label license tier.
 *
 * Requires a valid license. Builds without licensing never qualify unless
 * filtered via {@see 'wp_powersuite_is_agency_license'}.
 *
 * @since 1.0.0
 */
function wp_powersuite_has_agency_license(): bool {
	$is_agency = false;
	if ( wp_powersuite_is_license_valid() && class_exists( 'WPPS_License_Manager', false ) ) {
		$is_agency = WPPS_License_Manager::get_instance()->is_agency_license();
	}

	return (bool) apply_filters( 'wp_powersuite_is_agency_license', $is_agency );
}

/**
 * Whether the current request is a PowerSuite admin-ajax action.
 *
 * @since 1.0.0
 */
function wp_powersuite_is_ajax_request(): bool {
	if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
		return false;
	}

	$action = isset( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( $_REQUEST['action'] ) ) : '';
	if ( $action === '' ) {
		return false;
	}

	if ( str_starts_with( $action, 'wp_powersuite_' ) ) {
		return true;
	}

	return in_array( $action, [ 'wpps_set_delete_preference', 'wpps_deactivation_feedback' ], true );
}

/**
 * Load Bootstrap Files
 *
 * Loads the autoloader and kernel bootstrap files.
 *
 * @since 1.0.0
 * @return bool True if bootstrap files were loaded, false otherwise.
 */
function wp_powersuite_load_bootstrap(): bool {
	$autoloader_file = WP_POWERSUITE_BOOTSTRAP_DIR . 'autoloader.php';
	$kernel_file     = WP_POWERSUITE_BOOTSTRAP_DIR . 'kernel.php';

	if ( ! file_exists( $autoloader_file ) || ! file_exists( $kernel_file ) ) {
		return false;
	}

	require_once $autoloader_file;
	require_once $kernel_file;

	return true;
}

/**
 * Register PSR-4 Autoloader
 *
 * Registers the PSR-4 autoloader for the WP PowerSuite namespace.
 * Maps 'WP_PowerSuite' namespace to 'src' directory.
 *
 * @since 1.0.0
 * @return bool True if autoloader was registered, false otherwise.
 */
function wp_powersuite_register_autoloader() {
	// Load bootstrap files if not already loaded (contains register_autoloader function)
	if ( ! function_exists( '\WP_PowerSuite\Bootstrap\register_autoloader' ) ) {
		if ( ! wp_powersuite_load_bootstrap() ) {
			return false;
		}
	}

	// Verify function exists after loading bootstrap
	if ( ! function_exists( '\WP_PowerSuite\Bootstrap\register_autoloader' ) ) {
		return false;
	}

	// Register autoloader using bootstrap function
	return \WP_PowerSuite\Bootstrap\register_autoloader( 'WP_PowerSuite', WP_POWERSUITE_SRC_DIR );
}

/**
 * Add plugin row action links (Settings, Docs, Support) next to Deactivate.
 *
 * @since 1.0.0
 * @param array<string> $links Existing plugin action links.
 * @return array<string> Modified links.
 */
function wp_powersuite_plugin_action_links( array $links ): array {
	if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel', false ) ) {
		return \WP_PowerSuite\Core\WhiteLabel::filterPluginActionLinks( $links );
	}

	$settings_url = admin_url( 'admin.php?page=powersuite-settings' );
	$links['settings'] = '<a href="' . esc_url( $settings_url ) . '">' . esc_html__( 'Settings', 'wp-powersuite' ) . '</a>';

	return $links;
}

/**
 * Whether WordPress 6.8+ allows loading the wp-powersuite text domain.
 *
 * JIT translation before after_setup_theme prints a notice when WP_DEBUG is on,
 * which sends output and breaks later wp_safe_redirect() calls (blank admin-post pages).
 */
function wp_powersuite_translations_ready(): bool {
	return did_action( 'after_setup_theme' ) || doing_action( 'after_setup_theme' );
}

/**
 * Global branding helpers (delegate to WhiteLabel when available).
 */
function wp_powersuite_get_plugin_name(): string {
	if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel', false ) ) {
		return \WP_PowerSuite\Core\WhiteLabel::get_plugin_name();
	}

	return wp_powersuite_translations_ready()
		? __( 'Site Toolkit by WP PowerSuite', 'wp-powersuite' )
		: 'Site Toolkit by WP PowerSuite';
}

function wp_powersuite_get_plugin_short_name(): string {
	if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel', false ) ) {
		return \WP_PowerSuite\Core\WhiteLabel::get_plugin_short_name();
	}

	return wp_powersuite_translations_ready()
		? __( 'WP PowerSuite', 'wp-powersuite' )
		: 'WP PowerSuite';
}

function wp_powersuite_get_company_name(): string {
	if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel', false ) ) {
		return \WP_PowerSuite\Core\WhiteLabel::get_company_name();
	}

	return wp_powersuite_translations_ready()
		? __( 'WP PowerSuite', 'wp-powersuite' )
		: 'WP PowerSuite';
}

function wp_powersuite_get_support_url(): string {
	return class_exists( '\WP_PowerSuite\Core\WhiteLabel', false )
		? \WP_PowerSuite\Core\WhiteLabel::get_support_url()
		: ( defined( 'WP_POWERSUITE_SUPPORT_URL' ) ? WP_POWERSUITE_SUPPORT_URL : 'https://wppowersuite.com/support' );
}

function wp_powersuite_get_documentation_url(): string {
	return class_exists( '\WP_PowerSuite\Core\WhiteLabel', false )
		? \WP_PowerSuite\Core\WhiteLabel::get_documentation_url()
		: ( defined( 'WP_POWERSUITE_DOCS_URL' ) ? WP_POWERSUITE_DOCS_URL : 'https://wppowersuite.com/docs' );
}

function wp_powersuite_is_vendor_branding_hidden(): bool {
	return class_exists( '\WP_PowerSuite\Core\WhiteLabel', false )
		&& \WP_PowerSuite\Core\WhiteLabel::is_vendor_branding_hidden();
}

/**
 * Log init failure details and register a generic admin notice.
 *
 * @since 1.0.0
 * @param string $log_message  Detailed message for error_log only.
 * @param string $user_message Optional user-facing message.
 * @return void
 */
function wp_powersuite_init_error_notice( string $log_message, string $user_message = '' ): void {
	error_log( 'WP PowerSuite initialization error: ' . $log_message );

	if ( $user_message === '' ) {
		$user_message = 'WP PowerSuite could not initialize. Please reinstall the plugin or contact support.';
	}

	wp_powersuite_queue_admin_notice( $user_message );
}

/**
 * Initialize WP PowerSuite Plugin
 *
 * Main initialization function that sets up the plugin kernel.
 * This function is hooked into 'plugins_loaded' to ensure WordPress
 * is fully loaded before plugin initialization.
 *
 * @since 1.0.0
 * @return void
 */
function wp_powersuite_init() {
	// Step 1: Load bootstrap files (contains Kernel class)
	if ( ! wp_powersuite_load_bootstrap() ) {
		$bootstrap_dir = defined( 'WP_POWERSUITE_BOOTSTRAP_DIR' ) ? WP_POWERSUITE_BOOTSTRAP_DIR : 'Not defined';
		wp_powersuite_init_error_notice(
			'Bootstrap files missing or unreadable. Bootstrap dir: ' . $bootstrap_dir,
			'Failed to load WP PowerSuite bootstrap files. Please reinstall the plugin.'
		);
		return;
	}

	// Step 2: Register autoloader (needed for Plugin and other core classes)
	if ( ! wp_powersuite_register_autoloader() ) {
		$src_dir = defined( 'WP_POWERSUITE_SRC_DIR' ) ? WP_POWERSUITE_SRC_DIR : 'Not defined';
		wp_powersuite_init_error_notice(
			'Autoloader registration failed. Src dir: ' . $src_dir,
			'Failed to register WP PowerSuite autoloader. Please reinstall the plugin.'
		);
		return;
	}

	// Step 3: Translations load on init@0 via Kernel::loadTextdomainOnInit (WordPress 6.7+).
	// Do not call loadTextdomain here on plugins_loaded — it triggers _load_textdomain_just_in_time notices.

	// Step 4: License - load licensing and validate (never blocks plugin)
	if ( wp_powersuite_load_license_bootstrap() ) {
		$license_manager = WPPS_License_Manager::get_instance();
		$license_manager->init();
		$license_manager->register_admin_hooks();
	}

	// Step 5: Verify Kernel class exists (should exist after loading bootstrap)
	if ( ! class_exists( 'WP_PowerSuite\Bootstrap\Kernel', false ) ) {
		wp_powersuite_init_error_notice(
			'Kernel class not found after loading bootstrap files.',
			'Kernel class not found after loading bootstrap files.'
		);
		return;
	}

	// Step 6: Verify Plugin class exists (should be autoloadable)
	if ( ! class_exists( 'WP_PowerSuite\Core\Plugin', false ) ) {
		// Try to trigger autoloader
		if ( ! class_exists( 'WP_PowerSuite\Core\Plugin', true ) ) {
			$plugin_file = defined( 'WP_POWERSUITE_SRC_DIR' )
				? WP_POWERSUITE_SRC_DIR . 'Core' . DIRECTORY_SEPARATOR . 'Plugin.php'
				: 'Not defined';
			wp_powersuite_init_error_notice(
				sprintf(
					'Plugin class not autoloadable. Plugin file: %s; file exists: %s',
					$plugin_file,
					file_exists( $plugin_file ) ? 'yes' : 'no'
				),
				'Failed to load Plugin class. Please reinstall the plugin.'
			);
			return;
		}
	}

	// Initialize the plugin kernel
	try {
		$kernel = \WP_PowerSuite\Bootstrap\Kernel::getInstance();
		$kernel->init();

		// Plugin row action links are registered by WhiteLabel::init() via the kernel bootstrap.

		// Register WP-CLI commands only in a CLI context. Command classes are
		// PSR-4 autoloaded and instantiated lazily, so this adds no overhead to
		// web/admin/AJAX/REST requests.
		if ( defined( 'WP_CLI' ) && WP_CLI && class_exists( '\WP_PowerSuite\CLI\CommandLoader' ) ) {
			\WP_PowerSuite\CLI\CommandLoader::register();
		}
	} catch ( \Exception $e ) {
		wp_powersuite_init_error_notice(
			sprintf(
				'%s in %s:%d',
				$e->getMessage(),
				$e->getFile(),
				$e->getLine()
			)
		);
	}
}

// Perform compatibility checks before proceeding
if ( ! wp_powersuite_check_php_version() || ! wp_powersuite_check_wp_version() ) {
	return;
}

/**
 * Get WP PowerSuite Plugin Instance
 *
 * Global helper function to access the main Plugin instance.
 * Returns null if plugin is not initialized.
 *
 * @since 1.0.0
 * @return \WP_PowerSuite\Core\Plugin|null Plugin instance or null if not initialized.
 */
function wp_powersuite(): ?\WP_PowerSuite\Core\Plugin {
	try {
		$kernel = \WP_PowerSuite\Bootstrap\Kernel::getInstance();
		if ( $kernel->isInitialized() ) {
			return $kernel->getPlugin();
		}
	} catch ( \Exception $e ) {
		unset( $e );
	}
	return null;
}

/**
 * Get WP PowerSuite Kernel Instance
 *
 * Global helper function to access the Kernel instance.
 * Returns null if kernel is not initialized.
 *
 * @since 1.0.0
 * @return \WP_PowerSuite\Bootstrap\Kernel|null Kernel instance or null if not initialized.
 */
function wp_powersuite_kernel(): ?\WP_PowerSuite\Bootstrap\Kernel {
	try {
		$kernel = \WP_PowerSuite\Bootstrap\Kernel::getInstance();
		if ( $kernel->isInitialized() ) {
			return $kernel;
		}
	} catch ( \Exception $e ) {
		unset( $e );
	}
	return null;
}

/**
 * Uninstall handler - prompts user to delete all data
 */
function wpps_uninstall_plugin() {
	if ( class_exists( 'W_P_Power_Suite_Premium_Base' ) ) {
		W_P_Power_Suite_Premium_Base::run_on_delete_callbacks();
	}

	// Include uninstall.php which handles the actual deletion
	if ( file_exists( __DIR__ . '/uninstall.php' ) ) {
		require_once __DIR__ . '/uninstall.php';
		
		// Check if user wants to delete all data
		if ( function_exists( 'wpps_should_delete_all_data' ) && wpps_should_delete_all_data() ) {
			if ( function_exists( 'wpps_delete_all_plugin_data' ) ) {
				wpps_delete_all_plugin_data();
			}
		}
	}
}

/**
 * Bootstrap core classes required during activation/deactivation.
 *
 * @since 1.0.0
 * @return bool True when autoloader is available.
 */
function wp_powersuite_bootstrap_for_lifecycle(): bool {
	if ( ! wp_powersuite_load_bootstrap() ) {
		return false;
	}

	return wp_powersuite_register_autoloader();
}

/**
 * Plugin activation callback.
 *
 * Multisite: WordPress invokes this once per site. When the plugin is
 * network-activated, shared settings use site options ({@see NetworkScope});
 * per-site activation stores settings in each blog's options table. See
 * {@see \WP_PowerSuite\Core\PluginLifecycle} for full behavior.
 *
 * @since 1.0.0
 * @return void
 */
function wp_powersuite_activate(): void {
	if ( ! wp_powersuite_bootstrap_for_lifecycle() ) {
		return;
	}

	wp_powersuite_load_license_bootstrap();
	\WP_PowerSuite\Core\PluginLifecycle::activate();
}

/**
 * Plugin deactivation callback.
 *
 * Clears core plugin crons only; settings and module data are preserved.
 *
 * @since 1.0.0
 * @return void
 */
function wp_powersuite_deactivate(): void {
	if ( ! wp_powersuite_bootstrap_for_lifecycle() ) {
		wp_clear_scheduled_hook( 'wp_powersuite_license_recheck' );
		return;
	}

	\WP_PowerSuite\Core\PluginLifecycle::deactivate();
}

register_activation_hook( __FILE__, 'wp_powersuite_activate' );
register_deactivation_hook( __FILE__, 'wp_powersuite_deactivate' );

// Register uninstall hook
register_uninstall_hook( __FILE__, 'wpps_uninstall_plugin' );

require_once __DIR__ . '/includes/backup-restore-retire.php';
require_once WP_POWERSUITE_SRC_DIR . 'Core' . DIRECTORY_SEPARATOR . 'BootServiceProvider.php';
\WP_PowerSuite\Core\BootServiceProvider::registerEarly();

// Hook into plugins_loaded with priority 5 to ensure early initialization
// but after WordPress core is fully loaded
add_action( 'plugins_loaded', 'wp_powersuite_retire_backup_restore_module_run', 4 );
add_action( 'before_woocommerce_init', 'wp_powersuite_declare_woocommerce_compatibility' );
add_action( 'plugins_loaded', 'wp_powersuite_init', 5 );

/**
 * Declare WooCommerce HPOS and Checkout Blocks compatibility for the whole plugin.
 */
function wp_powersuite_declare_woocommerce_compatibility(): void {
	if ( ! class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
		return;
	}
	\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
		'custom_order_tables',
		WP_POWERSUITE_PLUGIN_FILE,
		true
	);
	\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
		'cart_checkout_blocks',
		WP_POWERSUITE_PLUGIN_FILE,
		true
	);
	\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
		'product_block_editor',
		WP_POWERSUITE_PLUGIN_FILE,
		true
	);
}

