<?php
/**
 * The admin-specific functionality of the plugin.
 *
 * @link       https://personalizewp.com
 * @since      1.0.0
 *
 * @package    PersonalizeWP
 * @subpackage PersonalizeWP/Admin
 */

namespace PersonalizeWP\Admin;

use PersonalizeWP\PersonalizeWP;
use PersonalizeWP\Admin\PageSettings;
use PersonalizeWP\Admin\Onboarding_Wizard;
use PersonalizeWP\Admin\RuleFormExtension;
use PersonalizeWP\Traits\SingletonTrait;

defined( 'ABSPATH' ) || exit; // Exit if accessed directly.

/**
 * The admin-specific functionality of the plugin.
 *
 * @package    PersonalizeWP
 * @subpackage PersonalizeWP/Admin
 */
class Admin {

	use SingletonTrait;

	/**
	 * Holds Instance of plugin object
	 *
	 * @var PersonalizeWP
	 */
	private $plugin;

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string  $personalizewp The ID of this plugin.
	 */
	private $personalizewp;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string  $version The current version of this plugin.
	 */
	private $version;

	/**
	 * WP Admin url action parameter
	 *
	 * @var string
	 */
	const URL_ACTION = 'personalizewp_action';

	/**
	 * Capability needed to access
	 *
	 * @var string
	 */
	const CAP = 'manage_options';

	/**
	 * Stores each of the admin screens
	 *
	 * @since 2.0.0
	 *
	 * @var array
	 */
	public $screens = array();

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since 1.0.0
	 * @since 1.2.0 Switch to single plugin param
	 * @since 2.5.0 Removed param, use singletontrait
	 */
	protected function __construct() {
		$this->plugin        = \personalizewp();
		$this->personalizewp = $this->plugin->get_personalizewp();
		$this->version       = $this->plugin->get_version();
	}

	/**
	 * Execute admin hooks
	 *
	 * @since 1.2.0
	 *
	 * @return void
	 */
	public function setup() {

		$this->setup_ajax_hooks();

		// Initialize the rule form extension
		RuleFormExtension::init();

		// Check for an action only used within Pro, to trigger additional warnings.
		if ( has_action( 'activate_personalizewp-pro/personalizewp-pro.php' ) ) {
			$this->display_pro_warnings();
		}

		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_styles_scripts' ] );

		// This action fires on both the frontend and the admin.
		add_action( 'enqueue_block_assets', [ $this, 'enqueue_block_editor_content_styles' ] );

		// This action only adds styles to the actual admin, and non-iframed block editors.
		add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_styles_scripts' ] );

		add_action( 'admin_menu', [ $this, 'create_admin_menus' ] ); // Runs before 'admin_init'

		// add_action( 'admin_init', [ $this, 'setup_onboarding_wizard' ] );

		// Hide all unrelated to the plugin notices on the plugin admin pages.
		add_action( 'admin_print_scripts', [ $this, 'hide_unrelated_notices' ] );

		// Add additional query args to WP defaults that we use to display messaging.
		add_filter(
			'removable_query_args',
			function ( $args ) {
				$args[] = 'created';
				$args[] = 'duplicated';
				$args[] = 'duplicate_error';
				$args[] = 'delete_error';
				$args[] = 'export_email';
				$args[] = 'export_emailed';
				$args[] = 'export_email_error';
				$args[] = 'activated';
				$args[] = 'deactivated';
				$args[] = 'onboarding_complete';
				$args[] = 'removed_segment';
				return $args;
			}
		);

		add_action( 'admin_print_footer_scripts', [ '\PersonalizeWP\Admin\Utils', 'output_inline_svgs' ], 100 );
	}

	/**
	 * Setup all admin AJAX hook requests.
	 *
	 * @since 3.2.0
	 *
	 * @return void
	 */
	public function setup_ajax_hooks() {
		// Allow dismissing the first time (legacy onboarding) messaging on various screens.
		add_action( 'wp_ajax_pwp_dismiss_onboarding_message', [ $this, 'dismiss_onboarding_message' ] );

		add_action( 'wp_ajax_pwp_export_data', [ Data_Export::instance(), 'wp_ajax_process_export_data' ] );

		// Since PageSettings isn't loaded normally, use static functions to process.
		add_action( 'wp_ajax_pwp_newsletter_signup', [ '\PersonalizeWP\Admin\PageSettings', 'process_newsletter_signup' ] );
		add_action( 'wp_ajax_pwp_add_url_api_authentication', [ '\PersonalizeWP\Admin\PageSettings', 'process_add_url_token' ] );
		add_action( 'wp_ajax_pwp_revoke_url_api_authentication', [ '\PersonalizeWP\Admin\PageSettings', 'process_revoke_url_token' ] );
	}

	/**
	 * Checks for the activation of PersonalizeWP Pro, if so triggers additional actions.
	 *
	 * @since 3.2.0
	 *
	 * @return void
	 */
	public function display_pro_warnings() {

		// Display admin notice to deactivate Pro.
		add_action( 'admin_notices', [ $this, 'display_deactivate_pro_admin_warning' ] );

		// Add a warning notice against Pro listing on Plugins page.
		add_filter( 'after_plugin_row_meta', [ $this, 'display_deactivate_pro_plugin_listing' ], 10, 2 );
	}

	/**
	 * Display an admin notice that Pro can be de-activated and removed.
	 *
	 * @since 3.2.0
	 *
	 * @return void
	 */
	public function display_deactivate_pro_admin_warning() {

		$notice = wp_get_admin_notice(
			wp_kses(
				sprintf(
					/* translators: 1: %s expands to a link to the Plugins admin screen, 2: </a> closing tag. */
					esc_html__( 'Please %1$sdeactivate PersonalizeWP Pro%2$s. All features and functionality are now in the main PersonalizeWP plugin, and some functionality cannot work whilst Pro is active.', 'personalizewp' ),
					'<a href="' . esc_url( admin_url( 'plugins.php' ) ) . '">',
					'</a>',
				),
				array(
					'a' => array(
						'href' => array(),
					),
				)
			),
			array(
				'type'               => 'warning',
				'additional_classes' => array( 'notice' ),
			)
		);

		echo $notice; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped within wp_get_admin_notice
	}

	/**
	 * Display a notice against the listing of the Pro plugin that it can be de-activated and removed.
	 *
	 * @since 3.2
	 *
	 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
	 * @param array  $plugin_data An array of plugin data. See get_plugin_data()
	 *
	 * @return void
	 */
	public function display_deactivate_pro_plugin_listing( $plugin_file, $plugin_data ) {

		if ( 'personalizewp-pro/personalizewp-pro.php' !== $plugin_file ) {
			return;
		}

		$notice = wp_get_admin_notice(
			esc_html__( 'Pro is no longer required for PersonalizeWP. All features and functionality are now in the main plugin. PersonalizeWP Pro can be safely deactivated and deleted.', 'personalizewp' ),
			array(
				'type'               => 'warning',
				'additional_classes' => array( 'notice', 'inline', 'notice-alt' ),
			)
		);
		printf(
			'<div class="requires">%1$s</div>',
			$notice // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped within wp_get_admin_notice
		);
	}

	/**
	 * Register the stylesheets and JS for the admin area.
	 *
	 * @since 3.2.0 - Combined previously separate functions
	 */
	public function enqueue_styles_scripts() {

		if ( $this->is_admin_page() ) {
			$suffix  = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
			$version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->version;

			wp_enqueue_style(
				$this->personalizewp . '_jquery_ui',
				plugin_dir_url( __FILE__ ) . 'libs/css/jquery-ui.css',
				array(),
				'1.5'
			); // For datepicker etc

			wp_enqueue_style(
				$this->personalizewp,
				plugin_dir_url( __FILE__ ) . "css/admin{$suffix}.css",
				array(),
				$version
			);

			// Ensures focused CSS styles with namespacing.
			add_filter( 'admin_body_class', [ $this, 'admin_body_class' ] );

			/**
			 * Enqueue Admin Scripts
			 */

			wp_enqueue_script( 'jquery-ui-datepicker' );

			$properties = require plugin_dir_path( __FILE__ ) . 'js/admin.asset.php';
			$js_version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? $properties['version'] : $this->version;
			wp_enqueue_script(
				$this->personalizewp,
				plugin_dir_url( __FILE__ ) . 'js/admin.js',
				$properties['dependencies'],
				$js_version,
				[ 'strategy' => 'defer' ]
			);

			// Various AJAX callbacks etc
			wp_add_inline_script(
				$this->personalizewp,
				'window.pwpSettings = ' . wp_json_encode(
					array(
						'kb'        => 'https://help.personalizewp.com',
						'url'       => admin_url( 'admin-ajax.php' ),
						'nonce'     => wp_create_nonce( 'pwp-ajax-nonce' ),
						'restUrl'   => esc_url_raw( rest_url() ),
						'restNonce' => wp_create_nonce( 'wp_rest' ),
					)
				) . ';',
				'before'
			);

		} else {
			// Fake register to allow variable below.
			wp_register_script( $this->personalizewp, false, [], $this->version, true );
			wp_enqueue_script( $this->personalizewp );
			// Inline script directly embeds the KB URL rather than have to use a global setting and then double check.
			wp_add_inline_script(
				$this->personalizewp,
				'
					( function() {
						document.querySelector(`ul#adminmenu a[href=\'https://help.personalizewp.com\']`)?.setAttribute("target", "_blank");
					}() );
				',
			);
		}
	}

	/**
	 * Add a PWP class to body element of wp-admin.
	 *
	 * @since 1.0.0
	 *
	 * @param string $classes CSS classes for the body tag in the admin, a space separated string.
	 *
	 * @return string
	 */
	public function admin_body_class( $classes ) {
		$classes .= ' pwp-page';
		return $classes;
	}

	/**
	 * Enqueue block editor content styles.
	 *
	 * @uses 'enqueue_block_assets' action
	 * @see https://developer.wordpress.org/block-editor/how-to-guides/enqueueing-assets-in-the-editor/
	 *
	 * @since 3.2.3
	 */
	public function enqueue_block_editor_content_styles() {

		// Even though the action fires on the frontend, restrict to admin only.
		if ( ! is_admin() ) {
			return;
		}

		$suffix  = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
		$version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->version;

		wp_enqueue_style(
			$this->personalizewp . '-editor-content-styles',
			plugin_dir_url( __FILE__ ) . "css/editor-content{$suffix}.css",
			array(),
			$version
		);
	}

	/**
	 * Enqueue block editor styles and scripts.
	 *
	 * @uses 'enqueue_block_editor_assets' action
	 *
	 * @since 3.2.0 - Combined previously separate functions
	 */
	public function enqueue_block_editor_styles_scripts() {

		$suffix  = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
		$version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->version;

		wp_enqueue_style(
			$this->personalizewp . '-editor-styles',
			plugin_dir_url( __FILE__ ) . "css/editor{$suffix}.css",
			array(),
			$version
		);

		/**
		 * Personalisation not currently supported within legacy widgets.
		 *
		 * @since 2.6.0 Expanded to include Site Editor
		 * @since 2.0.0
		 */
		if ( wp_script_is( 'wp-edit-widgets' ) ) {
			return;
		}

		$properties = require $this->plugin->plugin_path( 'admin/js/block-editor.asset.php' );
		$js_version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? $properties['version'] : $this->version;
		wp_enqueue_script(
			$this->personalizewp . '-block-editor',
			$this->plugin->plugin_url( 'admin/js/block-editor.js' ),
			$properties['dependencies'],
			$js_version,
			false
		);
		// Add translations for the PWP block in the editor.
		wp_set_script_translations( $this->personalizewp . '-block-editor', 'personalizewp', plugin_dir_path( __FILE__ ) . '../languages' );
	}

	/**
	 * Return a base64 encoded SVG of the PersonalizeWP menu logo.
	 * Can be used as a data URI to use the logo inline in CSS.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public function get_base64_menu_logo() {
		$base_logo = file_get_contents( __DIR__ . '/img/menu_icon_personalize.svg' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- File is local, not remote

		$encoded_logo = base64_encode( $base_logo ); // phpcs:ignore Generic.PHP.ForbiddenFunctions.Found,WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- The encoded version is used as data URI to use the logo in CSS.

		return 'data:image/svg+xml;base64,' . $encoded_logo;
	}

	/**
	 * Process all admin routing, ensuring correct class is used.
	 *
	 * @since 3.2.0
	 *
	 * @return void
	 */
	public function route_admin_page() {
		// Check for user caps before any possible processing of data.
		if ( ! current_user_can( self::CAP ) ) {
			return;
		}

		$page = ! empty( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: Form verified within each process

		if ( empty( $page ) ) {
			return;
		}

		foreach ( $this->screens as $slug => $admin_page ) {
			if ( $slug === $page && method_exists( $admin_page, 'route' ) ) {
				// TBC Load class only at this point?
				$admin_page->route();
				return;
			}
		}
	}

	/**
	 * Create menu items for PersonalizeWP
	 *
	 * @uses `admin_menu`
	 *
	 * @return void
	 */
	public function create_admin_menus() {
		$parent_slug = PageDashboard::SLUG;

		// Setup all screens
		$this->screens = array(
			PageDashboard::SLUG    => PageDashboard::instance(),
			PageRules::SLUG        => PageRules::instance(),
			PageCategories::SLUG   => PageCategories::instance(),
			PageActivities::SLUG   => PageActivities::instance(),
			PageContacts::SLUG     => PageContacts::instance(),
			PageDataExport::SLUG   => PageDataExport::instance(),
			PageSegments::SLUG     => PageSegments::instance(),
			PageScoringRules::SLUG => PageScoringRules::instance(),
			PageSettings::SLUG     => PageSettings::instance(),
		);

		$hook_suffix = add_menu_page(
			esc_html_x( 'Personalize', 'plugin name', 'personalizewp' ),
			esc_html_x( 'Personalize', 'plugin name', 'personalizewp' ),
			self::CAP,
			$parent_slug,
			[ $this, 'route_admin_page' ],
			$this->get_base64_menu_logo(),
			21
		);

		$dashboard = add_submenu_page(
			$parent_slug,
			esc_html__( 'Dashboard', 'personalizewp' ),
			esc_html__( 'Dashboard', 'personalizewp' ),
			self::CAP,
			$parent_slug,
			[ $this, 'route_admin_page' ]
		);

		/**
		 * Fires immediately after the main Personalize menu and it's dashboard sub-menu, and before any other sub-menus.
		 *
		 * @since 1.0.0
		 *
		 * @param string $parent_slug Slug of the main Personalize menu item
		 */
		do_action( 'personalizewp_menus_before', $parent_slug );

		$rules = add_submenu_page(
			$parent_slug,
			esc_html__( 'Rules', 'personalizewp' ),
			esc_html__( 'Rules', 'personalizewp' ),
			self::CAP,
			PageRules::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$rules", [ $this->screens[ PageRules::SLUG ], 'dashboard_screen_options' ] );

		// Not directly shown in the main admin menu, but required for permission checks
		$rule_categories = add_submenu_page(
			PageRules::SLUG, // Use a different parent slug so it's not visible
			esc_html__( 'Categories', 'personalizewp' ),
			esc_html__( 'Categories', 'personalizewp' ),
			self::CAP,
			PageCategories::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$rule_categories", [ $this->screens[ PageCategories::SLUG ], 'dashboard_screen_options' ] );

		$segments = add_submenu_page(
			$parent_slug,
			esc_html__( 'Segments', 'personalizewp' ),
			esc_html__( 'Segments', 'personalizewp' ),
			self::CAP,
			PageSegments::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$segments", [ $this->screens[ PageSegments::SLUG ], 'dashboard_screen_options' ] );

		$lead_scoring = add_submenu_page(
			$parent_slug,
			esc_html__( 'Lead Scoring', 'personalizewp' ),
			esc_html__( 'Lead Scoring', 'personalizewp' ),
			self::CAP,
			PageScoringRules::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$lead_scoring", [ $this->screens[ PageScoringRules::SLUG ], 'dashboard_screen_options' ] );

		$activities = add_submenu_page(
			$parent_slug,
			esc_html__( 'Visitor Profiles', 'personalizewp' ),
			esc_html__( 'Visitor Profiles', 'personalizewp' ),
			self::CAP,
			PageActivities::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$activities", [ $this->screens[ PageActivities::SLUG ], 'dashboard_screen_options' ] );

		// Register PageContacts as hidden submenu
		$contacts = add_submenu_page(
			PageActivities::SLUG, // Use PageActivities as parent so it doesn't appear in main menu
			esc_html__( 'Visitor Profiles', 'personalizewp' ),
			esc_html__( 'Visitor Profiles', 'personalizewp' ),
			self::CAP,
			PageContacts::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$contacts", [ $this->screens[ PageContacts::SLUG ], 'dashboard_screen_options' ] );

		// Register PageDataExport as hidden submenu
		$data_export = add_submenu_page(
			PageActivities::SLUG, // Use PageActivities as parent so it doesn't appear in main menu
			esc_html__( 'Data Export', 'personalizewp' ),
			esc_html__( 'Data Export', 'personalizewp' ),
			self::CAP,
			PageDataExport::SLUG,
			[ $this, 'route_admin_page' ]
		);
		add_action( "load-$data_export", [ $this->screens[ PageDataExport::SLUG ], 'dashboard_screen_options' ] );

		/**
		 * Fires after most Personalize sub-menus are added to the menu bar, but before Settings and KB.
		 *
		 * @since 2.8.0
		 *
		 * @param string $parent_slug Slug of the main Personalize menu item
		 */
		do_action( 'personalizewp_menus_before_settings', $parent_slug );

		$settings = add_submenu_page(
			$parent_slug,
			esc_html__( 'Settings', 'personalizewp' ),
			esc_html__( 'Settings', 'personalizewp' ),
			self::CAP,
			PageSettings::SLUG,
			[ $this, 'route_admin_page' ]
		);

		add_submenu_page(
			$parent_slug,
			esc_html__( 'Custom Profile Fields', 'personalizewp' ),
			esc_html(
				sprintf(
					/* translators: 1: %s menu indent prefix. */
					__( '%sProfile Fields', 'personalizewp' ),
					'&nbsp;&ndash; '
				)
			),
			self::CAP,
			sprintf( '%s#pwp-profile', PageSettings::SLUG ),
			$settings
		);

		add_submenu_page(
			$parent_slug,
			esc_html__( 'Privacy & Data', 'personalizewp' ),
			esc_html(
				sprintf(
					/* translators: 1: %s menu indent prefix. */
					__( '%sPrivacy & Data', 'personalizewp' ),
					'&nbsp;&ndash; '
				)
			),
			self::CAP,
			sprintf( '%s#pwp-privacy', PageSettings::SLUG ),
			$settings
		);

		/**
		 * Fires after Settings sub-menu has been added to the menu bar, but before KB.
		 *
		 * @since 2.8.0
		 *
		 * @param string $parent_slug Slug of the main Personalize menu item
		 */
		do_action( 'personalizewp_menus_after_settings', $parent_slug );

		// Directly add KB item to menu.
		$icon = ' <span class="dashicons dashicons-external" style="transform:translateY(-2px)"></span>'; // Previously was ' <span class="bi bi-box-arrow-up-right"></span>',
		add_submenu_page(
			$parent_slug,
			'<span style="white-space:nowrap">' . esc_html__( 'Knowledge Base', 'personalizewp' ) . $icon . '</span>',
			'<span style="white-space:nowrap">' . esc_html__( 'Knowledge Base', 'personalizewp' ) . $icon . '</span>',
			'edit_pages',
			'https://help.personalizewp.com/'
		);
	}

	/**
	 * Setup the onboarding wizard
	 *
	 * @since 2.0.0
	 *
	 * @return void
	 */
	public function setup_onboarding_wizard() {

		if ( ! $this->should_enqueue_onboarding_wizard() || ! current_user_can( self::CAP ) ) {
			return;
		}

		$onboarding = new Onboarding_Wizard();
		$onboarding->setup();
	}

	/**
	 * Should the onboarding wizard be queued up to show.
	 *
	 * @since 2.0.0
	 *
	 * @return bool
	 */
	public function should_enqueue_onboarding_wizard() {

		if ( ! $this->is_admin_page() &&
			! wp_doing_ajax() &&
			// Check for completion action
			( empty( $_REQUEST['action'] ) || 'pwp_onboarding_complete' !== sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) )
		) {
			return false;
		}

		if ( defined( 'PWP_DISPLAY_ONBOARDING_WIZARD' ) && PWP_DISPLAY_ONBOARDING_WIZARD ) {
			return true;
		}

		return (bool) get_option( 'pwp_pending_onboarding' );
	}

	/**
	 * Remove all non-PersonalizeWP plugin notices from our plugin pages.
	 *
	 * @since 2.0.0
	 *
	 * @return void
	 */
	public function hide_unrelated_notices() {

		// Bail if we're not on our screen or page.
		if ( ! $this->is_admin_page() ) {
			return;
		}

		$this->remove_unrelated_actions( 'user_admin_notices' );
		$this->remove_unrelated_actions( 'admin_notices' );
		$this->remove_unrelated_actions( 'all_admin_notices' );
		$this->remove_unrelated_actions( 'network_admin_notices' );
	}

	/**
	 * Remove all non-PersonalizeWP notices from the our plugin pages based on the provided action hook.
	 *
	 * @since 2.0.0
	 *
	 * @param string $action The name of the action.
	 *
	 * @return void
	 */
	private function remove_unrelated_actions( $action ) {
		global $wp_filter;

		if ( empty( $wp_filter[ $action ]->callbacks ) || ! is_array( $wp_filter[ $action ]->callbacks ) ) {
			return;
		}

		foreach ( $wp_filter[ $action ]->callbacks as $priority => $hooks ) {
			foreach ( $hooks as $name => $arr ) {
				if (
					( // Cover object method callback case.
						is_array( $arr['function'] ) &&
						is_object( $arr['function'][0] ) &&
						str_starts_with( strtolower( get_class( $arr['function'][0] ) ), 'personalizewp' )
					) ||
					( // Cover class static method callback case.
						! empty( $name ) &&
						str_starts_with( strtolower( $name ), 'personalizewp' )
					)
				) {
					continue;
				}

				unset( $wp_filter[ $action ]->callbacks[ $priority ][ $name ] );
			}
		}
	}

	/**
	 * Is the current page an admin page of PersonalizeWP?
	 *
	 * @since 2.7.0 Changed function visibility
	 *
	 * @return boolean
	 */
	public function is_admin_page() {
		if ( ! is_admin() ) {
			return false;
		}

		$page = ! empty( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.

		if ( empty( $page ) ) {
			return false;
		}

		/**
		 * Allows filtering the known screens/pages that are regarded as Personalize screens.
		 *
		 * @since 1.0.0
		 *
		 * @param array $pages Personalize page slugs to validate against.
		 */
		$pages = apply_filters( 'personalizewp_is_pwp_page', array_keys( $this->screens ) );
		// Sanitise the filtered pages.
		$pages = array_filter( array_unique( $pages ) );

		return in_array( $page, $pages, true );
	}

	/**
	 * Detects if current screen is post edit
	 *
	 * @return boolean
	 */
	protected function is_block_editing_page() {
		$screen = get_current_screen();

		if ( is_admin() && $screen->is_block_editor ) {
			return true;
		}

		return false;
	}

	/**
	 * Dismisses Onboarding for all users.
	 *
	 * @since 2.0.0
	 *
	 * @return void
	 */
	public function dismiss_onboarding_message() {
		check_ajax_referer( 'pwp-ajax-nonce' );

		update_option( 'pwp_admin_onboarding_dismissed', '1', true );
		wp_send_json_success( null, 200 );
		exit;
	}
}
