<?php
/**
 * Admin hooks class.
 *
 * @package SaveToWishlist\Classes\Admin
 * @since 1.0.0
 */
namespace SaveToWishlist\Classes\Admin;

use SaveToWishlist\Abstracts\Singleton;
use SaveToWishlist\Helpers\Vite_App;
use SaveToWishlist\Classes\Translations;
use SaveToWishlist\Classes\Admin\Render_Settings;
use SaveToWishlist\Classes\Admin\Render_Wishlists;
use SaveToWishlist\Classes\Admin\Render_Installer;
use SaveToWishlist\Helpers\Helper_Functions;

// Integrations Classes.
use SaveToWishlist\Classes\Integrations\Pro_Dependencies;

// Importer Factory.
use SaveToWishlist\Classes\Importers\Importer_Factory;

/**
 * Class Admin_Hooks
 *
 * This class serves as the main plugin class.
 */
class Admin_Hooks extends Singleton {

    /**
     * Settings.
     *
     * @var Render_Settings
     */
    private $render_settings;

    /**
     * Wishlists.
     *
     * @var Render_Wishlists
     */
    private $render_wishlists;

    /**
     * Installer.
     *
     * @var Render_Installer
     */
    private $render_installer;

    /**
     * Helper functions.
     *
     * @var Helper_Functions
     */
    private $helper_functions;

    /**
     * Run the controller.
     *
     * @since 1.0.0
     * @access public
     */
    public function run() {
        // Initialize the class.
        $this->render_settings  = Render_Settings::instance();
        $this->render_wishlists = Render_Wishlists::instance();
        $this->render_installer = Render_Installer::instance();
        $this->helper_functions = Helper_Functions::instance();

        // Add admin hooks.
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts_and_styles' ), 10, 1 );

        // Add admin body class.
        add_filter( 'admin_body_class', array( $this, 'add_admin_body_class' ), 10, 1 );

        // Add settings link to plugins page.
        add_filter( 'plugin_action_links_' . STWLITE_BASENAME, array( $this, 'add_settings_link' ), 10, 1 );

        // Triggers.
        add_action( 'stwlite_trigger_install_plugin', array( $this->render_installer, 'install_activate_plugin' ), 10, 1 );

        // Add admin app after.
        add_filter( 'stwlite_admin_app_after', array( $this, 'admin_app_after' ), 10 );

        // Remove notice if inside the admin panel under wishlists pages.
        add_action( 'in_admin_header', array( $this, 'remove_notice' ), 10 );

        // Flush rewrite rules when wishlist page option is added or updated.
        add_action( 'update_option_stwlite_wishlist_page', array( $this, 'flag_rewrite_flush' ), 10, 2 );
        add_action( 'add_option_stwlite_wishlist_page', array( $this, 'flag_rewrite_flush_on_add' ), 10 );
        add_action( 'init', array( $this, 'maybe_flush_rewrite_rules' ), 999 );

        // Dismiss review request.
        add_action( 'wp_ajax_stwlite_dismiss_review_request', array( $this, 'dismiss_review_request' ) );

        // Dismiss importer notice (per-user).
        add_action( 'wp_ajax_stwlite_dismiss_importer_notice', array( $this, 'dismiss_importer_notice' ) );

        // Show review request admin notice.
        add_action( 'admin_notices', array( $this, 'show_review_request_notice' ), 999 );

        // Show importer-available admin notice on SaveTo Wishlist pages.
        add_action( 'admin_notices', array( $this, 'show_importer_notice' ), 999 );

        // Flush cached importer detection when any plugin is toggled so the
        // Imports tab and its notice reflect the new state on the next request.
        add_action( 'activated_plugin', array( $this, 'flush_importer_detection_cache' ), 10, 0 );
        add_action( 'deactivated_plugin', array( $this, 'flush_importer_detection_cache' ), 10, 0 );
    }

    /**
     * Flush the cached importer-detection list.
     *
     * Bound to `activated_plugin` / `deactivated_plugin` so the Imports tab
     * (registered in {@see Tabs}) and the importer admin notice stay in sync
     * with the active source plugins without waiting for the transient TTL.
     *
     * @since 1.0.6
     * @access public
     * @return void
     */
    public function flush_importer_detection_cache() {
        Importer_Factory::flush_detected_cache();
    }

    /**
     * Add admin menu.
     *
     * @since 1.0.0
     * @access public
     */
    public function add_admin_menu() {
        $menu_title = __( 'SaveTo Wishlist', 'saveto-wishlist-lite-for-woocommerce' );

        if ( $this->should_show_review_request() ) {
            $menu_title .= ' <span class="update-plugins count-1"><span class="plugin-count">1</span></span>';
        }

        $capability = 'manage_options';
        $menu_slug  = 'save-to-wishlist';
        $function   = array( $this->render_wishlists, 'render_admin_app_wishlists' );
        $stw_icon   = STWLITE_IMG_URL . 'savetowishlist-sm-logo.svg';

        add_menu_page(
            $menu_title,
            $menu_title,
            $capability,
            $menu_slug,
            $function,
            $stw_icon,
            56
        );

        add_submenu_page(
            $menu_slug,
            __( 'All Wishlists', 'saveto-wishlist-lite-for-woocommerce' ),
            __( 'All Wishlists', 'saveto-wishlist-lite-for-woocommerce' ),
            $capability,
            $menu_slug,
            $function
        );

        add_submenu_page(
            $menu_slug,
            __( 'Add New', 'saveto-wishlist-lite-for-woocommerce' ),
            __( 'Add New', 'saveto-wishlist-lite-for-woocommerce' ),
            $capability,
            'save-to-wishlist&add=new',
            $function
        );

        if ( ! $this->helper_functions->is_pro_installed() ) {
            add_submenu_page(
                $menu_slug,
                __( 'Analytics', 'saveto-wishlist-lite-for-woocommerce' ),
                __( 'Analytics', 'saveto-wishlist-lite-for-woocommerce' ),
                $capability,
                'save-to-wishlist-analytics',
                array( $this, 'render_admin_app_pages' )
            );

            add_submenu_page(
                $menu_slug,
                __( 'Automations', 'saveto-wishlist-lite-for-woocommerce' ),
                __( 'Automations', 'saveto-wishlist-lite-for-woocommerce' ),
                $capability,
                'save-to-wishlist-automations',
                array( $this, 'render_admin_app_pages' )
            );
        }

        add_submenu_page(
            $menu_slug,
            __( 'Settings', 'saveto-wishlist-lite-for-woocommerce' ),
            __( 'Settings', 'saveto-wishlist-lite-for-woocommerce' ),
            $capability,
            'save-to-wishlist-settings',
            array( $this->render_settings, 'render_admin_app_settings' )
        );

        add_submenu_page(
            $menu_slug,
            __( 'About', 'saveto-wishlist-lite-for-woocommerce' ),
            __( 'About', 'saveto-wishlist-lite-for-woocommerce' ),
            $capability,
            'save-to-wishlist-about',
            array( $this, 'render_admin_app_pages' )
        );

        add_submenu_page(
            $menu_slug,
            __( 'Help', 'saveto-wishlist-lite-for-woocommerce' ),
            __( 'Help', 'saveto-wishlist-lite-for-woocommerce' ),
            $capability,
            'save-to-wishlist-help',
            array( $this, 'render_admin_app_pages' )
        );

        do_action( 'stwlite_admin_menu' );

        // Register new Upgrade to Pro menu.
        $this->register_upgrade_to_pro_page_menu();
    }

    /**
     * Register new Upgrade to Pro menu
     *
     * @since 1.0.3
     * @access public
     */
    public function register_upgrade_to_pro_page_menu() {
        global $submenu;

        if ( ! $this->helper_functions->is_pro_installed() ) {

            add_submenu_page(
                'save-to-wishlist',
                __( 'Upgrade To Pro', 'saveto-wishlist-lite-for-woocommerce' ),
                __( 'Upgrade To Pro', 'saveto-wishlist-lite-for-woocommerce' ),
                'manage_options',
                'save-to-wishlist-pro',
                '',
                99
            );

            if ( isset( $submenu['save-to-wishlist'] ) ) {
                foreach ( $submenu['save-to-wishlist'] as $key => $menu ) {
                    if ( in_array( 'Upgrade To Pro', $menu, true ) ) {
                        // phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited
                        $submenu['save-to-wishlist'][ $key ][2] = esc_url( Helper_Functions::get_utm_url( 'pricing', 'stwlite', 'admin_menu', 'upgrade_to_pro' ) );
                        $submenu['save-to-wishlist'][ $key ][4] = 'stwlite-upgrade-to-pro stwlite-upgrade-link';
                        // phpcs:enable WordPress.WP.GlobalVariablesOverride.Prohibited
                    }
                }
            }
        }
    }

    /**
     * Render the admin app for the pages.
     *
     * @since 1.0.0
     * @access public
     */
    public function render_admin_app_pages() {
        echo '<div class="wrap"><div id="saveto-wishlist-admin-app-pages"></div></div>';
        echo wp_kses_post( apply_filters( 'stwlite_admin_app_after', '' ) );
    }

    /**
     * Admin app after.
     *
     * @since 1.0.0
     * @access public
     *
     * @return string
     */
    public function admin_app_after() {
        ob_start();
        require_once STWLITE_TEMPLATES_DIR . 'admin/request-feature.php';

        // Add Pro Features Banner container for all admin pages (only if Pro is not installed).
        // Display the banner only on the wishlist page.
        $current_page     = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $is_wishlist_page = ( 'save-to-wishlist' === $current_page );

        if ( ! $this->helper_functions->is_pro_installed() && $is_wishlist_page ) {
            echo '<div id="saveto-wishlist-pro-features-banner" class="stwlite-tw-bg-gray-50"></div>';
        }

        return ob_get_clean();
    }

    /**
     * Admin scripts and styles.
     *
     * @param string $hook_queue The hook queue.
     *
     * @since 1.0.0
     * @since 1.0.3 Added review request script and styles.
     * @access public
     */
    public function admin_scripts_and_styles( $hook_queue = '' ) {
        // Register brand colors CSS first to ensure color variables are available
        // for all other stylesheets that depend on them.
        wp_enqueue_style( 'stwlite_brand_css', STWLITE_CSS_URL . 'savetowishlist-brand-colors.css', array(), STWLITE_VERSION, 'all' );

        // Register styles.
        wp_enqueue_style( 'stwlite_admin_css', STWLITE_CSS_URL . 'savetowishlist-backend-styles.css', array( 'stwlite_brand_css' ), STWLITE_VERSION, 'all' );

        if ( $this->should_show_review_request() ) {
            // Enqueue review prompt script for admin notices.
            wp_enqueue_script(
                'stwlite_backend_review_prompt_js',
                STWLITE_JS_URL . 'savetowishlist-backend-review-prompt.js',
                array( 'jquery' ),
                STWLITE_VERSION,
                true
            );

            // Localize script with nonce for review request dismissal.
            wp_localize_script(
                'stwlite_backend_review_prompt_js',
                'stwliteReviewPrompt',
                array(
                    'nonce' => wp_create_nonce( 'stwlite_dismiss_review_request' ),
                )
            );
        }

        if ( false !== strpos( $hook_queue, 'save-to-wishlist' ) ) {
            wp_enqueue_style( 'stwlite_admin_page_css', STWLITE_CSS_URL . 'savetowishlist-backend-pages-styles.css', array(), STWLITE_VERSION, 'all' );

            // Enqueue Pro Features Banner on all SaveTo Wishlist admin pages (only if Pro is not installed).
            // Display the banner only on the wishlist page.
            if ( ! $this->helper_functions->is_pro_installed() && false !== strpos( $hook_queue, 'page_save-to-wishlist' ) ) {
                $translations = Translations::instance()->pro_translations();

                $banner_object = array(
                    'i18n'           => $translations,
                    'stwInstalledBy' => get_option( 'stwlite_installed_by', false ),
                );

                $banner_app = new Vite_App(
                    'saveto-wishlist-pro-features-banner-scripts',
                    'src/apps/admin-banner/index.ts',
                    array(
                        'wp-i18n',
                        'wp-url',
                        'wp-hooks',
                        'wp-html-entities',
                        'lodash',
                        'jquery',
                    ),
                    array(),
                    $banner_object
                );

                $banner_app->enqueue();
            }
        }

        $include_editor = false;

        // STW Pro License Status.
        $stwpro_status = apply_filters(
            'stwlite_stwpro_license_status',
            array(
                'success'    => false,
                'check_type' => '',
            )
        );

        // Wishlists.
        if ( false !== strpos( $hook_queue, 'page_save-to-wishlist' ) ) {
            $translations = Translations::instance()->admin_translations();

            $admin_base_url_args = array( 'page' => 'save-to-wishlist' );
            if ( defined( 'HMR_DEV' ) && HMR_DEV ) {
                $admin_base_url_args['hmr'] = 'stwl';
            }

            $wishlists_object = array(
                'i18n'            => $translations,
                'stwproStatus'    => $stwpro_status,
                'isProInstalled'  => $this->helper_functions->is_pro_installed(),
                'details'         => $this->details(),
                'wpNonce'         => wp_create_nonce( 'wp_rest' ),
                'restApiUrl'      => $this->render_wishlists->rest_api_url,
                'productsApiUrl'  => $this->render_wishlists->products_api_url,
                'usersApiUrl'     => $this->render_wishlists->users_api_url,
                'pluginDirUrl'    => STWLITE_PLUGIN_URL,
                'wishlistUrl'     => get_permalink( get_option( 'stwlite_wishlist_page' ) ),
                'adminBaseUrl'    => esc_url_raw(
                    add_query_arg( $admin_base_url_args, admin_url( 'admin.php', 'relative' ) )
                ),
                'wcCurrency'      => $this->helper_functions->get_wc_currency(),
                'proDependencies' => Pro_Dependencies::instance()->get_pro_dependencies(),
            );

            $wishlists_app = new Vite_App(
                'saveto-wishlist-wishlists-app-scripts',
                'src/apps/wishlist/index.ts',
                array(
                    'wp-i18n',
                    'wp-url',
                    'wp-hooks',
                    'wp-html-entities',
                    'lodash',
                    'jquery',
                ),
                array(),
                $wishlists_object
            );

            $wishlists_app->enqueue();
        }

        // Pages.
        $pages_hooks       = array(
            'page_save-to-wishlist-about',
            'page_save-to-wishlist-help',
            'page_save-to-wishlist-analytics',
            'page_save-to-wishlist-automations',
        );
        $should_load_pages = false;
        foreach ( $pages_hooks as $hook ) {
            if ( false !== strpos( $hook_queue, $hook ) ) {
                $should_load_pages = true;
                break;
            }
        }
        if ( $should_load_pages ) {
            $translations    = array();
            $plugin_statuses = array();
            $plugin_logos    = array();
            if ( false !== strpos( $hook_queue, 'page_save-to-wishlist-help' ) ) {
                $translations = Translations::instance()->help_translations();
            } elseif ( false !== strpos( $hook_queue, 'page_save-to-wishlist-about' ) ) {
                $translations    = Translations::instance()->about_translations();
                $plugin_logos    = array(
                    'acfwf'          => $this->helper_functions->get_wp_org_plugin_icon_url( 'advanced-coupons-for-woocommerce-free' ),
                    'wwp'            => $this->helper_functions->get_wp_org_plugin_icon_url( 'woocommerce-wholesale-prices' ),
                    'storeagent'     => $this->helper_functions->get_wp_org_plugin_icon_url( 'storeagent-ai-for-woocommerce' ),
                    'adtribes'       => $this->helper_functions->get_wp_org_plugin_icon_url( 'woo-product-feed-pro' ),
                    'wcvendors'      => $this->helper_functions->get_wp_org_plugin_icon_url( 'wc-vendors' ),
                    'invoiceGateway' => $this->helper_functions->get_wp_org_plugin_icon_url( 'invoice-gateway-for-woocommerce' ),
                    'storeToolkit'   => $this->helper_functions->get_wp_org_plugin_icon_url( 'woocommerce-store-toolkit' ),
                    'storeExporter'  => $this->helper_functions->get_wp_org_plugin_icon_url( 'woocommerce-exporter' ),
                );
                $plugin_statuses = array(
                    'acfwf'          => $this->helper_functions->is_acfwf_installed(),
                    'wwp'            => $this->helper_functions->is_wwp_installed(),
                    'storeagent'     => $this->helper_functions->is_storeagent_installed(),
                    'adtribes'       => $this->helper_functions->is_adtribes_installed(),
                    'wcvendors'      => $this->helper_functions->is_wcvendors_installed(),
                    'invoiceGateway' => $this->helper_functions->is_invoice_gateway_installed(),
                    'storeToolkit'   => $this->helper_functions->is_store_toolkit_installed(),
                    'storeExporter'  => $this->helper_functions->is_store_exporter_installed(),
                );
            }

            // Get WooCommerce placeholder image URL.
            $wc_placeholder_img = '';
            if ( function_exists( 'wc_placeholder_img_src' ) ) {
                $wc_placeholder_img = wc_placeholder_img_src();
                if ( false === $wc_placeholder_img ) {
                    $wc_placeholder_img = '';
                }
            }

            $pages_object = array(
                'i18n'             => $translations,
                'stwproStatus'     => $stwpro_status,
                'isProInstalled'   => $this->helper_functions->is_pro_installed(),
                'details'          => $this->details(),
                'pluginDirUrl'     => STWLITE_PLUGIN_URL,
                'pluginLogos'      => $plugin_logos,
                'pluginStatuses'   => $plugin_statuses,
                'stwInstalledBy'   => get_option( 'stwlite_installed_by', false ),
                'wpNonce'          => wp_create_nonce( 'wp_rest' ),
                'rest_action_url'  => $this->render_settings->rest_action_url,
                'wcPlaceholderImg' => $wc_placeholder_img,
            );

            $pages_app = new Vite_App(
                'saveto-wishlist-pages-app-scripts',
                'src/apps/pages/index.ts',
                array(
                    'wp-i18n',
                    'wp-url',
                    'wp-hooks',
                    'wp-html-entities',
                    'lodash',
                    'jquery',
                ),
                array(),
                $pages_object
            );

            $pages_app->enqueue();
        }

        // Settings.
        if ( false !== strpos( $hook_queue, 'page_save-to-wishlist-settings' ) ) {
            $translations = Translations::instance()->admin_translations();

            $settings_object = array(
                'i18n'              => $translations,
                'stwproStatus'      => $stwpro_status,
                'isProInstalled'    => $this->helper_functions->is_pro_installed(),
                'wpNonce'           => wp_create_nonce( 'wp_rest' ),
                'details'           => $this->details(),
                'rest_save_url'     => $this->render_settings->rest_save_url,
                'rest_action_url'   => $this->render_settings->rest_action_url,
                'rest_importer_url' => $this->render_settings->rest_importer_url,
                'settings'          => $this->render_settings->get_registered_tab_settings(),
                'pluginDirUrl'      => STWLITE_PLUGIN_URL,
                'allowedTags'       => $this->render_settings->allowed_tags(),
                'allowedAttrs'      => $this->render_settings->allowed_attrs(),
            );

            // Load vue scripts.
            $settings_app = new Vite_App(
                'saveto-wishlist-settings-app-scripts',
                'src/apps/settings/index.ts',
                array(
                    'wp-i18n',
                    'wp-url',
                    'wp-hooks',
                    'wp-html-entities',
                    'lodash',
                    'jquery',
                ),
                array(),
                $settings_object
            );

            $settings_app->enqueue();

            $include_editor = true;
        }

        if ( $include_editor ) {
            /***************************************************************************
             * Enqueue wp_editor scripts/styles
             ***************************************************************************
            *
            * We make sure the wp.editor scripts/styles are enqueued as we will be
            * using it in our app.
            */
            wp_enqueue_editor();
            wp_enqueue_media();
        }
    }

    /**
     * Details.
     *
     * @since 1.0.0
     * @access public
     * @return array
     */
    public function details() {
        return array(
            'logo'     => esc_url( STWLITE_IMG_URL ) . 'savetowishlist-big-logo.svg',
            'logo_alt' => __( 'SaveTo Wishlist', 'saveto-wishlist-lite-for-woocommerce' ),
            'title'    => __( 'Settings', 'saveto-wishlist-lite-for-woocommerce' ),
        );
    }

    /**
     * Add body class for wishlists page only.
     *
     * @param string $classes Body classes.
     *
     * @since  1.0.0
     * @access public
     *
     * @return string
     */
    public function add_admin_body_class( $classes ) {
        global $pagenow;

        if ( 'admin.php' === $pagenow ) {
            $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
            if ( false !== strpos( $page, 'save-to-wishlist' ) ) {
                $classes .= ' stw-wishlists-page ';
            }
        }

        return $classes;
    }

    /**
     * Remove notice if inside the admin panel under wishlists pages.
     *
     * @since 1.0.0
     * @access public
     */
    public function remove_notice() {
        $screen = get_current_screen();

        if ( ! $screen ) {
            return;
        }

        if ( false !== strpos( $screen->id, 'save-to-wishlist' ) ) {
            // Remove all admin notices except our own plugin notices.
            global $wp_filter;
            $preserved_callbacks = array(
                array( $this, 'show_review_request_notice' ),
                array( $this, 'show_importer_notice' ),
            );

            if ( isset( $wp_filter['admin_notices'] ) ) {
                foreach ( $wp_filter['admin_notices']->callbacks as $priority => $callbacks ) {
                    foreach ( $callbacks as $callback_id => $callback ) {
                        // Skip our preserved notices.
                        if ( isset( $callback['function'] ) && in_array( $callback['function'], $preserved_callbacks, true ) ) {
                            continue;
                        }
                        remove_action( 'admin_notices', $callback['function'], $priority );
                    }
                }
            }
            remove_all_actions( 'all_admin_notices' );
            remove_all_actions( 'network_admin_notices' );
            remove_all_actions( 'user_admin_notices' );
        }
    }

    /**
     * Flag rewrite flush on option add.
     *
     * @since 1.0.0
     * @access public
     */
    public function flag_rewrite_flush_on_add() {
        update_option( 'stwlite_flush_rewrite_rules_flag', '1', false );
    }

    /**
     * Flag rewrite flush on option update.
     *
     * @param string $old_value The old value.
     * @param string $new_value The new value.
     *
     * @since 1.0.0
     * @access public
     */
    public function flag_rewrite_flush( $old_value, $new_value ) {
        // Only flag for flush if the value actually changed.
        if ( $old_value !== $new_value ) {
            update_option( 'stwlite_flush_rewrite_rules_flag', '1', false );
        }
    }

    /**
     * Maybe flush rewrite rules if flag is set.
     *
     * This runs on 'init' hook with high priority (999) to ensure
     * all rewrite rules are registered before flushing.
     *
     * @since 1.0.0
     * @access public
     */
    public function maybe_flush_rewrite_rules() {
        // Check if we need to flush rewrite rules.
        if ( '1' === get_option( 'stwlite_flush_rewrite_rules_flag' ) ) {
            flush_rewrite_rules();
            delete_option( 'stwlite_flush_rewrite_rules_flag' );
        }
    }

    /**
     * Add settings link to plugins page.
     *
     * @param array $links Existing plugin action links.
     *
     * @since 1.0.2
     * @access public
     *
     * @return array Modified plugin action links.
     */
    public function add_settings_link( $links ) {
        $settings_link = sprintf(
            '<a href="%s">%s</a>',
            esc_url( admin_url( 'admin.php?page=save-to-wishlist-settings' ) ),
            esc_html__( 'Settings', 'saveto-wishlist-lite-for-woocommerce' )
        );

        // Add settings link at the beginning of the links array.
        array_unshift( $links, $settings_link );

        return $links;
    }

    /**
     * Check if we should show the review request.
     *
     * @since 1.0.3
     * @access private
     * @return bool
     */
    private function should_show_review_request() {
        // Check if reviewed.
        if ( 'yes' === get_option( 'stwlite_review_request_dismissed' ) ) {
            return false;
        }

        $install_date = get_option( 'stwlite_review_dismiss_date' );

        // If not set, set it now.
        if ( ! $install_date ) {
            update_option( 'stwlite_review_dismiss_date', time() );
            return false;
        }

        // Check if 10 days passed.
        if ( ( time() - $install_date ) >= ( 10 * DAY_IN_SECONDS ) ) {
            return true;
        }

        return false;
    }

    /**
     * Show review request admin notice.
     * This notice is displayed after 10 days of installation.
     *
     * @since 1.0.3
     * @access public
     */
    public function show_review_request_notice() {
        if ( ! $this->should_show_review_request() ) {
            return;
        }
        ?>
        <div class="stwlite-review-request-notice notice notice-info is-dismissible">
            <div class="stwlite-review-request-content" style="padding: 10px 0;">
                <p style="margin-top: 0;">
                    <strong><?php esc_html_e( 'Enjoying SaveTo Wishlist?', 'saveto-wishlist-lite-for-woocommerce' ); ?></strong>
                </p>
                <p>
                    <?php esc_html_e( 'If you are happy with our plugin, please leave us a review on WordPress.org. It helps us to keep developing the plugin and adding new features. Thank you!', 'saveto-wishlist-lite-for-woocommerce' ); ?>
                </p>
                <p class="stwlite-review-request-actions">
                    <a href="https://wordpress.org/support/plugin/saveto-wishlist-lite-for-woocommerce/reviews/#new-post" class="button button-primary" target="_blank" rel="noopener noreferrer">
                        <?php esc_html_e( 'Leave a Review', 'saveto-wishlist-lite-for-woocommerce' ); ?>
                    </a>
                    <a href="#" class="stwlite-dismiss-review-request" style="margin-left: 15px;">
                        <?php esc_html_e( 'I already did', 'saveto-wishlist-lite-for-woocommerce' ); ?>
                    </a>
                    <a href="#" class="stwlite-dismiss-review-later" style="margin-left: 15px;">
                        <?php esc_html_e( 'Maybe later', 'saveto-wishlist-lite-for-woocommerce' ); ?>
                    </a>
                </p>
            </div>
        </div>
        <?php
    }

    /**
     * Show importer-available admin notice on SaveTo Wishlist pages.
     *
     * Detects source wishlist plugins via Importer_Factory and renders a
     * dismissible notice linking to the Imports settings tab.
     *
     * @since 1.0.6
     * @access public
     */
    public function show_importer_notice() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }

        $screen = get_current_screen();

        if ( ! $screen || false === strpos( $screen->id, 'save-to-wishlist' ) ) {
            return;
        }

        // Skip when this user has dismissed the notice.
        if ( 'yes' === get_user_meta( get_current_user_id(), 'stwlite_importer_notice_dismissed', true ) ) {
            return;
        }

        // Skip when the user is already viewing the Imports tab.
        // phpcs:disable WordPress.Security.NonceVerification.Recommended
        $current_page  = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
        $current_child = isset( $_GET['tab-child'] ) ? sanitize_text_field( wp_unslash( $_GET['tab-child'] ) ) : '';
        // phpcs:enable WordPress.Security.NonceVerification.Recommended

        if ( 'save-to-wishlist-settings' === $current_page && 'importer' === $current_child ) {
            return;
        }

        $detected = Importer_Factory::get_detected_importers();

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

        $names = wp_list_pluck( $detected, 'name' );

        $importer_url = add_query_arg(
            array(
                'page'      => 'save-to-wishlist-settings',
                'tab'       => 'saveto_wishlist',
                'tab-child' => 'importer',
            ),
            admin_url( 'admin.php' )
        );

        $message = sprintf(
            /* translators: %s: comma-separated list of detected wishlist plugin names. */
            _n(
                'We detected an existing wishlist plugin you can import from: %s.',
                'We detected existing wishlist plugins you can import from: %s.',
                count( $names ),
                'saveto-wishlist-lite-for-woocommerce'
            ),
            '<strong>' . esc_html( implode( ', ', $names ) ) . '</strong>'
        );

        $dismiss_nonce = wp_create_nonce( 'stwlite_dismiss_importer_notice' );
        ?>
        <div class="notice notice-info is-dismissible stwlite-importer-notice">
            <p>
                <?php echo wp_kses( $message, array( 'strong' => array() ) ); ?>
            </p>
            <p>
                <a href="<?php echo esc_url( $importer_url ); ?>" class="button button-primary">
                    <?php esc_html_e( 'Go to Importer', 'saveto-wishlist-lite-for-woocommerce' ); ?>
                </a>
            </p>
        </div>
        <script>
            (function ($) {
                $(document).on('click', '.stwlite-importer-notice .notice-dismiss', function () {
                    $.post(ajaxurl, {
                        action: 'stwlite_dismiss_importer_notice',
                        nonce: '<?php echo esc_js( $dismiss_nonce ); ?>'
                    });
                });
            })(jQuery);
        </script>
        <?php
    }

    /**
     * Dismiss the importer notice persistently for the current user.
     *
     * @since 1.0.6
     * @access public
     * @return void
     */
    public function dismiss_importer_notice() {
        check_ajax_referer( 'stwlite_dismiss_importer_notice', 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( 'Unauthorized', 403 );
        }

        update_user_meta( get_current_user_id(), 'stwlite_importer_notice_dismissed', 'yes' );

        wp_die();
    }

    /**
     * Dismiss review request.
     *
     * @since 1.0.3
     * @access public
     */
    public function dismiss_review_request() {
        check_ajax_referer( 'stwlite_dismiss_review_request', 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( 'Unauthorized', 403 );
        }

        if ( isset( $_POST['later'] ) && 'yes' === sanitize_text_field( wp_unslash( $_POST['later'] ) ) ) {
            update_option( 'stwlite_review_dismiss_date', time() );
        } else {
            update_option( 'stwlite_review_request_dismissed', 'yes' );
        }

        wp_die();
    }
}
