<?php

namespace WC_Affiliate\Controllers\Common;

defined( 'ABSPATH' ) || exit;

/**
 * Asset Controller for WC Affiliate Plugin.
 *
 * Handles registration and enqueuing of CSS and JavaScript assets
 * for both admin and frontend interfaces of the affiliate system.
 *
 * @since 1.0.0
 */
class Asset {

	/**
	 * Controller constructor
	 *
	 * Initializes the asset controller and registers necessary hooks for asset management
	 */
	public function __construct() {
		$this->register_hooks();
	}

	/**
	 * Register hooks for asset controller
	 *
	 * Registers WordPress hooks for asset registration and enqueuing
	 *
	 * @return void
	 */
	protected function register_hooks(): void {
		add_action( 'init', array( $this, 'register_assets' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_dashboard_assets' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_affiliate_dashboard_assets' ) );
	}

	/**
	 * Register all assets on init hook
	 *
	 * Registers all CSS and JavaScript assets for both admin and frontend use
	 *
	 * @return void
	 */
	public function register_assets(): void {
		/**
		 * Action hook fired before asset registration.
		 */
		do_action( 'wc_affiliate_register_assets_before' );

		// Register google font.
		$this->register_google_fonts();

		// Register WC Affiliate Data Stores.
		$this->register_data_stores();

		// Register utilities and others.
		$this->register_utilities_and_others();

		// Register WC Affiliate Admin assets.
		$this->register_admin_dashboard_assets();

		// Register WC Affiliate dashboard assets.
		$this->register_affiliate_dashboard_assets();

		/**
		 * Action hook fired after asset registration.
		 */
		do_action( 'wc_affiliate_register_assets_after' );
	}

	/**
	 * Register Google Fonts
	 *
	 * @return void
	 */
	protected function register_google_fonts() {
		wp_register_style( 'wc-affiliate-google-font-inter', 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap', array(), '1.0.0' );
	}

	/**
	 * Registers data store assets for the plugin.
	 *
	 * This method registers various data store JavaScript assets required for the plugin's functionality,
	 * including dashboard, affiliate, options, referrals, transactions, and visits stores.
	 * For each store type, it checks for the existence of the asset file, includes dependencies,
	 * and registers the script with WordPress.
	 *
	 * @return void
	 */
	protected function register_data_stores() {
		$version = WC_AFFILIATE_VERSION;

		$dashboard_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/dashboard-store.asset.php';
		if ( file_exists( $dashboard_store_asset_file ) ) {
			$dashboard_store_asset = include $dashboard_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-dashboard',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/dashboard-store.js',
				$dashboard_store_asset['dependencies'],
				$dashboard_store_asset['version'] ?? $version,
				true
			);
		}

		$affiliate_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/affiliates-store.asset.php';
		if ( file_exists( $affiliate_store_asset_file ) ) {
			$affiliate_store_asset = include $affiliate_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-affiliates',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/affiliates-store.js',
				$affiliate_store_asset['dependencies'],
				$affiliate_store_asset['version'] ?? $version,
				true
			);
		}

		$referrals_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/referrals-store.asset.php';
		if ( file_exists( $referrals_store_asset_file ) ) {
			$referrals_store_asset = include $referrals_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-referrals',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/referrals-store.js',
				$referrals_store_asset['dependencies'],
				$referrals_store_asset['version'] ?? $version,
				true
			);
		}

		$transactions_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/transactions-store.asset.php';
		if ( file_exists( $transactions_store_asset_file ) ) {
			$transactions_store_asset = include $transactions_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-transactions',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/transactions-store.js',
				$transactions_store_asset['dependencies'],
				$transactions_store_asset['version'] ?? $version,
				true
			);
		}

		$visits_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/visits-store.asset.php';
		if ( file_exists( $visits_store_asset_file ) ) {
			$visits_store_asset = include $visits_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-visits',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/visits-store.js',
				$visits_store_asset['dependencies'],
				$visits_store_asset['version'] ?? $version,
				true
			);
		}

		$settings_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/settings-store.asset.php';
		if ( file_exists( $settings_store_asset_file ) ) {
			$settings_store_asset = include WC_AFFILIATE_PLUGIN_DIR . 'build/stores/settings-store.asset.php';
			wp_register_script(
				'wc-affiliate-stores-settings',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/settings-store.js',
				$settings_store_asset['dependencies'],
				$settings_store_asset['version'] ?? $version,
				true
			);
		}

		$wizard_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/setup-wizard-store.asset.php';
		if ( file_exists( $wizard_store_asset_file ) ) {
			$wizard_store_asset = include $wizard_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-setup-wizard',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/setup-wizard-store.js',
				$wizard_store_asset['dependencies'],
				$wizard_store_asset['version'] ?? $version,
				true
			);
		}

		$export_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/export-store.asset.php';
		if ( file_exists( $export_store_asset_file ) ) {
			$export_store_asset = include $export_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-export',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/export-store.js',
				$export_store_asset['dependencies'],
				$export_store_asset['version'] ?? $version,
				true
			);
		}

		$import_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/import-store.asset.php';
		if ( file_exists( $import_store_asset_file ) ) {
			$import_store_asset = include $import_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-import',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/import-store.js',
				$import_store_asset['dependencies'],
				$import_store_asset['version'] ?? $version,
				true
			);
		}

		$user_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/user-store.asset.php';
		if ( file_exists( $user_store_asset_file ) ) {
			$user_store_asset = include $user_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-user',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/user-store.js',
				$user_store_asset['dependencies'],
				$user_store_asset['version'] ?? $version,
				true
			);
		}

		$notices_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/stores/notices-store.asset.php';
		if ( file_exists( $notices_store_asset_file ) ) {
			$notices_store_asset = include $notices_store_asset_file;
			wp_register_script(
				'wc-affiliate-stores-notices',
				WC_AFFILIATE_PLUGIN_URL . 'build/stores/notices-store.js',
				$notices_store_asset['dependencies'],
				$notices_store_asset['version'] ?? $version,
				true
			);
		}

		do_action( 'wc_affiliate_register_data_stores', $version );
	}

	/**
	 * Registers utility scripts and other miscellaneous assets.
	 *
	 * This method loads utility JavaScript assets that are shared across various parts of the plugin,
	 * retrieves dependencies and version information from the corresponding asset file,
	 * and registers the script with WordPress.
	 *
	 * @return void
	 */
	protected function register_utilities_and_others() {
		$version = WC_AFFILIATE_VERSION;

		$dashboard_store_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/utilities.asset.php';
		if ( file_exists( $dashboard_store_asset_file ) ) {
			$dashboard_store_asset = include $dashboard_store_asset_file;
			wp_register_script(
				'wc-affiliate-utilities',
				WC_AFFILIATE_PLUGIN_URL . 'build/utilities.js',
				$dashboard_store_asset['dependencies'],
				$dashboard_store_asset['version'] ?? $version,
				true
			);
		}
	}

	/**
	 * Registers the assets required for the admin dashboard of the plugin.
	 *
	 * This method loads the necessary JavaScript and CSS assets for the admin dashboard,
	 * retrieves asset dependencies and version information from the corresponding asset file,
	 * and localizes the script with relevant data, such as API base URL and security nonce.
	 *
	 * @return void
	 */
	protected function register_admin_dashboard_assets() {
		$wizard_skip_data = wca_get_option( 'wizard', 'skip', array() );
		$localize_data    = array(
			'api_base'            => rest_url( 'wc-affiliate/v1' ),
			'admin_app_base'      => admin_url( 'admin.php?page=wc-affiliate/#/' ),
			'dashboard_app_base'  => wca_get_dashboard(),
			'nonce'               => wp_create_nonce( 'wp_rest' ),
			'payment_methods'     => wca_get_payment_methods_options(),
			'is_pro_installed'    => wca_has_pro(),
			'is_pro_activated'    => wca_is_pro_activated(),
			'is_stg_pg_reloaded'  => get_option( 'wc_affiliate_settings_page_reloaded', false ),
			'is_wizard_completed' => get_option( 'wc_affiliate_wizard_completed', false ),
			'is_wizard_skipped'   => wca_get_option( 'wizard', 'skip.skipped', false ),
			'new_ticket_url'      => 'https://help.pluggable.io/new-ticket/',
			'docs_url'            => 'https://wcaffiliate.com/docs/',
			'pricing_url'         => 'https://wcaffiliate.com/pricing/',
			'features_url'        => 'https://wcaffiliate.com/#wc-features-section',
			'setup_wizard'        => array(
				'skip_data'       => $wizard_skip_data,
				'skip_reasons'    => array(
					'already_configured' => __( 'Already configured manually', 'wc-affiliate' ),
					'too_complex'        => __( 'Setup is too complex', 'wc-affiliate' ),
					'not_ready'          => __( 'Not ready to configure yet', 'wc-affiliate' ),
					'custom'             => __( 'Other reason', 'wc-affiliate' ),
				),
				'confirm_message' => __( 'Are you sure you want to skip the setup wizard? You can always access it later from the menu.', 'wc-affiliate' ),
				'skip_success'    => __( 'Setup wizard skipped successfully. You can now configure the plugin manually or access it later from the menu.', 'wc-affiliate' ),
			),
			'notices'             => apply_filters(
				'wc_affiliate_notices_localize_data',
				array(
					'after_sw_notice_dismissed' => get_option( 'wc_affiliate_after_sw_notice_dismissed', false ),
				)
			),
		);

		$asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/admin-dashboard.asset.php';
		if ( file_exists( $asset_file ) ) {
			$asset = include $asset_file;
			wp_register_script(
				'wc-affiliate-admin-dashboard',
				WC_AFFILIATE_PLUGIN_URL . 'build/admin-dashboard.js',
				$asset['dependencies'],
				$asset['version'] ?? WC_AFFILIATE_VERSION,
				true
			);

			wp_register_style(
				'wc-affiliate-admin-dashboard',
				WC_AFFILIATE_PLUGIN_URL . 'build/admin-dashboard.css',
				array( 'wc-affiliate-google-font-inter' ),
				$asset['version'] ?? WC_AFFILIATE_VERSION,
			);

			wp_set_script_translations( 'wc-affiliate-admin-dashboard', 'wc-affiliate' );

			wp_localize_script(
				'wc-affiliate-admin-dashboard',
				'WC_AFFILIATE_PLUGIN_ADMIN',
				apply_filters( 'wc_affiliate_admin_dashboard_localize_data', $localize_data )
			);
		}

		$general_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/general-admin.asset.php';
		if ( file_exists( $general_asset_file ) ) {
			$asset = include $general_asset_file;

			wp_register_script(
				'wc-affiliate-general-admin',
				WC_AFFILIATE_PLUGIN_URL . 'build/general-admin.js',
				$asset['dependencies'],
				$asset['version'] ?? WC_AFFILIATE_VERSION,
				true
			);

			wp_set_script_translations( 'wc-affiliate-general-admin', 'wc-affiliate' );
		}
	}

	/**
	 * Registers the assets required for the affiliate dashboard.
	 *
	 * This method loads JavaScript and CSS assets necessary for the affiliate dashboard,
	 * retrieves dependencies and versioning information from the corresponding asset file,
	 * sets script translations, and localizes the script with affiliate-specific data including
	 * API base URL, nonces, user tokens, AJAX URL, chart data, and various settings.
	 *
	 * @return void
	 */
	protected function register_affiliate_dashboard_assets() {
		$enable_recaptcha = wca_is_recaptcha_enabled() ? 'on' : 'off';
		$minimum_payout   = wca_get_minimum_payout();
		$localize_data    = array(
			'has_pro'            => wca_has_pro(),
			'token'              => wca_get_token(),
			'ref_key'            => wca_get_ref_key(),
			'logout_url'         => wp_logout_url(),
			'home_url'           => home_url(),
			'api_base'           => rest_url( 'wc-affiliate/v1' ),
			'nonce'              => wp_create_nonce( 'wp_rest' ),
			'ajaxurl'            => admin_url( 'admin-ajax.php' ),
			'charts'             => apply_filters( 'wc_affiliate_front_charts', array() ),
			'_nonce'             => wp_create_nonce( 'wc-affiliate' ),
			'enable_recaptcha'   => $enable_recaptcha,
			'minimum_payout'     => wca_format_price( $minimum_payout ),
			'minimum_payout_raw' => $minimum_payout,
			'enabled_methods'    => wca_get_enabled_payout_methods(),
			'recaptcha_message'  => __( 'Please verify you are human!', 'wc-affiliate' ),
		);

		if ( 'on' === $enable_recaptcha ) {
			wp_register_script( 'recaptcha', 'https://www.google.com/recaptcha/api.js', array( 'jquery' ), '1.0.0', false );
		}

		$asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/affiliate-dashboard.asset.php';
		if ( file_exists( $asset_file ) ) {
			$asset = include $asset_file;
			wp_register_script(
				'wc-affiliate-dashboard',
				WC_AFFILIATE_PLUGIN_URL . 'build/affiliate-dashboard.js',
				$asset['dependencies'],
				$asset['version'] ?? WC_AFFILIATE_VERSION,
				true
			);

			wp_register_style(
				'wc-affiliate-dashboard',
				WC_AFFILIATE_PLUGIN_URL . 'build/affiliate-dashboard.css',
				array( 'wc-affiliate-google-font-inter' ),
				$asset['version'] ?? WC_AFFILIATE_VERSION,
			);

			wp_set_script_translations( 'wc-affiliate-dashboard', 'wc-affiliate' );

			wp_localize_script(
				'wc-affiliate-dashboard',
				'WC_AFFILIATE_FRONT',
				apply_filters( 'wc_affiliate_dashboard_localize_data', $localize_data )
			);
		}

		// general assets.
		$general_asset_file = WC_AFFILIATE_PLUGIN_DIR . 'build/general-frontend.asset.php';
		if ( file_exists( $general_asset_file ) ) {
			$general_asset = include $general_asset_file;
			wp_register_script(
				'wc-affiliate-general-frontend',
				WC_AFFILIATE_PLUGIN_URL . 'build/general-frontend.js',
				$general_asset['dependencies'],
				$general_asset['version'] ?? WC_AFFILIATE_VERSION,
				true
			);

			wp_register_style(
				'wc-affiliate-general-frontend',
				WC_AFFILIATE_PLUGIN_URL . 'build/general-frontend.css',
				array(),
				$legacy_asset['version'] ?? WC_AFFILIATE_VERSION,
			);

			wp_set_script_translations( 'wc-affiliate-general-frontend', 'wc-affiliate' );

			$localize_data['is_general'] = true;

			wp_localize_script(
				'wc-affiliate-general-frontend',
				'WCAFFILIATE',
				apply_filters( 'wc_affiliate_dashboard_localize_data', $localize_data )
			);
		}
	}

	/**
	 * Enqueues the necessary JavaScript and CSS assets for the admin dashboard.
	 *
	 * @return void
	 */
	public function enqueue_admin_dashboard_assets() {
		/**
		 * Action hook fired before admin dashboard assets enqueuing.
		 */
		do_action( 'wc_affiliate_enqueue_admin_dashboard_assets_before' );

		wp_enqueue_script( 'wc-affiliate-general-admin' );

		$current_screen = get_current_screen();
		if ( 'toplevel_page_wc-affiliate' === $current_screen->id ) {
			// Enqueue WordPress editor for text-editor field support.
			wp_enqueue_media();
			wp_enqueue_editor();
			wp_enqueue_script( 'wp-tinymce' );

			wp_enqueue_script( 'wc-affiliate-admin-dashboard' );
			wp_enqueue_style( 'wc-affiliate-admin-dashboard' );

			// Suppress all WP admin notices when the setup-wizard route is active.
			// React toggles the `wca-wizard-active` class on <body> on mount/unmount.
			wp_add_inline_style(
				'wc-affiliate-admin-dashboard',
				'body.wca-wizard-active .notice,
body.wca-wizard-active .notice-warning,
body.wca-wizard-active .notice-error,
body.wca-wizard-active .notice-success,
body.wca-wizard-active .notice-info,
body.wca-wizard-active #message,
body.wca-wizard-active .update-nag,
body.wca-wizard-active .updated,
body.wca-wizard-active .error { display: none !important; }'
			);
		}

		/**
		 * Action hook fired after admin dashboard assets enqueuing.
		 */
		do_action( 'wc_affiliate_enqueue_admin_dashboard_assets_after' );
	}

	/**
	 * Enqueues the required JavaScript and CSS assets for the affiliate dashboard.
	 *
	 * @return void
	 */
	public function enqueue_affiliate_dashboard_assets() {
		/**
		 * Action hook fired before affiliate dashboard assets enqueuing.
		 */
		do_action( 'wc_affiliate_enqueue_affiliate_dashboard_assets_before' );

		if ( wca_is_recaptcha_enabled() ) {
			wp_enqueue_script( 'recaptcha' );
		}

		// General assets.
		wp_enqueue_script( 'wc-affiliate-general-frontend' );
		wp_enqueue_style( 'wc-affiliate-general-frontend' );

		// Load assets for new structure.
		wp_enqueue_media();
		wp_enqueue_editor();
		wp_enqueue_script( 'wp-tinymce' );

		wp_enqueue_script( 'wc-affiliate-dashboard' );
		wp_enqueue_style( 'wc-affiliate-dashboard' );

		/**
		 * Action hook fired after affiliate dashboard assets enqueuing.
		 */
		do_action( 'wc_affiliate_enqueue_affiliate_dashboard_assets_after' );
	}
}
