<?php
/**
 * Manage Assets
 *
 * @package Tutor
 * @author Themeum <support@themeum.com>
 * @link https://themeum.com
 * @since 1.0.0
 */

namespace TUTOR;

use Tutor\Ecommerce\CartController;
use Tutor\Ecommerce\CheckoutController;
use Tutor\Ecommerce\CouponController;
use Tutor\Ecommerce\OptionKeys;
use Tutor\Ecommerce\OrderController;
use Tutor\Ecommerce\Settings;
use Tutor\Models\CourseModel;
use Tutor\Options_V2;

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

/**
 * Assets class
 *
 * @since 1.0.0
 */
class Assets {


	/**
	 * Constructor
	 *
	 * @since 1.0.0
	 *
	 * @since 3.0.0 register hook param added
	 *
	 * @param bool $register_hooks param added to enable or disable registering hooks.
	 *
	 * @return void
	 */
	public function __construct( $register_hooks = true ) {
		if ( ! $register_hooks ) {
			return;
		}

		/**
		 * Common scripts loading
		 */
		add_action( 'admin_enqueue_scripts', array( $this, 'common_scripts' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'common_scripts' ) );
		/**
		 * Front and backend script enqueue
		 */
		add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );

		add_action( 'admin_enqueue_scripts', array( $this, 'load_meta_data' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'load_meta_data' ) );

		/**
		 * Text domain loading
		 */
		add_action( 'admin_enqueue_scripts', array( $this, 'tutor_script_text_domain' ), 100 );
		add_action( 'wp_enqueue_scripts', array( $this, 'tutor_script_text_domain' ), 100 );
		add_filter( 'tutor_localize_data', array( $this, 'modify_localize_data' ) );

		/**
		 * Register translatable function to load
		 * Handled script with text domain attached to
		 *
		 * @since 1.9.0
		 */
		add_action( 'admin_head', array( $this, 'tutor_add_mce_button' ) );
		add_filter( 'get_the_generator_html', array( $this, 'tutor_generator_tag' ), 10, 2 );
		add_filter( 'get_the_generator_xhtml', array( $this, 'tutor_generator_tag' ), 10, 2 );

		/**
		 * Add translation support for external tinyMCE button
		 *
		 * @since 1.9.7
		 */
		add_filter( 'mce_external_languages', array( $this, 'tutor_tinymce_translate' ) );

		/**
		 * Identifier class to body tag
		 *
		 * @since v1.9.9
		 */
		add_filter( 'body_class', array( $this, 'add_identifier_class_to_body' ) );
		add_filter( 'admin_body_class', array( $this, 'add_identifier_class_to_body' ) );

		/**
		 * Add edit with front end builder button on Gutenberg editor
		 *
		 * @since v2.0.5
		 */
		add_action( 'enqueue_block_editor_assets', __CLASS__ . '::add_frontend_editor_button' );

		/**
		 * Enqueue styles & scripts
		 *
		 * @since 4.0.0
		 */
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );

		// Add custom meta.
		add_action( 'wp_head', array( $this, 'add_custom_data' ) );

		/**
		 * Add preload to CSS
		 *
		 * @since 4.0.0
		 */
		add_filter( 'style_loader_tag', array( $this, 'add_preload_to_css' ), 10, 2 );
	}

	/**
	 * Load default localized data
	 *
	 * @since 1.0.0
	 * @return array
	 */
	public function get_default_localized_data() {
		$home_url = get_home_url();
		$parsed   = parse_url( $home_url );

		$base_path = ( is_array( $parsed ) && isset( $parsed['path'] ) ) ? $parsed['path'] : '/';
		$base_path = rtrim( $base_path, '/' ) . '/';

		$post_id   = get_the_ID();
		$post_type = get_post_type( $post_id );

		$current_page = tutor_utils()->get_current_page_slug();

		/**
		 * Only required current user data.
		 *
		 * @since 2.6.2
		 */
		$current_user = array();
		$userdata     = get_userdata( get_current_user_id() );

		if ( $userdata ) {
			$current_user = array(
				'roles' => array_values( $userdata->roles ),
				'data'  => array(
					'id'           => $userdata->ID,
					'display_name' => $userdata->display_name,
				),
			);
		}

		$tutor_currency = array(
			'symbol'             => Settings::get_currency_symbol_by_code( tutor_utils()->get_option( OptionKeys::CURRENCY_CODE, 'USD' ) ),
			'currency'           => tutor_utils()->get_option( OptionKeys::CURRENCY_CODE ),
			'position'           => tutor_utils()->get_option( OptionKeys::CURRENCY_POSITION, 'left' ),
			'thousand_separator' => tutor_utils()->get_option( OptionKeys::THOUSAND_SEPARATOR, ',' ),
			'decimal_separator'  => tutor_utils()->get_option( OptionKeys::DECIMAL_SEPARATOR, '.' ),
			'no_of_decimal'      => tutor_utils()->get_option( OptionKeys::NUMBER_OF_DECIMALS, '2' ),
		);

		/**
		 * Get only required options.
		 *
		 * @since 3.0.0
		 */
		$required_options = array(
			'monetize_by',
		);

		$tutor_settings = Options_V2::get_only( $required_options );

		// Load available kids mode icons to avoid frontend 404s if kids mode is active.
		$kids_icons = array();
		if ( tutor_utils()->is_kids_mode() ) {
			$kids_icons = array_map(
				function ( $file ) {
					return basename( $file, '.svg' );
				},
				glob( tutor()->path . 'assets/icons/kids/*.svg' ) ?: array()
			);
		}

		return array(
			'ajaxurl'                      => admin_url( 'admin-ajax.php' ),
			'home_url'                     => rtrim( get_home_url(), '/' ),
			'site_url'                     => rtrim( get_site_url(), '/' ),
			'site_title'                   => get_bloginfo( 'title' ),
			'base_path'                    => tutor()->basepath,
			'tutor_url'                    => tutor()->url,
			'tutor_pro_url'                => function_exists( 'tutor_pro' ) ? tutor_pro()->url : null,
			'nonce_key'                    => tutor()->nonce,
			tutor()->nonce                 => wp_create_nonce( tutor()->nonce_action ),
			'loading_icon_url'             => get_admin_url() . 'images/wpspin_light.gif',
			'placeholder_img_src'          => tutor_placeholder_img_src(),
			'enable_lesson_classic_editor' => get_tutor_option( 'enable_lesson_classic_editor' ),
			'tutor_frontend_dashboard_url' => tutor_utils()->get_tutor_dashboard_page_permalink(),
			'wp_date_format'               => tutor_js_date_format_against_wp(),
			'start_of_week'                => get_option( 'start_of_week', 1 ),
			'is_admin'                     => is_admin(),
			'is_admin_bar_showing'         => is_admin_bar_showing(),
			'addons_data'                  => tutor_utils()->prepare_free_addons_data(),
			'current_user'                 => $current_user,
			'content_change_event'         => 'tutor_content_changed_event',
			'is_tutor_course_edit'         => isset( $_GET['action'] ) && 'edit' === $_GET['action'] && tutor()->course_post_type === get_post_type( get_the_ID() ) ? true : false,
			'current_page'                 => $current_page,
			'quiz_answer_display_time'     => 1000 * (int) tutor_utils()->get_option( 'quiz_answer_display_time' ),
			'is_ssl'                       => is_ssl(),
			'course_list_page_url'         => admin_url( 'admin.php?page=tutor' ),
			'course_post_type'             => tutor()->course_post_type,
			'tutor_currency'               => $tutor_currency,
			'local'                        => get_locale(),
			'settings'                     => $tutor_settings,
			'max_upload_size'              => wp_max_upload_size(),
			'monetize_by'                  => tutor_utils()->get_option( 'monetize_by' ),
			'kids_icons_registry'          => $kids_icons,
			'is_kids_mode'                 => tutor_utils()->is_kids_mode(),
			'user_preferences'             => UserPreference::get_preferences( get_current_user_id() ),
			'is_legacy_learning_mode'      => tutor_utils()->is_legacy_learning_mode(),
			'course_slug'                  => tutor_utils()->get_option( 'course_permalink_base', 'courses' ),
			'lesson_slug'                  => tutor_utils()->get_option( 'lesson_permalink_base', 'lessons' ),
			'quiz_slug'                    => tutor_utils()->get_option( 'quiz_permalink_base', 'quizzes' ),
			'is_tour_completed'            => (bool) get_user_meta( get_current_user_id(), User::TOUR_COMPLETED_META, true ),
		);
	}

	/**
	 * Enqueue scripts for admin
	 *
	 * @since 1.0.0
	 * @since 3.0.0 Order details & coupon scripts added.
	 *
	 * @param string $slug The page slug.
	 *
	 * @return void
	 */
	public function admin_scripts( $slug ) {
		wp_enqueue_style( 'tutor-select2', tutor()->url . 'assets/lib/select2/select2.min.css', array(), TUTOR_VERSION );
		wp_enqueue_style( 'tutor-admin', tutor()->url . 'assets/css/tutor-admin.min.css', array(), TUTOR_VERSION );

		/**
		 * Scripts
		 */
		wp_enqueue_media();

		wp_enqueue_script( 'wp-color-picker' );
		wp_enqueue_style( 'wp-color-picker' );

		wp_enqueue_script( 'jquery-ui-slider' );
		wp_enqueue_script( 'jquery-ui-datepicker' );

		wp_enqueue_script( 'tutor-select2', tutor()->url . 'assets/lib/select2/select2.full.min.js', array( 'jquery' ), TUTOR_VERSION, true );
		wp_enqueue_script( 'tutor-admin', tutor()->url . 'assets/js/tutor-admin.js', array( 'jquery', 'tutor-script', 'wp-color-picker', 'wp-i18n', 'wp-data' ), TUTOR_VERSION, true );

		// Tutor order detail & coupon scripts.
		$page     = Input::get( 'page', '' );
		$action   = Input::get( 'action' );
		$sub_page = Input::get( 'sub_page' );

		$allowed_actions = array( 'add_new', 'edit' );

		if ( tutor_utils()->is_monetize_by_tutor() ) {
			if ( OrderController::PAGE_SLUG === $page && 'edit' === $action ) {
				wp_enqueue_script( 'tutor-order-details', tutor()->url . 'assets/js/tutor-order-details.js', array( 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );
			}

			if ( CouponController::PAGE_SLUG === $page && in_array( $action, $allowed_actions, true ) ) {
				wp_enqueue_script( 'tutor-coupon', tutor()->url . 'assets/js/tutor-coupon.js', array( 'wp-date', 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );
			}

			// @since 3.0.0 add tax react app on the settings page.
			if ( 'tutor_settings' === $page && ! Input::has( 'edit' ) ) {
				wp_enqueue_editor();
				wp_enqueue_script( 'tutor-tax-settings', tutor()->url . 'assets/js/tutor-tax-settings.js', array( 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );
				wp_enqueue_script( 'tutor-payment-settings', tutor()->url . 'assets/js/tutor-payment-settings.js', array( 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );
			}
		}

		if ( 'tutor-tools' === $page && 'import_export' === $sub_page ) {
				wp_enqueue_script( 'tutor-import-export', tutor()->url . 'assets/js/tutor-import-export.js', array( 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );
		}

		if ( 'tutor-addons' === $page ) {
			wp_enqueue_script( 'tutor-coupon', tutor()->url . 'assets/js/tutor-addon-list.js', array( 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );
		}
	}

	/**
	 * Load frontend scripts
	 *
	 * @since 1.0.0
	 *
	 * @since 4.0.0 Legacy scripts loading check added.
	 *
	 * @return void
	 */
	public function frontend_scripts() {
		$load_legacy_scripts = self::should_load_legacy_scripts();
		if ( ! $load_legacy_scripts ) {
			return;
		}

		/**
		 * We checked wp_enqueue_editor() in condition because it conflicting with Divi Builder
		 * condition updated @since v.1.7.4
		 *
		 * @since 2.7.0 is_user_logged_in() check added to remove duplicate H1 tag on each single post.
		 */
		if ( is_single() && is_user_logged_in() ) {
			if ( function_exists( 'et_pb_is_pagebuilder_used' ) ) {
				$is_page_builder_used = et_pb_is_pagebuilder_used( get_the_ID() );
				if ( ! $is_page_builder_used ) {
					wp_enqueue_editor();
					wp_enqueue_script( 'quicktags' );
				}
			} else {
				wp_enqueue_editor();
				wp_enqueue_script( 'quicktags' );
			}
		}

		/**
		 * Enabling Sorting, draggable, droppable...
		 */
		wp_enqueue_script( 'jquery-ui-sortable' );
        wp_enqueue_script('jquery-touch-punch', ['jquery-ui-sortable']); //phpcs:ignore

		// Plyr.
		if ( is_single_course( true ) ) {
			wp_enqueue_style( 'tutor-plyr', tutor()->url . 'assets/lib/plyr/plyr.css', array(), TUTOR_VERSION );
			wp_enqueue_script( 'tutor-plyr', tutor()->url . 'assets/lib/plyr/plyr.polyfilled.min.js', array( 'jquery' ), TUTOR_VERSION, true );
		}

		// Social Share.
		wp_enqueue_script( 'tutor-social-share', tutor()->url . 'assets/lib/SocialShare/SocialShare.min.js', array( 'jquery' ), TUTOR_VERSION, true );

		/**
		 * Dependency wp-i18n added for translate js file
		 *
		 * @since 1.9.0
		 */
		wp_enqueue_style( 'tutor-frontend', tutor()->url . 'assets/css/tutor-front.min.css', array(), TUTOR_VERSION );
		wp_enqueue_script( 'tutor-frontend', tutor()->url . 'assets/js/tutor-front.js', array( 'jquery', 'wp-i18n', 'wp-date' ), TUTOR_VERSION, true );
	}

	/**
	 * Modify localize data
	 *
	 * @since 1.0.0
	 *
	 * @param array $localize_data localize data.
	 * @return array
	 */
	public function modify_localize_data( $localize_data ) {
		global $post;

		if ( is_admin() ) {
			$taxonomy = Input::get( 'taxonomy' );
			if ( CourseModel::COURSE_CATEGORY === $taxonomy || CourseModel::COURSE_TAG === $taxonomy ) {
				$localize_data['open_tutor_admin_menu'] = true;
			}

			if ( 'en_US' !== $localize_data['local'] ) {
				$page            = Input::get( 'page', '' );
				$action          = Input::get( 'action' );
				$allowed_actions = array( 'add_new', 'edit' );
				if ( CouponController::PAGE_SLUG === $page && in_array( $action, $allowed_actions, true ) ) {
					$localize_data['coupon_main_content_locales'] = tutils()->get_script_locale_data( 'tutor-coupon-main-content', $localize_data['local'] );
				}
			}
		} else {

			// Assign quiz option.
			if ( ! empty( $post->post_type ) && 'tutor_quiz' === $post->post_type ) {
				$single_quiz_options = (array) tutor_utils()->get_quiz_option( $post->ID );
				$saved_quiz_options  = array(
					'quiz_when_time_expires' => tutor_utils()->get_option( 'quiz_when_time_expires' ),
				);

				$quiz_options = array_merge( $single_quiz_options, $saved_quiz_options );

				$previous_attempts = tutor_utils()->quiz_attempts();

				if ( $previous_attempts && count( $previous_attempts ) ) {
					$quiz_options['quiz_auto_start'] = 0;
				}

				$localize_data['quiz_options'] = $quiz_options;
			}

			// Including player assets if video exists.
			if ( tutor_utils()->has_video_in_single() ) {
				$localize_data['post_id']         = get_the_ID();
				$localize_data['best_watch_time'] = 0;

				$best_watch_time = tutor_utils()->get_lesson_reading_info( get_the_ID(), 0, 'video_best_watched_time' );
				if ( $best_watch_time > 0 ) {
					$localize_data['best_watch_time'] = $best_watch_time;
				}
			}
		}

		return $localize_data;
	}

	/**
	 * Load common scripts for frontend and backend
	 *
	 * @since 1.0.0
	 *
	 * @since 4.0.0 Legacy scripts loading check added.
	 *
	 * @param string $slug The page slug.
	 *
	 * @return void
	 */
	public function common_scripts( $slug ) {
		if ( ! self::should_load_legacy_scripts() ) {
			return;
		}

		/**
		 * Load TinyMCE for tutor settings page if tutor pro is not available.
		 *
		 * @since v2.0.8
		 */
		$baseurl      = includes_url( 'js/tinymce' );
		$current_page = Input::get( 'page' );

		// If it is settings page & tutor pro not activated.
		if ( 'tutor_settings' === $current_page && ! wp_script_is( 'wp-tinymce-root' ) ) {
			wp_enqueue_script( 'tutor-tiny', $baseurl . '/tinymce.min.js', array( 'jquery' ), TUTOR_VERSION, true );
		}
		wp_enqueue_style( 'tutor-icon', tutor()->url . 'assets/css/tutor-icon.min.css', array(), TUTOR_VERSION );

		// Common css library.
		if ( is_rtl() ) {
			wp_enqueue_style( 'tutor', tutor()->url . 'assets/css/tutor-rtl.min.css', array(), TUTOR_VERSION );
		} else {
			wp_enqueue_style( 'tutor', tutor()->url . 'assets/css/tutor.min.css', array(), TUTOR_VERSION );
		}

		/**
		 * Load tutor common scripts both backend and frontend
		 *
		 * @since v2.0.0
		 */
		wp_enqueue_script( 'tutor-script', tutor()->url . 'assets/js/tutor.js', array( 'jquery', 'wp-i18n', 'wp-element' ), TUTOR_VERSION, true );

		/**
		 * Enqueue datetime countdown scripts & styles
		 *
		 * Add filter to enqueue countdown scripts & styles
		 * don't return false if it is true to prevent conflict
		 * with other filters
		 *
		 * @since v2.1.0
		 */
		$should_enqueue = apply_filters( 'tutor_should_enqueue_countdown_scripts', false );
		if ( $should_enqueue ) {
			wp_enqueue_script( 'tutor-moment', tutor()->url . 'assets/lib/countdown/moment.min.js', array(), TUTOR_VERSION, true );

			wp_enqueue_script( 'tutor-moment-timezone', tutor()->url . 'assets/lib/countdown/moment-timezone-with-data.min.js', array(), TUTOR_VERSION, true );

			wp_enqueue_script( 'tutor-jquery-countdown', tutor()->url . 'assets/lib/countdown/jquery.countdown.min.js', array( 'jquery' ), TUTOR_VERSION, true );

			wp_enqueue_script( 'tutor-countdown', tutor()->url . 'assets/lib/countdown/tutor-countdown.min.js', array( 'jquery' ), TUTOR_VERSION, true );

			wp_enqueue_style( 'tutor-countdown', tutor()->url . 'assets/lib/countdown/tutor-countdown.min.css', '', TUTOR_VERSION );
		}
	}

	/**
	 * Load meta data
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function load_meta_data() {
		// Localize scripts.
		$localize_data = apply_filters( 'tutor_localize_data', $this->get_default_localized_data() );
		wp_localize_script( 'tutor-frontend', '_tutorobject', $localize_data );
		wp_localize_script( 'tutor-admin', '_tutorobject', $localize_data );
		wp_localize_script( 'tutor-script', '_tutorobject', $localize_data );
		wp_localize_script( 'tutor-order-details', '_tutorobject', $localize_data );
		wp_localize_script( 'tutor-tax-settings', '_tutorobject', $localize_data );
		wp_localize_script( 'tutor-coupon', '_tutorobject', $localize_data );
		wp_localize_script( 'tutor-course-builder', '_tutorobject', $localize_data );

		// Inline styles.
		wp_add_inline_style( 'tutor-frontend', $this->load_color_palette() );
		wp_add_inline_style( 'tutor-admin', $this->load_color_palette() );
	}

	/**
	 * Load color palette
	 *
	 * @since 1.0.0
	 * @return string
	 */
	private function load_color_palette() {
		$colors = array(
			'tutor_primary_color'       => '--tutor-color-primary',
			'tutor_primary_hover_color' => '--tutor-color-primary-hover',
			'tutor_text_color'          => '--tutor-body-color',
			'tutor_border_color'        => '--tutor-border-color',
			'tutor_gray_color'          => '--tutor-color-gray',
		);

		// Admin colors.
		$admin_colors = array();
		if ( is_admin() ) {
			$admin_colors = array(
				'--tutor-color-primary'       => '#3E64DE',
				'--tutor-color-primary-hover' => '#3A5CCC',
				'--tutor-body-color'          => '#212327',
				'--tutor-border-color'        => '#CDCFD5',
				'--tutor-color-gray'          => '#CDCFD5',
			);
		}

		$fallback_colors = array(
			'tutor_primary_color'       => '#3E64DE',
			'tutor_primary_hover_color' => '#3A5CCC',
			'tutor_text_color'          => '#212327',
			'tutor_border_color'        => '#E3E5EB',
			'tutor_gray_color'          => '#CDCFD5',
		);

		$brand_color = tutor_utils()->get_brand_color();

		$color_string = '';
		foreach ( $colors as $key => $property ) {
			$fallback_color = isset( $fallback_colors[ $key ] ) ? $fallback_colors[ $key ] : '#212327';
			$color          = $fallback_color;

			if ( Options_V2::DEFAULT_BRAND_COLOR !== $brand_color ) {
				if ( 'tutor_primary_color' === $key ) {
					$color = $brand_color;
				}

				if ( 'tutor_primary_hover_color' === $key ) {
					$palette = $this->generate_color_palette( $brand_color );
					$color   = $palette[700];
				}
			}

			$color_rgb = tutor_utils()->hex2rgb( $color );

			if ( is_admin() && isset( $admin_colors[ $property ] ) ) {
				$color     = $admin_colors[ $property ];
				$color_rgb = tutor_utils()->hex2rgb( $admin_colors[ $property ] );
			}

			if ( $color ) {
				$color_string .= $property . ':' . $color . ';';
			}

			if ( $color_rgb ) {
				$color_string .= $property . '-rgb:' . $color_rgb . ';';
			}
		}

		return ':root{' . $color_string . '}';
	}

	/**
	 * Generate color palette
	 *
	 * @since 4.0.0
	 *
	 * @param string $base_hex HEX color code.
	 *
	 * @return array
	 */
	private function generate_color_palette( $base_hex ) {
		$base = tutor_utils()->hex_to_hsl( $base_hex );

		// Mapping of [Hue-Shift, Saturation-Shift, Target-Lightness].
		$rules = array(
			100 => array( -1, 3, 97.5 ),
			200 => array( -3, 1, 94.1 ),
			300 => array( -3, -2, 92.2 ),
			400 => array( -4, 0, 79.6 ),
			450 => array( -2, -3, 76.7 ),
			500 => array( -4, 5, 59.8 ),
			600 => array( 0, 0, $base['l'] ),
			700 => array( 3, -7, 48.0 ),
			800 => array( 4, -12, 40.2 ),
			900 => array( 5, -17, 33.1 ),
			950 => array( 6, -24, 20.8 ),
		);

		$palette = array();
		foreach ( $rules as $weight => $modifier ) {
			if ( 600 === $weight ) {
				$palette[ $weight ] = strtolower( $base_hex );
				continue;
			}

			$new_h = fmod( ( $base['h'] + $modifier[0] + 360 ), 360 );
			$new_s = max( 0, min( 100, $base['s'] + $modifier[1] ) );
			$new_l = max( 0, min( 100, $modifier[2] ) );

			$palette[ $weight ] = tutor_utils()->hsl_to_hex( $new_h, $new_s, $new_l );
		}

		return $palette;
	}

	/**
	 * Load core color palette
	 *
	 * @since 4.0.0
	 *
	 * @param string $brand_color Base color code.
	 *
	 * @return string
	 */
	private function load_core_color_palette( $brand_color ) {
		if ( empty( $brand_color ) ) {
			return '';
		}

		$palette = $this->generate_color_palette( $brand_color );

		return "
			:root {
			--tutor-brand-100: {$palette[100]};
			--tutor-brand-200: {$palette[200]};
			--tutor-brand-300: {$palette[300]};
			--tutor-brand-400: {$palette[400]};
			--tutor-brand-450: {$palette[450]};
			--tutor-brand-500: {$palette[500]};
			--tutor-brand-600: {$palette[600]};
			--tutor-brand-700: {$palette[700]};
			--tutor-brand-800: {$palette[800]};
			--tutor-brand-900: {$palette[900]};
			--tutor-brand-950: {$palette[950]};
			}
		";
	}

	/**
	 * Add Tinymce button for placing shortcode
	 *
	 * @since 1.0.0
	 * @return void|null
	 */
	public function tutor_add_mce_button() {
		// Check user permissions.
		if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
			return;
		}
		// Check if WYSIWYG is enabled.
		if ( 'true' == get_user_option( 'rich_editing' ) ) {
			add_filter( 'mce_external_plugins', array( $this, 'tutor_add_tinymce_js' ) );
			add_filter( 'mce_buttons', array( $this, 'tutor_register_mce_button' ) );
		}
	}

	/**
	 * Add tinymce button
	 *
	 * @since 1.0.0
	 *
	 * @param array $plugin_array plugin array.
	 * @return array
	 */
	public function tutor_add_tinymce_js( $plugin_array ) {
		$plugin_array['tutor_button'] = tutor()->url . 'assets/lib/mce-button.js';
		return $plugin_array;
	}

	/**
	 * Register new button in the editor
	 *
	 * @since 1.0.0
	 *
	 * @param array $buttons buttons.
	 * @return array
	 */
	public function tutor_register_mce_button( $buttons ) {
		array_push( $buttons, 'tutor_button' );
		return $buttons;
	}

	/**
	 * Output generator tag to aid debugging.
	 *
	 * @since 1.0.0
	 *
	 * @param string $gen Generator.
	 * @param string $type Type.
	 *
	 * @return string
	 */
	public function tutor_generator_tag( $gen, $type ) {
		switch ( $type ) {
			case 'html':
				$gen .= "\n" . '<meta name="generator" content="TutorLMS ' . TUTOR_VERSION . '">';
				break;
			case 'xhtml':
				$gen .= "\n" . '<meta name="generator" content="TutorLMS ' . TUTOR_VERSION . '" />';
				break;
		}
		return $gen;
	}

	/**
	 * Load text domain handled script after all enqueue_scripts
	 * registered functions
	 *
	 * @since 1.9.0
	 * @since 3.9.2 Refactored to dynamically detect scripts instead of hardcoded list.
	 *
	 * @return void
	 */
	public function tutor_script_text_domain() {
		global $wp_scripts;

		if ( empty( $wp_scripts->registered ) ) {
			return;
		}

		foreach ( $wp_scripts->registered as $handle => $data ) {
			$src           = $data->src ?? '';
			$is_from_tutor = str_contains( $src, 'tutor/assets/js' );

			if ( ! $is_from_tutor ) {
				continue;
			}

			wp_set_script_translations( $handle, 'tutor', tutor()->path . 'languages/' );
		}
	}

	/**
	 * Add translation support for external tinyMCE button
	 *
	 * @since 1.9.7
	 * @return array
	 */
	public function tutor_tinymce_translate() {
		$locales['tutor_button'] = tutor()->path . 'includes/tinymce_translate.php';
		return $locales;
	}

	/**
	 * Add an identifier class to body
	 *
	 * @since 1.0.0
	 *
	 * @param mixed $classes classes.
	 * @return mixed
	 */
	public function add_identifier_class_to_body( $classes ) {
		$course_builder_screen = tutor_utils()->get_course_builder_screen();
		$to_add                = array( 'tutor-lms' );

		// Add backend course editor identifier class to body.
		if ( $course_builder_screen ) {
			$to_add[] = is_admin() ? 'tutor-backend' : 'tutor-frontend';
			$to_add[] = ' tutor-screen-course-builder tutor-screen-course-builder-' . $course_builder_screen . ' ';
		}

		// Add frontend course builder identifier class.
		if ( ! $course_builder_screen && tutor_utils()->is_tutor_frontend_dashboard() ) {
			$to_add[] = 'tutor-screen-frontend-dashboard';
		}

		if ( is_post_type_archive( tutor()->course_post_type ) ) {
			$to_add[] = 'tutor-frontend';
		}

		if ( tutor_utils()->is_tutor_frontend_dashboard() ) {
			$to_add[] = 'tutor-frontend';
		}

		if ( is_single() ) {
			global $post;

			$post_types = array(
				tutor()->course_post_type,
				tutor()->lesson_post_type,
				tutor()->quiz_post_type,
				tutor()->assignment_post_type,
				tutor()->zoom_post_type,
				tutor()->meet_post_type,
			);

			if ( isset( $post->post_type ) && in_array( $post->post_type, $post_types, true ) ) {
				$to_add[] = 'tutor-frontend';
			}
		}

		if ( is_admin() ) {
			$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
			$base   = ( $screen && is_object( $screen ) && property_exists( $screen, 'base' ) ) ? $screen->base : '';
			$index  = strpos( $base, 'tutor' );

			if ( 0 === $index || $index > 0 ) {
				$to_add[] = 'tutor-backend';

				$page = Input::get( 'page' );
				if ( 'tutor_settings' === $page ) {
					$to_add[] = 'tutor-screen-backend-settings ';
				}
				if ( ! empty( $page ) ) {
					$to_add[] = 'tutor-backend-' . $page;
				}
			}
		}

		// Remove duplicate classes if any.
		$to_add = array_unique( $to_add );

		if ( is_array( $classes ) ) {
			$classes = array_merge( $classes, $to_add );
		} else {
			$classes .= implode( ' ', $to_add );
		}

		return $classes;
	}

	/**
	 * Enqueue script for adding edit with frontend course builder button
	 * on the Gutenberg editor
	 *
	 * @since 2.0.5
	 * @return void
	 */
	public static function add_frontend_editor_button() {
		$wp_screen = get_current_screen();

		if ( is_a( $wp_screen, 'WP_Screen' ) && tutor()->course_post_type === $wp_screen->post_type ) {
			wp_enqueue_script( 'tutor-gutenberg', tutor()->url . 'assets/js/tutor-gutenberg.js', array(), TUTOR_VERSION, true );
			$data = array(
				'frontend_dashboard_url' => esc_url( trailingslashit( tutor_utils()->tutor_dashboard_url( 'create-course' ) ) ) . '?course_id=' . get_the_ID(),
			);

			wp_add_inline_script(
				'tutor-gutenberg',
				'const tutorInlineData =' . json_encode( $data ),
				'before'
			);
		}
	}

	/**
	 * Enqueue styles & scripts for latest design system
	 *
	 * @since 4.0.0
	 *
	 * @return void
	 */
	public function enqueue_scripts() {
		if ( self::should_load_legacy_scripts() ) {
			return;
		}

		$is_dashboard       = tutor_utils()->is_dashboard_page();
		$is_learning_area   = tutor_utils()->is_learning_area();
		$is_kids_mode       = tutor_utils()->is_kids_mode();
		$is_legacy_learning = Options_V2::LEARNING_MODE_LEGACY === tutor_utils()->get_option( 'learning_mode' );

		$core_css_url          = tutor()->assets_url . 'css/tutor-core.min.css';
		$kids_css_url          = tutor()->assets_url . 'css/tutor-kids.min.css';
		$dashboard_css_url     = tutor()->assets_url . 'css/tutor-dashboard.min.css';
		$learning_area_css_url = tutor()->assets_url . 'css/tutor-learning-area.min.css';
		$google_font_url       = 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap';

		$core_js_url          = tutor()->assets_url . 'js/tutor-core.js';
		$dashboard_js_url     = tutor()->assets_url . 'js/tutor-dashboard.js';
		$learning_area_js_url = tutor()->assets_url . 'js/tutor-learning-area.js';

		$version = TUTOR_ENV === 'DEV' ? time() : TUTOR_VERSION;

		$is_course_list_page    = tutor_utils()->is_course_list_page();
		$is_course_details_page = tutor_utils()->is_course_details_page();

		$localize_data = apply_filters( 'tutor_localize_data', $this->get_default_localized_data() );
		if ( $is_kids_mode ) {
			$google_font_url = 'https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700&display=swap';
			wp_enqueue_style( 'tutor-kids', $kids_css_url, array( 'tutor-core' ), $version );
		}

		// Core.
		wp_enqueue_style( 'tutor-google-fonts', $google_font_url, array(), $version );

		wp_enqueue_style( 'tutor-core', $core_css_url, array( 'tutor-google-fonts' ), $version );
		wp_enqueue_script( 'tutor-core', $core_js_url, array( 'wp-i18n' ), $version, true );

		wp_localize_script( 'tutor-core', '_tutorobject', $localize_data );

		// Generate color palette from user selected brand color and add to the root.
		$brand_color = tutor_utils()->get_brand_color();
		if ( Options_V2::DEFAULT_BRAND_COLOR !== $brand_color ) {
			wp_add_inline_style( 'tutor-core', $this->load_core_color_palette( $brand_color ) );
		}

		if ( $is_dashboard ) {
			wp_enqueue_style( 'tutor-dashboard', $dashboard_css_url, array(), $version );
			wp_enqueue_script( 'tutor-dashboard', $dashboard_js_url, array( 'tutor-core', 'wp-i18n' ), $version, true );
		}

		if ( $is_learning_area ) {
			wp_enqueue_style( 'tutor-learning', $learning_area_css_url, array(), $version );
			wp_enqueue_script( 'tutor-learning', $learning_area_js_url, array( 'tutor-core', 'wp-i18n' ), $version, true );

			if ( is_single_course( true ) ) {
				wp_enqueue_style( 'tutor-plyr', tutor()->url . 'assets/lib/plyr/plyr.css', array(), $version );
				wp_enqueue_script( 'tutor-plyr', tutor()->url . 'assets/lib/plyr/plyr.polyfilled.min.js', array( 'jquery' ), $version, true );
			}
		}
	}

	/**
	 * Check if need to load legacy scripts
	 *
	 * If the current screen is dashboard or new learning area
	 * then this method will return false to avoid loading legacy css & js files
	 *
	 * @since 4.0.0
	 *
	 * @return boolean
	 */
	public static function should_load_legacy_scripts(): bool {
		$load = true;

		$post_id = get_the_ID();

		$is_learning_area   = tutor_utils()->is_learning_area();
		$is_legacy_learning = tutor_utils()->is_legacy_learning_mode();
		$is_dashboard       = tutor_utils()->is_dashboard_page();

		$page_ids = array(
			(int) tutor_utils()->get_option( 'student_register_page' ),
			(int) tutor_utils()->get_option( 'instructor_register_page' ),
		);

		// Ignore loading legacy scripts on specific case.
		if ( $is_learning_area && ! $is_legacy_learning ) {
			$load = false;
		} elseif ( $is_dashboard ) {
			$load = false;
		} elseif ( in_array( $post_id, $page_ids, true ) ) {
			$load = false;
		} else {
			// Ignore loading legacy scripts for these shortcodes.
			$has_shortcode = false;

			$shortcdes = array(
				'tutor_student_registration_form',
				'tutor_instructor_registration_form',
				'tutor_dashboard',
				'tutor_login',
			);

			$post_content = get_the_content();

			foreach ( $shortcdes as $shortcde ) {
				$has_shortcode = has_shortcode( $post_content, $shortcde );
				if ( $has_shortcode ) {
					$load = false;
					break;
				}
			}
		}

		return apply_filters( 'tutor_should_load_legacy_scripts', $load );
	}

	/**
	 * Add custom meta data to the head section.
	 *
	 * Outputs a viewport meta tag to improve mobile responsiveness.
	 *
	 * @since 4.0.0
	 *
	 * @return void
	 */
	public function add_custom_data() {
		if ( tutor_utils()->is_dashboard_page() || tutor_utils()->is_learning_area() ) {
			echo '<meta name="viewport" content="width=device-width, initial-scale=1" />' . "\n";
		}
	}

	/**
	 * Add preload to CSS
	 *
	 * @param string $html HTML.
	 * @param string $handle Handle.
	 *
	 * @since 4.0.0
	 *
	 * @return string
	 */
	public function add_preload_to_css( $html, $handle ) {
		if ( 'tutor-google-fonts' === $handle ) {
			$html = str_replace(
				"rel='stylesheet'",
				"rel='preload' as='style' onload=\"this.onload=null;this.rel='stylesheet'\"",
				$html
			);
		}
		return $html;
	}
}
