<?php
/**
 * Assets Manager
 *
 * Handles conditional loading of admin CSS and JavaScript assets.
 * Assets are loaded ONLY on WP PowerSuite admin pages, never globally.
 *
 * @package WP_PowerSuite\Core
 * @since 1.0.0
 */

namespace WP_PowerSuite\Core;

use WP_PowerSuite\Admin\PageHero;

/**
 * Assets Class
 *
 * Manages enqueuing of admin CSS and JavaScript files with proper
 * dependencies and AJAX support. Only loads on plugin admin pages.
 *
 * @since 1.0.0
 */
class Assets {

	/**
	 * Assets Instance
	 *
	 * Singleton instance of the Assets class.
	 *
	 * @var Assets|null
	 * @since 1.0.0
	 */
	private static ?Assets $instance = null;

	/**
	 * Admin Menu Instance
	 *
	 * Reference to AdminMenu for page detection.
	 *
	 * @var AdminMenu|null
	 * @since 1.0.0
	 */
	private ?AdminMenu $admin_menu = null;

	/**
	 * Plugin Version
	 *
	 * Plugin version for cache busting.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	private string $version = '1.0.0';

	/**
	 * Initialization Flag
	 *
	 * Tracks whether assets have been initialized.
	 *
	 * @var bool
	 * @since 1.0.0
	 */
	private bool $initialized = false;

	private const CORE_SCRIPT_HANDLE = 'wp-powersuite-core';

	private const ADMIN_SCRIPT_HANDLE = 'wp-powersuite-admin';

	private const QUICK_LAUNCHER_HANDLE = 'wp-powersuite-quick-launcher';

	private const SETTINGS_STYLE_HANDLE = 'wp-powersuite-settings';

	private const SETTINGS_SCRIPT_HANDLE = 'wp-powersuite-settings';

	/**
	 * Get Assets Instance
	 *
	 * Returns the singleton instance of the Assets class.
	 *
	 * @since 1.0.0
	 * @return Assets Assets instance.
	 */
	public static function getInstance(): Assets {
		if ( self::$instance === null ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor
	 *
	 * Private constructor to enforce singleton pattern.
	 *
	 * @since 1.0.0
	 */
	private function __construct() {
		$this->version = defined( 'WP_POWERSUITE_VERSION' )
			? WP_POWERSUITE_VERSION
			: '1.0.0';
	}

	/**
	 * Prevent Cloning
	 *
	 * Prevents cloning of the singleton instance.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	private function __clone() {
		// Prevent cloning
	}

	/**
	 * Prevent Unserialization
	 *
	 * Prevents unserialization of the singleton instance.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function __wakeup(): void {
		throw new \Exception( 'Cannot unserialize singleton' );
	}

	/**
	 * Initialize Assets
	 *
	 * Registers hooks for conditional asset loading. Only loads assets
	 * on WP PowerSuite admin pages.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function init(): void {
		// Prevent multiple initializations
		if ( $this->initialized ) {
			return;
		}

		// Only initialize in admin context
		if ( ! is_admin() ) {
			return;
		}

		$this->admin_menu = AdminMenu::getInstance();

		// Hook into admin_enqueue_scripts to conditionally load assets
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueueAdminAssets' ] );
		add_action( 'admin_notices', [ $this, 'maybeRenderMissingAssetNotice' ], 1 );

		$this->initialized = true;
	}

	/**
	 * Surface incomplete installs where src/Admin/Assets files were never uploaded or were removed.
	 *
	 * Without app.js the modules UI stays on "Loading modules..." with no explanation.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function maybeRenderMissingAssetNotice(): void {
		if ( ! is_admin() || ! current_user_can( NetworkScope::adminCapability() ) ) {
			return;
		}

		$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
		if ( ! AdminMenu::isPowerSuitePageSlug( $page ) ) {
			return;
		}

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

		$critical = $plugin_dir . 'src/Admin/Assets/app.js';
		$quick    = $plugin_dir . 'src/Admin/Assets/quick-launcher.js';
		if ( is_readable( $critical ) || is_readable( $quick ) ) {
			return;
		}

		printf(
			'<div class="notice notice-error"%1$s><p>%2$s <code>%3$s</code></p></div>',
			function_exists( 'wp_powersuite_plugin_notice_attr' ) ? wp_powersuite_plugin_notice_attr() : '',
			esc_html__(
				'WP PowerSuite admin JavaScript is missing from the plugin folder (incomplete install, partial deploy, or files removed after a restore). Re-upload the full plugin package or restore this plugin\'s files from backup. Until the files exist under',
				'wp-powersuite'
			),
			esc_html( 'src/Admin/Assets/' )
		);
	}

	/**
	 * Enqueue Admin Assets
	 *
	 * Conditionally enqueues CSS and JavaScript only on WP PowerSuite
	 * admin pages. No assets are loaded on other admin pages.
	 *
	 * @since 1.0.0
	 * @param string $hook_suffix Current admin page hook suffix.
	 * @return void
	 */
	public function enqueueAdminAssets( string $hook_suffix ): void {
		if ( ! $this->isPluginPage( $hook_suffix ) ) {
			return;
		}

		$current_page = $this->currentAdminPage();

		$this->enqueueAdminCss();
		$this->enqueueCoreScript();
		$this->enqueueQuickLauncherScript();

		if ( $current_page === 'powersuite-settings' || $current_page === WhiteLabel::WHITE_LABEL_PAGE_SLUG ) {
			$this->enqueueSettingsAssets();
		}

		if ( ! $this->shouldLoadModulesApp() ) {
			return;
		}

		wp_enqueue_media();

		$use_code_editor = $this->shouldLoadEditorAssets();
		if ( $use_code_editor ) {
			wp_enqueue_code_editor( [ 'type' => 'text/html' ] );
			wp_enqueue_code_editor( [ 'type' => 'text/css' ] );
			$this->enqueueCodeSnippetEditorStyles();
		}

		$this->enqueueModulesAppScript( $use_code_editor );
		if ( $use_code_editor ) {
			$this->enqueueColorPanelAssets();
		}
	}

	/**
	 * Current PowerSuite admin.php page slug.
	 */
	private function currentAdminPage(): string {
		return isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
	}

	/**
	 * Screens that need the modules dashboard JS bundle (save, color panel, CodeMirror init).
	 *
	 * @return string[]
	 */
	private function modulesAppPages(): array {
		return [
			'powersuite',
			'powersuite-login-page-customizor',
			'powersuite-coming-soon-maintenance',
		];
	}

	private function shouldLoadModulesApp(): bool {
		if ( in_array( $this->currentAdminPage(), $this->modulesAppPages(), true ) ) {
			return true;
		}

		// Basic Forms settings uses the shared custom-page save handler in app.js.
		if ( $this->currentAdminPage() === 'powersuite-basic-forms' ) {
			$view = isset( $_GET['view'] ) ? sanitize_key( wp_unslash( $_GET['view'] ) ) : '';

			return $view === 'settings';
		}

		return false;
	}

	private function shouldLoadEditorAssets(): bool {
		return in_array( $this->currentAdminPage(), $this->modulesAppPages(), true );
	}

	/**
	 * Code Snippet editor stylesheet (shared by Code Snippets page and module settings modals).
	 */
	private function enqueueCodeSnippetEditorStyles(): void {
		if ( wp_style_is( 'wpps-cs-admin', 'enqueued' ) ) {
			return;
		}
		$plugin_dir = defined( 'WP_POWERSUITE_PLUGIN_DIR' ) ? WP_POWERSUITE_PLUGIN_DIR : '';
		$plugin_url = defined( 'WP_POWERSUITE_PLUGIN_URL' ) ? WP_POWERSUITE_PLUGIN_URL : '';
		if ( $plugin_dir === '' || $plugin_url === '' ) {
			return;
		}
		$rel  = 'modules/code-snippet/assets/cs-admin.css';
		$path = $plugin_dir . $rel;
		if ( ! is_readable( $path ) ) {
			return;
		}
		$ver = (string) filemtime( $path );
		wp_enqueue_style( 'wpps-cs-admin', $plugin_url . $rel, [ 'wp-admin' ], $ver );
	}

	/**
	 * Enqueue Admin CSS
	 *
	 * Enqueues the admin stylesheet.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	private function enqueueAdminCss(): void {
		$css_file = $this->getAssetUrl( 'app.css' );
		if ( ! $this->assetExists( $css_file ) ) {
			return;
		}

		wp_enqueue_style( 'wp-powersuite-admin', $css_file, [ 'wp-admin' ], $this->getAssetVersion( 'app.css' ) );

		$module_settings_css = $this->getAssetUrl( 'module-settings.css' );
		if ( $this->assetExists( $module_settings_css ) ) {
			wp_enqueue_style( 'wp-powersuite-module-settings', $module_settings_css, [ 'wp-powersuite-admin' ], $this->getAssetVersion( 'module-settings.css' ) );
		}

		if ( AdminAppearance::isCustomBrandMode() ) {
			$inline = AdminAppearance::inlineCss();
			if ( $inline !== '' ) {
				wp_add_inline_style( 'wp-powersuite-admin', $inline );
			}
		}
	}

	/**
	 * Enqueue color panel assets (shared across modules)
	 *
	 * Loads the reusable color picker panel CSS and JS so any module
	 * using .wpps-color-picker-circle or .wpps-box-shadow-color-picker
	 * gets the custom panel instead of the native picker.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	private function enqueueColorPanelAssets(): void {
		$css_file = $this->getAssetUrl( 'color-panel.css' );
		if ( $this->assetExists( $css_file ) ) {
			wp_enqueue_style( 'wp-powersuite-color-panel', $css_file, [ 'wp-powersuite-admin' ], $this->version );
		}

		$js_file = $this->getAssetUrl( 'color-panel.js' );
		if ( $this->assetExists( $js_file ) ) {
			wp_enqueue_script( 'wp-powersuite-color-panel', $js_file, [ 'jquery', self::CORE_SCRIPT_HANDLE ], $this->version, true );
		}
	}

	/**
	 * Register the shared localized script handle used by admin bundles.
	 */
	private function enqueueCoreScript(): void {
		if ( ! wp_script_is( self::CORE_SCRIPT_HANDLE, 'registered' ) ) {
			wp_register_script( self::CORE_SCRIPT_HANDLE, false, [ 'jquery' ], $this->version, true );
		}

		if ( ! wp_script_is( self::CORE_SCRIPT_HANDLE, 'enqueued' ) ) {
			wp_enqueue_script( self::CORE_SCRIPT_HANDLE );
			$this->localizeScript( self::CORE_SCRIPT_HANDLE );
		}
	}

	/**
	 * Enqueue Quick Launcher on all PowerSuite admin pages.
	 */
	private function enqueueQuickLauncherScript(): void {
		$js_file = $this->getAssetUrl( 'quick-launcher.js' );
		if ( ! $this->assetExists( $js_file ) ) {
			return;
		}

		wp_enqueue_script(
			self::QUICK_LAUNCHER_HANDLE,
			$js_file,
			[ 'jquery', self::CORE_SCRIPT_HANDLE ],
			$this->version,
			true
		);
	}

	/**
	 * Enqueue settings page CSS and JavaScript.
	 */
	private function enqueueSettingsAssets(): void {
		$css_file = $this->getAssetUrl( 'settings.css' );
		if ( $this->assetExists( $css_file ) ) {
			wp_enqueue_style( self::SETTINGS_STYLE_HANDLE, $css_file, [ 'wp-powersuite-admin' ], $this->version );
		}

		$js_file = $this->getAssetUrl( 'settings.js' );
		if ( ! $this->assetExists( $js_file ) ) {
			return;
		}

		$this->enqueueColorPanelAssets();

		wp_enqueue_script(
			self::SETTINGS_SCRIPT_HANDLE,
			$js_file,
			[ 'jquery', self::CORE_SCRIPT_HANDLE, 'wp-powersuite-color-panel' ],
			$this->version,
			true
		);

		$white_label_settings = WhiteLabel::getSettings();
		$has_agency_license   = WhiteLabel::hasAgencyLicense();
		$current_page         = $this->currentAdminPage();
		$wl_tab_active        = ( isset( $_GET['tab'] ) && sanitize_key( wp_unslash( $_GET['tab'] ) ) === 'white-label' )
			|| $current_page === WhiteLabel::WHITE_LABEL_PAGE_SLUG;

		if ( $wl_tab_active ) {
			wp_enqueue_media();
		}

		$appearance = AdminAppearance::getSettingsSnapshot();

		wp_localize_script(
			self::SETTINGS_SCRIPT_HANDLE,
			'wppsSettings',
			[
				'ajaxUrl'  => admin_url( 'admin-ajax.php' ),
				'nonce'    => wp_create_nonce( 'wp_powersuite_ajax' ),
				'baseUrl'  => esc_url( remove_query_arg( [ 'wpps_notice', 'wpps_message' ], admin_url( 'admin.php?page=powersuite-settings' ) ) ),
				'appearance' => [
					'mode'              => $appearance['mode'],
					'brandColor'        => $appearance['color'],
					'defaultBrandColor' => AdminAppearance::DEFAULT_BRAND_COLOR,
					'appearanceCss'     => AdminAppearance::inlineCss(),
					'palette'           => $appearance['palette'],
				],
				'whiteLabel' => [
					'settings'                 => $white_label_settings,
					'hasAgencyLicense'         => $has_agency_license,
					'defaultPluginName'        => WhiteLabel::defaultPluginName(),
					'defaultPluginDescription' => WhiteLabel::defaultPluginDescription(),
					'defaultIconUrl'           => PageHero::default_icon_url(),
					'logoUrl'                  => WhiteLabel::logoUrl(),
					'menuIconUrl'              => WhiteLabel::menuIconUrl(),
					'mediaReady'               => $wl_tab_active,
					'standalonePage'           => $current_page === WhiteLabel::WHITE_LABEL_PAGE_SLUG,
					'directUrls'               => [
						'whiteLabel' => WhiteLabel::whiteLabelDirectUrl(),
						'license'    => WhiteLabel::licenseDirectUrl(),
					],
				],
				'strings'  => [
					'saved'                => __( 'Saved', 'wp-powersuite' ),
					'saveFailed'           => __( 'Save failed.', 'wp-powersuite' ),
					'requestFailed'        => __( 'Request failed.', 'wp-powersuite' ),
					'requestFailedRetry'   => __( 'Request failed. Please try again.', 'wp-powersuite' ),
					'errorOccurred'        => __( 'An error occurred.', 'wp-powersuite' ),
					'done'                 => __( 'Done', 'wp-powersuite' ),
					'failed'               => __( 'Failed', 'wp-powersuite' ),
					'clearInactiveConfirm' => __( 'Remove settings for disabled modules? This cannot be undone.', 'wp-powersuite' ),
					'clearAllConfirm'      => __( 'Delete ALL plugin data permanently? This cannot be undone. All module settings and configurations will be deleted.', 'wp-powersuite' ),
					'clearAllTypePrompt'   => __( 'Type DELETE below to permanently delete all plugin data.', 'wp-powersuite' ),
					'clearAllTypeLabel'    => __( 'Confirmation', 'wp-powersuite' ),
					'clearAllTypeRequired' => __( 'DELETE', 'wp-powersuite' ),
					'clearAllTypeMismatch' => __( 'Confirmation text did not match. No data was deleted.', 'wp-powersuite' ),
					'resetConfirm'         => __( 'Reset all settings to defaults? All modules will be disabled.', 'wp-powersuite' ),
					'presetNameRequired'   => __( 'Please enter a preset name.', 'wp-powersuite' ),
					'loadPresetConfirm'    => __( 'Load this preset? Current settings will be replaced.', 'wp-powersuite' ),
					'deletePresetConfirm'  => __( 'Delete this preset?', 'wp-powersuite' ),
					'exportFailed'         => __( 'Export failed.', 'wp-powersuite' ),
					'importFailed'         => __( 'Import failed.', 'wp-powersuite' ),
					'invalidJson'          => __( 'Invalid JSON file.', 'wp-powersuite' ),
					'agencyRequired'       => __( 'An Agency license is required to enable white-label branding.', 'wp-powersuite' ),
					'mediaUnavailable'     => __( 'Media library is unavailable.', 'wp-powersuite' ),
					'selectImage'          => __( 'Use image', 'wp-powersuite' ),
					'logoTitle'            => __( 'Select logo', 'wp-powersuite' ),
					'menuIconTitle'        => __( 'Select menu icon', 'wp-powersuite' ),
					'brandingSaved'        => __( 'Branding saved.', 'wp-powersuite' ),
					'brandingSavedMenu'    => __( 'Branding saved. Refresh the admin if the menu icon did not update.', 'wp-powersuite' ),
					'aiConnectionsSaved'   => __( 'AI connections saved.', 'wp-powersuite' ),
					'testingConnection'    => __( 'Testing…', 'wp-powersuite' ),
					'connectionOk'         => __( 'Connection successful.', 'wp-powersuite' ),
					'connectionFailed'     => __( 'Connection failed.', 'wp-powersuite' ),
					'authorBy'             => __( 'By %s', 'wp-powersuite' ),
					'confirm'              => __( 'Confirm', 'wp-powersuite' ),
					'cancel'               => __( 'Cancel', 'wp-powersuite' ),
					'dismiss'              => __( 'Dismiss', 'wp-powersuite' ),
					'resetWhiteLabelConfirm' => __( 'Reset all white-label fields to defaults? Branding will revert to the original plugin identity.', 'wp-powersuite' ),
					'whiteLabelReset'      => __( 'White-label settings reset.', 'wp-powersuite' ),
					'linkCopied'           => __( 'Link copied to clipboard.', 'wp-powersuite' ),
					'copyFailed'           => __( 'Could not copy link. Select and copy manually.', 'wp-powersuite' ),
				],
			]
		);
	}

	/**
	 * Enqueue the full modules dashboard bundle (main modules page only).
	 *
	 * @param bool $code_editor Whether code-editor assets are needed.
	 */
	private function enqueueModulesAppScript( bool $code_editor = false ): void {
		$js_file = $this->getAssetUrl( 'app.js' );
		if ( ! $this->assetExists( $js_file ) ) {
			return;
		}

		wp_enqueue_script( 'jquery-ui-sortable' );

		$deps = [ 'jquery', 'jquery-ui-sortable', self::CORE_SCRIPT_HANDLE ];
		$clamp_js = $this->getAssetUrl( 'number-clamp.js' );
		if ( $this->assetExists( $clamp_js ) ) {
			wp_enqueue_script( 'wp-powersuite-number-clamp', $clamp_js, [], $this->version, true );
			$deps[] = 'wp-powersuite-number-clamp';
		}
		if ( $code_editor && wp_script_is( 'code-editor', 'registered' ) ) {
			$deps[] = 'code-editor';
		}

		wp_enqueue_script( self::ADMIN_SCRIPT_HANDLE, $js_file, $deps, $this->getAssetVersion( 'app.js' ), true );
	}

	/**
	 * Load number-clamp.js alone (e.g. plugin screens that do not load the full admin bundle).
	 */
	public static function enqueueNumberClampScript(): void {
		$ver      = defined( 'WP_POWERSUITE_VERSION' ) ? WP_POWERSUITE_VERSION : '1.0.0';
		$url_base = defined( 'WP_POWERSUITE_PLUGIN_URL' ) ? WP_POWERSUITE_PLUGIN_URL : '';
		$dir_base = defined( 'WP_POWERSUITE_PLUGIN_DIR' ) ? WP_POWERSUITE_PLUGIN_DIR : '';
		$rel      = 'src/Admin/Assets/number-clamp.js';
		if ( $url_base === '' || $dir_base === '' || ! is_readable( $dir_base . $rel ) ) {
			return;
		}
		$handle = 'wp-powersuite-number-clamp';
		if ( ! wp_script_is( $handle, 'registered' ) ) {
			wp_register_script( $handle, $url_base . $rel, [], $ver, true );
		}
		wp_enqueue_script( $handle );
	}

	/**
	 * Localize Script
	 *
	 * Localizes the JavaScript with AJAX data, nonces, and other
	 * PHP-to-JavaScript data.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	private function localizeScript( string $handle = self::CORE_SCRIPT_HANDLE ): void {
		$option_store  = OptionStore::getInstance();
		$license_valid = function_exists( 'wp_powersuite_is_license_valid' ) && wp_powersuite_is_license_valid();
		$brand_name    = WhiteLabel::pluginName();

		$data = [
			'ajaxUrl'    => admin_url( 'admin-ajax.php' ),
			'nonce'      => wp_create_nonce( 'wp_powersuite_ajax' ),
			'action'     => [
				'toggleModule'       => 'wp_powersuite_toggle_module',
				'toggleFavorite'     => 'wp_powersuite_toggle_favorite',
				'saveModuleOrder'    => 'wp_powersuite_save_module_order',
				'refreshCache'       => 'wp_powersuite_refresh_cache',
				'commandPaletteData' => 'wp_powersuite_command_palette_data',
			],
			'licenseValid'   => $license_valid,
			'licensePageUrl' => admin_url( 'admin.php?page=powersuite-license' ),
			'brandName'      => $brand_name,
			'quickLauncherShortcut' => $option_store->get( 'quick_launcher_shortcut', 'ctrl-shift-k' ),
			'palette'    => [
				'title'            => __( 'Quick Launcher', 'wp-powersuite' ),
				'subtitle'         => __( 'Jump to screens or toggle modules', 'wp-powersuite' ),
				'searchLabel'      => sprintf(
					/* translators: %s: plugin or brand name */
					__( 'Search %s', 'wp-powersuite' ),
					$brand_name
				),
				'searchPlaceholder'=> __( 'Search pages, actions, and modules…', 'wp-powersuite' ),
				'recent'           => __( 'Recent', 'wp-powersuite' ),
				'navigation'       => __( 'Places', 'wp-powersuite' ),
				'modulesSection'   => __( 'Modules', 'wp-powersuite' ),
				'noResults'        => __( 'No matches', 'wp-powersuite' ),
				'noResultsHint'    => __( 'Try different keywords or browse the lists below.', 'wp-powersuite' ),
				'loading'          => __( 'Loading…', 'wp-powersuite' ),
				'loadError'        => __( 'Could not load Quick Launcher data. Please try again.', 'wp-powersuite' ),
				'hintOpen'         => __( 'Open', 'wp-powersuite' ),
				'hintNavigate'     => __( 'Navigate', 'wp-powersuite' ),
				'hintSelect'       => __( 'Select', 'wp-powersuite' ),
				'hintClose'        => __( 'Close', 'wp-powersuite' ),
				'badgeNav'         => __( 'Open', 'wp-powersuite' ),
				'badgeToggleOn'    => __( 'Enable', 'wp-powersuite' ),
				'badgeToggleOff'   => __( 'Disable', 'wp-powersuite' ),
			],
			'strings'    => [
				'enabling'      => __( 'Enabling...', 'wp-powersuite' ),
				'disabling'    => __( 'Disabling...', 'wp-powersuite' ),
				'licenseRequired' => __( 'A valid license is required to enable premium modules.', 'wp-powersuite' ),
				'activateLicense' => __( 'Activate your license', 'wp-powersuite' ),
				'enabled'      => __( 'Enabled', 'wp-powersuite' ),
				'disabled'     => __( 'Disabled', 'wp-powersuite' ),
				'error'        => __( 'An error occurred. Please try again.', 'wp-powersuite' ),
				'confirm'      => __( 'Are you sure?', 'wp-powersuite' ),
				'conflictsWith' => __( 'Conflicts with', 'wp-powersuite' ),
				'conflictEnableWarning' => __( 'This module conflicts with enabled module(s). Disable them first to enable this one.', 'wp-powersuite' ),
				'colorPanelCopy' => __( 'Copy', 'wp-powersuite' ),
				'modulesLoaded'  => __( '%d modules displayed.', 'wp-powersuite' ),
				'modulesNone'    => __( 'No modules match the current filters.', 'wp-powersuite' ),
			],
			'pageSlug'  => $this->admin_menu ? $this->admin_menu->getPageSlug() : 'powersuite',
		];

		wp_localize_script(
			$handle,
			'wpPowerSuite',
			$data
		);
	}

	/**
	 * Check if Plugin Page
	 *
	 * Checks if the current admin page is the WP PowerSuite page.
	 *
	 * @since 1.0.0
	 * @param string $hook_suffix Current admin page hook suffix.
	 * @return bool True if plugin page, false otherwise.
	 */
	private function isPluginPage( string $hook_suffix ): bool {
		if ( ! $this->admin_menu ) {
			return false;
		}

		// Match registered menu hook suffixes (top-level and submenu screens).
		if ( AdminMenu::isPowerSuiteHookSuffix( $hook_suffix ) ) {
			return true;
		}

		// Fallback: screen ID check when hook suffix is unavailable.
		if ( $this->admin_menu->isCurrentPage() ) {
			return true;
		}

		// White-label menu titles change WordPress submenu hook prefixes; page slugs stay stable.
		return AdminMenu::isPowerSuitePageSlug( $this->currentAdminPage() );
	}

	/**
	 * Get Asset URL
	 *
	 * Returns the URL to an asset file.
	 *
	 * @since 1.0.0
	 * @param string $filename Asset filename (e.g., 'admin.css').
	 * @return string Asset URL.
	 */
	private function getAssetUrl( string $filename ): string {
		$plugin_url = defined( 'WP_POWERSUITE_PLUGIN_URL' )
			? WP_POWERSUITE_PLUGIN_URL
			: '';

		// Use forward slashes for URLs regardless of OS
		$assets_dir = 'src/Admin/Assets';

		return $plugin_url . $assets_dir . '/' . $filename;
	}

	/**
	 * Cache-busting version for an admin asset: file modification time when available,
	 * falling back to the plugin version. Ensures CSS/JS changes are picked up on update.
	 */
	private function getAssetVersion( string $filename ): string {
		$plugin_dir = defined( 'WP_POWERSUITE_PLUGIN_DIR' ) ? WP_POWERSUITE_PLUGIN_DIR : '';
		$path       = $plugin_dir . 'src/Admin/Assets/' . $filename;
		if ( $plugin_dir !== '' && is_readable( $path ) ) {
			$mtime = filemtime( $path );
			if ( $mtime ) {
				return (string) $mtime;
			}
		}
		return $this->version;
	}

	/**
	 * Check if Asset Exists
	 *
	 * Checks if an asset file exists on the filesystem.
	 *
	 * @since 1.0.0
	 * @param string $url Asset URL.
	 * @return bool True if asset exists, false otherwise.
	 */
	private function assetExists( string $url ): bool {
		// Convert URL to filesystem path
		$plugin_dir = defined( 'WP_POWERSUITE_PLUGIN_DIR' )
			? WP_POWERSUITE_PLUGIN_DIR
			: '';

		// Extract relative path from URL
		$plugin_url = defined( 'WP_POWERSUITE_PLUGIN_URL' )
			? WP_POWERSUITE_PLUGIN_URL
			: '';

		if ( empty( $plugin_url ) || strpos( $url, $plugin_url ) !== 0 ) {
			return false;
		}

		$relative_path = str_replace( $plugin_url, '', $url );
		$file_path     = $plugin_dir . $relative_path;

		return file_exists( $file_path ) && is_readable( $file_path );
	}

	/**
	 * Get Asset Version
	 *
	 * Returns the asset version for cache busting.
	 *
	 * @since 1.0.0
	 * @return string Asset version.
	 */
	public function getVersion(): string {
		return $this->version;
	}

	/**
	 * Check if Assets are Initialized
	 *
	 * Returns whether assets have been initialized.
	 *
	 * @since 1.0.0
	 * @return bool True if initialized, false otherwise.
	 */
	public function isInitialized(): bool {
		return $this->initialized;
	}
}

