<?php
/**
 * Handles logic for the admin settings page.
 *
 * @since 1.3.0
 * @package UABB Admin Settings.
 */

/**
 * This class initializes UABB Builder Admin Settings
 *
 * @class UABBBuilderAdminSettings
 */
final class UABBBuilderAdminSettings {

	/**
	 * Holds any errors that may arise from
	 * saving admin settings.
	 *
	 * @since 1.3.0
	 * @var array $errors
	 */
	public static $errors = array();

	/**
	 * Initializes the admin settings.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function init() {
		add_action( 'after_setup_theme', __CLASS__ . '::init_hooks' );

		// Cron callback must be registered on all requests (including WP-Cron).
		add_action( 'uabbpro_module_usage_cron', __CLASS__ . '::uabb_check_modules_data_usage' );
	}

	/**
	 * Adds the admin menu and enqueues CSS/JS if we are on
	 * the builder admin settings page.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function init_hooks() {
		if ( ! is_admin() ) {
			return;
		}

		add_action( 'network_admin_menu', __CLASS__ . '::menu' );
		add_action( 'admin_menu', __CLASS__ . '::menu' );
		add_action( 'admin_init', __CLASS__ . '::render_styles' );
		add_action( 'admin_footer', __CLASS__ . '::show_nps_notice' );

		// Schedule the weekly module usage cron if opted in.
		if ( 'yes' === get_option( 'uabb_usage_optin', false ) ) {
			self::schedule_usage_cron();
		}
	}

	/**
	 * Schedule the Pro module usage cron event.
	 *
	 * Runs weekly — one scan per week updates both the module-usage counts and the
	 * KPI snapshot. If a different recurrence is already scheduled (e.g. from an
	 * interim build), migrate it to `weekly`.
	 *
	 * On the first schedule for this site, the scan callback is invoked once
	 * synchronously so the first snapshot exists immediately — otherwise a low
	 * traffic site could wait days before WP-Cron picks up the first tick, and
	 * the 24h stats send would ship with empty `kpi_records`.
	 *
	 * @since x.x.x
	 * @return void
	 */
	public static function schedule_usage_cron() {
		$current_recurrence = wp_get_schedule( 'uabbpro_module_usage_cron' );
		$needs_initial_run  = false === $current_recurrence && false === get_option( 'uabbpro_kpi_daily_snapshots', false );

		if ( 'weekly' === $current_recurrence ) {
			return;
		}

		if ( false !== $current_recurrence ) {
			self::unschedule_usage_cron();
		}

		wp_schedule_event( time(), 'weekly', 'uabbpro_module_usage_cron' );

		if ( $needs_initial_run ) {
			self::uabb_check_modules_data_usage();
		}
	}

	/**
	 * Unschedule the Pro module usage cron event.
	 *
	 * @since x.x.x
	 * @return void
	 */
	public static function unschedule_usage_cron() {
		$timestamp = wp_next_scheduled( 'uabbpro_module_usage_cron' );
		if ( $timestamp ) {
			wp_unschedule_event( $timestamp, 'uabbpro_module_usage_cron' );
		}
	}
	/**
	 * Adds the admin menu and enqueues CSS/JS if we are on
	 * the builder admin settings page.
	 *
	 * @since 1.25.1
	 * @return void
	 */
	public static function render_styles() {
		if ( isset( $_GET['page'] ) && isset( $_REQUEST['uabb_setting_nonce'] ) && wp_verify_nonce( sanitize_text_field( $_REQUEST['uabb_setting_nonce'] ), 'uabb_setting_nonce' ) && 'uabb-builder-settings' === $_GET['page'] ) {
			add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
			self::save();
			self::api_key_authenticate();
		}
	}
	/**
	 * API Key Authenticate
	 * the builder admin settings page.
	 *
	 * @since 1.18.0
	 * @return void
	 */
	public static function api_key_authenticate() {
		if ( ! current_user_can( 'delete_users' ) ) {
			return;
		}

		$status = array();

		if ( isset( $_POST['fl-uabb-nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['fl-uabb-nonce'] ), 'uabb' ) ) {

			if ( isset( $_POST['uabb-google-place-api'] ) && ! empty( $_POST['uabb-google-place-api'] ) ) {

				$api_key = sanitize_text_field( $_POST['uabb-google-place-api'] );

				$place_id = 'ChIJq6qqat2_wjsR4Rri4i22ap4';

				$url = add_query_arg(
					array(
						'key'     => $api_key,
						'placeid' => $place_id,
					),
					'https://maps.googleapis.com/maps/api/place/details/json'
				);

				$result = wp_remote_post(
					$url,
					array(
						'method'      => 'POST',
						'timeout'     => 60,
						'httpversion' => '1.0',
						'sslverify'   => false,
					)
				);
				if ( ! is_wp_error( $result ) || wp_remote_retrieve_response_code( $result ) === 200 ) {

					$final_result = json_decode( wp_remote_retrieve_body( $result ) );

					$result_status = $final_result->status;

					switch ( $result_status ) {
						case 'REQUEST_DENIED':
							$new_url = "https://places.googleapis.com/v1/places/$place_id?fields=id,displayName,formatted_address,reviews&key=$api_key";

							$new_result = wp_remote_get(
								$new_url,
								array(
									'method'      => 'GET',
									'timeout'     => 60,
									'httpversion' => '1.1',
									'headers'     => array(
										'Accept' => 'application/json',
									),
								)
							);
					
							if ( ! is_wp_error( $new_result ) && wp_remote_retrieve_response_code( $new_result ) === 200 ) {
								$new_body = json_decode( wp_remote_retrieve_body( $new_result ), true );
								if ( isset( $new_body['id'] ) ) {
									update_option( 'google_status_code', 'yes-new' ); // New Places API Key is valid.
									return;
								}
							} else {
								update_option( 'google_status_code', 'no' );
							}
							break;
						case 'OK':
							update_option( 'google_status_code', 'yes' );
							break;
						default:
							break;
					}
				}
			} else {

				delete_option( 'google_status_code' );

			}
			if ( isset( $_POST['uabb-yelp-api-key'] ) && ! empty( $_POST['uabb-yelp-api-key'] ) ) {

				$yelp_api_key = sanitize_text_field( $_POST['uabb-yelp-api-key'] );

				$business_id = 'ling-ho-chinese-cuisine-los-angeles';

				$url = 'https://api.yelp.com/v3/businesses/' . $business_id . '/reviews';

				$result = wp_remote_get(
					$url,
					array(
						'method'      => 'GET',
						'timeout'     => 60,
						'httpversion' => '1.0',
						'sslverify'   => false,
						'user-agent'  => '',
						'headers'     => array(
							'Authorization' => 'Bearer ' . $yelp_api_key,
						),
					)
				);
				if ( is_wp_error( $result ) ) {

					$error_message = $result->get_error_message();

					update_option( 'yelp_status_code', 'no' );
				} else {

					$reviews = json_decode( $result['body'] );

					$response_code = wp_remote_retrieve_response_code( $result );

					if ( 200 !== $response_code ) {

						$error_message = $reviews->error->code;

						if ( 'VALIDATION_ERROR' === $error_message ) {

							update_option( 'yelp_status_code', 'no' );
						}
					} else {
						update_option( 'yelp_status_code', 'yes' );
					}
				}
			} else {

				delete_option( 'yelp_status_code' );

			}
			global $wpdb;

			$param1 = '%\_transient\_%';
			$param2 = '%_uabb_reviews_%';
			$param3 = '%\_transient\_timeout%';

			$transients = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->options} WHERE option_name LIKE %s AND option_name LIKE %s AND option_name NOT LIKE %s", $param1, $param2, $param3 ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching

			foreach ( $transients as $transient ) {

				$transient_name = $transient->option_name;

				$transient_name = str_replace( '_transient_', '', $transient_name );

				delete_transient( $transient_name );
			}
		}
	}
	/**
	 * Show Branding tab.
	 *
	 * @since 1.16.1
	 * @return bool true | false
	 */
	public static function show_branding() {
		$show_branding = true;

		if ( true === (bool) get_option( 'uabb_hide_branding' ) ) {
			$show_branding = false;
		}

		if ( defined( 'WP_UABB_WHITE_LABEL' ) && WP_UABB_WHITE_LABEL ) {
			$show_branding = false;
		}
		return apply_filters( 'uabb_show_branding', $show_branding );
	}
	/**
	 * Renders the admin settings menu.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function menu() {
		if ( current_user_can( 'manage_options' ) ) {
			$_REQUEST['uabb_setting_nonce'] = wp_create_nonce( 'uabb_setting_nonce' );
			$title                          = UABB_PREFIX;
			$cap                            = 'manage_options';
			$slug                           = 'uabb-builder-settings';
			$func                           = __CLASS__ . '::render';
			add_submenu_page( 'options-general.php', $title, $title, $cap, $slug, $func );
		}
	}

	/**
	 * Enqueues the needed CSS/JS for the builder's admin settings page.
	 *
	 * @since 1.3.0
	 * @param hook $hook get the hooks for the styles.
	 * @return void
	 */
	public static function styles_scripts( $hook ) {

		wp_register_style( 'uabb-admin-css', BB_ULTIMATE_ADDON_URL . 'assets/css/uabb-admin.css', array(), BB_ULTIMATE_ADDON_VER );
		wp_register_script( 'uabb-admin-js', BB_ULTIMATE_ADDON_URL . 'assets/js/uabb-admin.js', array( 'jquery' ), BB_ULTIMATE_ADDON_VER, true );
		wp_localize_script( 'uabb-admin-js', 'uabb', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );

		// Load AJAX script only on Builder UI Panel.

		wp_register_script( 'uabb-lazyload', BB_ULTIMATE_ADDON_URL . 'assets/js/jquery.lazyload.min.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-tabs' ), BB_ULTIMATE_ADDON_VER, true );
		wp_register_script( 'uabb-cloud-templates-shuffle', BB_ULTIMATE_ADDON_URL . 'assets/js/jquery.shuffle.min.js', array( 'jquery' ), BB_ULTIMATE_ADDON_VER, true );
		wp_register_script( 'uabb-cloud-templates', BB_ULTIMATE_ADDON_URL . 'assets/js/uabb-cloud-templates.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-tabs', 'uabb-lazyload', 'uabb-cloud-templates-shuffle' ), BB_ULTIMATE_ADDON_VER, true );
		wp_enqueue_script( 'uabb-admin-menu-js', BB_ULTIMATE_ADDON_URL . 'assets/js/uabb-admin-menu.js', array(), BB_ULTIMATE_ADDON_VER, true );
		wp_register_style( 'uabb-admin-menu-css', BB_ULTIMATE_ADDON_URL . 'assets/css/uabb-admin-menu.css', array(), BB_ULTIMATE_ADDON_VER );

		$uabbcloudtemplates = array(
			'ajaxurl'                => admin_url( 'admin-ajax.php' ),
			'errorMessage'           => __( 'Something went wrong!', 'uabb' ),
			'successMessage'         => __( 'Complete', 'uabb' ),
			'successMessageFetch'    => __( 'Refreshed!', 'uabb' ),
			'errorMessageTryAgain'   => __( 'Try Again!', 'uabb' ),
			'successMessageDownload' => __( 'Installed!', 'uabb' ),
			'btnTextRemove'          => __( 'Remove', 'uabb' ),
			'btnTextDownload'        => __( 'Install', 'uabb' ),
			'btnTextInstall'         => __( 'Installed', 'uabb' ),
			'successMessageRemove'   => __( 'Removed!', 'uabb' ),
		);
		wp_localize_script( 'uabb-cloud-templates', 'UABBCloudTemplates', $uabbcloudtemplates );

		if ( 'settings_page_uabb-builder-settings' === $hook || 'settings_page_uabb-builder-multisite-settings' === $hook ) {

			wp_enqueue_style( 'wp-color-picker' );
			wp_enqueue_script( 'wp-color-picker' );
			wp_enqueue_style( 'uabb-admin-css' );
			wp_enqueue_script( 'uabb-admin-js' );
			wp_enqueue_script( 'uabb-lazyload' );

			wp_enqueue_script( 'uabb-cloud-templates' );
			wp_enqueue_script( 'uabb-lazyload' );
			wp_enqueue_style( 'uabb-admin-menu-css' );

			wp_enqueue_media();

			// Added ThickBox support.
			add_thickbox();

			/** BB Admin CSS */
			wp_enqueue_style( 'fl-builder-admin-settings' );
		}
	}

	/**
	 * Renders the admin settings.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function render() {
		include BB_ULTIMATE_ADDON_DIR . 'includes/admin-settings.php';
	}

	/**
	 * Renders the page class for network installs and single site installs.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function render_page_class() {
		if ( self::multisite_support() ) {
			echo 'fl-settings-network-admin';
		} else {
			echo 'fl-settings-single-install';
		}
	}

	/**
	 * Renders the admin settings page heading.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function render_page_heading() {
		if ( ! empty( $icon ) ) {
			echo '<img src="' . esc_url( $icon ) . '" />';
		}
		echo wp_kses_post( '<span>' . sprintf( /* translators: %s: search term */ _x( '%s Settings', '%s stands for custom branded "UABB" name.', 'uabb' ), UABB_PREFIX ) . '</span>' );
	}

	/**
	 * Renders the update message.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function render_update_message() {

		if ( ! empty( self::$errors ) ) {
			foreach ( self::$errors as $message ) {
				echo '<div class="error"><p>' . esc_html( $message ) . '</p></div>';
			}
		} elseif ( isset( $_REQUEST['uabb_setting_nonce'] ) && wp_verify_nonce( sanitize_text_field( $_REQUEST['uabb_setting_nonce'] ), 'uabb_setting_nonce' ) && ! empty( $_POST ) && ! isset( $_POST['email'] ) ) {
			echo wp_kses_post( '<div class="updated"><p>' ) . esc_attr( __( 'Settings updated!', 'uabb' ) ) . wp_kses_post( '</p></div>' );
		}
	}

	/**
	 * Renders the nav items for the admin settings menu.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function render_nav_items() {
		$items['uabb-license'] = array(
			'title'    => __( 'License', 'uabb' ),
			'show'     => is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
			'priority' => 505,
		);

		$items['uabb'] = array(
			'title'    => __( 'General Settings', 'uabb' ),
			'show'     => ! is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
			'priority' => 506,
		);

		$items['uabb-modules'] = array(
			'title'    => __( 'Modules', 'uabb' ),
			'show'     => is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
			'priority' => 507,
		);

		if ( BB_Ultimate_Addon_Helper::get_builder_uabb_branding( 'uabb-enable-template-cloud' ) ) {

			$items['uabb-cloud-templates'] = array(
				'title'    => __( 'Template Cloud', 'uabb' ),
				'show'     => is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
				'priority' => 508,
			);
		}

		$items['uabb-icons'] = array(
			'title'    => __( 'Font Icon Manager', 'uabb' ),
			'show'     => ! is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
			'priority' => 509,
		);
		if ( self::show_branding() ) {
			$items['uabb-branding'] = array(
				'title'    => __( 'Branding', 'uabb' ),
				'show'     => is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
				'priority' => 510,
			);
		}
		$items['uabb-social']           = array(
			'title'    => __( 'Social Login Settings', 'uabb' ),
			'show'     => ! is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
			'priority' => 511,
		);
		$items['uabb-turnstile']        = array(
			'title'    => __( 'Turnstile Settings', 'uabb' ),
			'show'     => ! is_network_admin() || ! FLBuilderAdminSettings::multisite_support(),
			'priority' => 512,
		);
		$items['uabb-rollback-version'] = array(
			'title'    => __( 'Rollback Version', 'uabb' ),
			'show'     => ( is_network_admin() || ! FLBuilderAdminSettings::multisite_support() ) && bsf_display_rollback_version_form( 'uabb' ),
			'priority' => 513,
		);

		$item_data = apply_filters( 'uabb_builder_admin_settings_nav_items', $items );

		$sorted_data = array();

		foreach ( $item_data as $key => $data ) {
			$data['key']                      = $key;
			$sorted_data[ $data['priority'] ] = $data;
		}

		ksort( $sorted_data );

		foreach ( $sorted_data as $data ) {
			if ( $data['show'] ) {
				echo '<li><a href="#' . esc_attr( $data['key'] ) . '">' . esc_html( $data['title'] ) . '</a></li>';
			}
		}

	}

	/**
	 * Renders the admin settings forms.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function render_forms() {
		// License.
		if ( is_network_admin() || ! self::multisite_support() ) {
			self::render_form( 'license' );
		}

		self::render_form( 'general' );
		self::render_form( 'modules' );
		self::render_form( 'icons' );
		self::render_form( 'branding' );

		self::render_form( 'template-cloud' );
		self::render_form( 'social' );
		self::render_form( 'turnstile' );
		self::render_form( 'rollback-version' );

		// Let extensions hook into form rendering.
		do_action( 'uabb_builder_admin_settings_render_forms' );
	}

	/**
	 * Renders an admin settings form based on the type specified.
	 *
	 * @since 1.3.0
	 * @param string $type The type of form to render.
	 * @return void
	 */
	public static function render_form( $type ) {
		if ( self::has_support( $type ) ) {
			include BB_ULTIMATE_ADDON_DIR . 'includes/admin-settings-' . $type . '.php';
		}
	}

	/**
	 * Renders the action for a form.
	 *
	 * @since 1.3.0
	 * @param string $type The type of form being rendered.
	 * @return void
	 */
	public static function render_form_action( $type = '' ) {
		if ( is_network_admin() ) {
			echo esc_url( network_admin_url( '/settings.php?page=uabb-builder-multisite-settings#' . $type ) );
		} else {
			echo esc_url( admin_url( '/options-general.php?page=uabb-builder-settings#' . $type ) );
		}
	}

	/**
	 * Returns the action for a form.
	 *
	 * @since 1.3.0
	 * @param string $type The type of form being rendered.
	 * @return string The URL for the form action.
	 */
	public static function get_form_action( $type = '' ) {
		if ( is_network_admin() ) {
			return network_admin_url( '/settings.php?page=uabb-builder-multisite-settings#' . $type );
		} else {
			return admin_url( '/options-general.php?page=uabb-builder-settings#' . $type );
		}
	}

	/**
	 * Checks to see if a settings form is supported.
	 *
	 * @since 1.3.0
	 * @param string $type The type of form to check.
	 * @return bool
	 */
	public static function has_support( $type ) {
		return file_exists( BB_ULTIMATE_ADDON_DIR . 'includes/admin-settings-' . $type . '.php' );
	}

	/**
	 * Checks to see if multisite is supported.
	 *
	 * @since 1.3.0
	 * @return bool
	 */
	public static function multisite_support() {
		return is_multisite() && class_exists( 'FLBuilderMultisiteSettings' );
	}

	/**
	 * Adds an error message to be rendered.
	 *
	 * @since 1.3.0
	 * @param string $message The error message to add.
	 * @return void
	 */
	public static function add_error( $message ) {
		self::$errors[] = $message;
	}

	/**
	 * Saves the admin settings.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	public static function save() {
		// Only admins can save settings.
		if ( ! current_user_can( 'delete_users' ) ) {
			return;
		}

		if ( isset( $_POST['fl-uabb-nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['fl-uabb-nonce'] ), 'uabb' ) ) {

			$uabb = UABB_Init::$uabb_options['fl_builder_uabb'];

			isset( $_POST['uabb-enabled-panels'] ) ? $uabb['load_panels']     = true : $uabb['load_panels'] = false;
			isset( $_POST['uabb-live-preview'] ) ? $uabb['uabb-live-preview'] = true : $uabb['uabb-live-preview'] = false;
			isset( $_POST['uabb-load-templates'] ) ? $uabb['load_templates']  = true : $uabb['load_templates'] = false;
			if ( isset( $_POST['uabb-google-map-api'] ) ) {
				$uabb['uabb-google-map-api'] = sanitize_text_field( $_POST['uabb-google-map-api'] );
			}
			isset( $_POST['uabb-enable-beta-updates'] ) ? $uabb['uabb-enable-beta-updates']           = true : $uabb['uabb-enable-beta-updates'] = false;
			isset( $_POST['uabb-enable-analytics-updates'] ) ? $uabb['uabb-enable-analytics-updates'] = true : $uabb['uabb-enable-analytics-updates'] = false;
			if ( isset( $_POST['uabb-enable-analytics-updates'] ) ) {
				update_option( 'uabb_usage_optin', 'yes' );
			} else {
				update_option( 'uabb_usage_optin', 'no' );
			}
			if ( isset( $_POST['uabb-yelp-api-key'] ) ) {
				$uabb['uabb-yelp-api-key'] = sanitize_text_field( $_POST['uabb-yelp-api-key'] );
			}
			if ( isset( $_POST['uabb-google-place-api'] ) ) {
				$uabb['uabb-google-place-api'] = sanitize_text_field( $_POST['uabb-google-place-api'] );
			}

			FLBuilderModel::update_admin_settings_option( '_fl_builder_uabb', $uabb, false );
		}

		if ( isset( $_POST['fl-uabb-branding-nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['fl-uabb-branding-nonce'] ), 'uabb-branding' ) ) {

			if ( isset( $_POST['uabb-plugin-name'] ) ) {
				$uabb['uabb-plugin-name'] = wp_kses_post( $_POST['uabb-plugin-name'] ); }
			if ( isset( $_POST['uabb-plugin-short-name'] ) ) {
				$uabb['uabb-plugin-short-name'] = wp_kses_post( $_POST['uabb-plugin-short-name'] );   }
			if ( isset( $_POST['uabb-plugin-desc'] ) ) {
				$uabb['uabb-plugin-desc'] = wp_kses_post( $_POST['uabb-plugin-desc'] ); }
			if ( isset( $_POST['uabb-author-name'] ) ) {
				$uabb['uabb-author-name'] = wp_kses_post( $_POST['uabb-author-name'] ); }
			if ( isset( $_POST['uabb-author-url'] ) ) {
				$uabb['uabb-author-url'] = sanitize_text_field( $_POST['uabb-author-url'] );   }
			if ( isset( $_POST['uabb-knowledge-base-url'] ) ) {
				$uabb['uabb-knowledge-base-url'] = sanitize_text_field( $_POST['uabb-knowledge-base-url'] );   }
			if ( isset( $_POST['uabb-contact-support-url'] ) ) {
				$uabb['uabb-contact-support-url'] = sanitize_text_field( $_POST['uabb-contact-support-url'] );  }
			if ( isset( $_POST['uabb-plugin-icon-url'] ) ) {
				$uabb['uabb-plugin-icon-url'] = sanitize_text_field( $_POST['uabb-plugin-icon-url'] );   }

			/* Enable / Disable Template Cloud */
			$uabb['uabb-enable-template-cloud'] = false;
			if ( isset( $_POST['uabb-enable-template-cloud'] ) ) {
				$uabb['uabb-enable-template-cloud'] = true;
			}

			/* Enable / Disable Template Cloud */
			$uabb['uabb-global-module-listing'] = false;
			if ( isset( $_POST['uabb-global-module-listing'] ) ) {
				$uabb['uabb-global-module-listing'] = true;
			}

			/* Enable / Disable KB */
			$uabb['uabb-enable-knowledge-base'] = true;
			if ( ! isset( $_POST['uabb-enable-knowledge-base'] ) ) {
				$uabb['uabb-enable-knowledge-base'] = false;
			}

			/* Enable / Disable Template Cloud */
			$uabb['uabb-enable-contact-support'] = true;
			if ( ! isset( $_POST['uabb-enable-contact-support'] ) ) {
				$uabb['uabb-enable-contact-support'] = false;
			}

			if ( isset( $_POST['uabb-hide-branding'] ) ) {
				update_option( 'uabb_hide_branding', true );
			} else {
				update_option( 'uabb_hide_branding', false );
			}

			FLBuilderModel::update_admin_settings_option( '_fl_builder_uabb_branding', $uabb, false );
		}

		if ( isset( $_POST['fl-uabb-modules-nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['fl-uabb-modules-nonce'] ), 'uabb-modules' ) ) {
			$modules = array();

			$modules_array = BB_Ultimate_Addon_Helper::get_all_modules();

			if ( isset( $_POST['uabb-modules'] ) && is_array( $_POST['uabb-modules'] ) ) {

				$modules = array_map( 'sanitize_text_field', $_POST['uabb-modules'] );

				foreach ( $modules_array as $key => $value ) {
					if ( ! array_key_exists( $key, $modules ) ) {
						$modules[ $key ] = 'false';
					}
				}

				$modules['image-icon']         = 'image-icon';
				$modules['advanced-separator'] = 'advanced-separator';
				$modules['uabb-separator']     = 'uabb-separator';
				$modules['uabb-button']        = 'uabb-button';

			} else {
				$modules = array( 'unset_all' => 'unset_all' );
			}

			// update extension options.
			$extenstions_array = BB_Ultimate_Addon_Helper::get_all_extenstions();
			$uabb              = UABB_Init::$uabb_options['fl_builder_uabb'];

			foreach ( $extenstions_array as $slug => $name ) {
				$uabb[ $slug ]                            = true;
				isset( $_POST[ $slug ] ) ? $uabb[ $slug ] = true : $uabb[ $slug ] = false;
			}
			FLBuilderModel::update_admin_settings_option( '_fl_builder_uabb', $uabb, false );
			FLBuilderModel::update_admin_settings_option( '_fl_builder_uabb_modules', $modules, false );
		}
		if ( isset( $_POST['fl-uabb-social-nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['fl-uabb-social-nonce'] ), 'uabb' ) ) {

			$uabb = UABB_Init::$uabb_options['fl_builder_uabb'];

			if ( isset( $_POST['uabb-social-google-client-id'] ) ) {
				$uabb['uabb-social-google-client-id'] = sanitize_text_field( $_POST['uabb-social-google-client-id'] );
			}

			if ( isset( $_POST['uabb-social-google-redirect-url'] ) ) {
				$uabb['uabb-social-google-redirect-url'] = esc_url_raw( $_POST['uabb-social-google-redirect-url'] );
			}
			if ( isset( $_POST['uabb-social-facebook-app-id'] ) ) {
				$uabb['uabb-social-facebook-app-id'] = sanitize_text_field( $_POST['uabb-social-facebook-app-id'] );
			}
			if ( isset( $_POST['uabb-social-facebook-app-secret'] ) ) {
				$uabb['uabb-social-facebook-app-secret'] = sanitize_text_field( $_POST['uabb-social-facebook-app-secret'] );
			}
			if ( isset( $_POST['uabb-social-facebook-redirect-url'] ) ) {
				$uabb['uabb-social-facebook-redirect-url'] = esc_url_raw( $_POST['uabb-social-facebook-redirect-url'] );
			}

			FLBuilderModel::update_admin_settings_option( '_fl_builder_uabb', $uabb, false );
		}

		// Save Turnstile settings.
		if ( isset( $_POST['uabb-turnstile-nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['uabb-turnstile-nonce'] ), 'uabb-turnstile-nonce' ) ) {
			$existing_integration = get_option( '_uabb_integration', array() );
			
			if ( isset( $_POST['cloudflare_turnstile_site_key'] ) ) {
				$existing_integration['cloudflare_turnstile_site_key'] = sanitize_text_field( $_POST['cloudflare_turnstile_site_key'] );
			}
			if ( isset( $_POST['cloudflare_turnstile_secret_key'] ) ) {
				$existing_integration['cloudflare_turnstile_secret_key'] = sanitize_text_field( $_POST['cloudflare_turnstile_secret_key'] );
			}
			if ( isset( $_POST['cloudflare_turnstile_theme'] ) ) {
				$valid_themes = array( 'auto', 'light', 'dark' );
				$theme        = sanitize_text_field( $_POST['cloudflare_turnstile_theme'] );
				$existing_integration['cloudflare_turnstile_theme'] = in_array( $theme, $valid_themes, true ) ? $theme : 'auto';
			}
			if ( isset( $_POST['cloudflare_turnstile_size'] ) ) {
				$valid_sizes = array( 'normal', 'compact' );
				$size        = sanitize_text_field( $_POST['cloudflare_turnstile_size'] );
				$existing_integration['cloudflare_turnstile_size'] = in_array( $size, $valid_sizes, true ) ? $size : 'normal';
			}
			
			update_option( '_uabb_integration', $existing_integration );
		}

		/**
		 *  For Performance
		 *  Update UABB static object from database.
		 */
		UABB_Init::set_uabb_options();

		// Clear all asset cache.
		FLBuilderModel::delete_asset_cache_for_all_posts();
	}

	/**
	 * Render Ultimate Addons for Beaver Builder NPS Survey Notice.
	 *
	 * @since x.x.x
	 * @return void
	 */
	public static function show_nps_notice() {
		// Check if branding should be shown.
		if ( ! self::show_branding() ) {
			return;
		}
	
		$dismiss_timespan = get_option( 'nps-survey-uabb-lite' ) ? ( 3 * MONTH_IN_SECONDS ) : ( 2 * WEEK_IN_SECONDS );
	
		if ( class_exists( 'Nps_Survey' ) ) {
			\Nps_Survey::show_nps_notice(
				'nps-survey-uabb',
				array(
					'show_if'          => true, // Add your display conditions.
					'dismiss_timespan' => 2 * WEEK_IN_SECONDS,
					'display_after'    => $dismiss_timespan,
					'plugin_slug'      => 'uabb',
					'show_on_screens'  => array( 'settings_page_uabb-builder-settings' ),
					'message'          => array(
	
						// Step 1 i.e rating input.
						'logo'                  => esc_url( BB_ULTIMATE_ADDON_URL . 'assets/images/uabb.svg' ),
						'plugin_name'           => __( 'Ultimate Addons for Beaver Builder', 'uabb' ),
						'nps_rating_message'    => __( 'How likely are you to recommend Ultimate Addons for Beaver Builder to your friends or colleagues?', 'uabb' ),
	
						// Step 2A i.e. positive.
						'feedback_title'        => __( 'Thanks a lot for your feedback! 😍', 'uabb' ),
						'feedback_content'      => __( 'Thanks for using Ultimate Addons! Got feedback or suggestions to make it even better? We’d love to hear from you.', 'uabb' ),
						'plugin_rating_link'    => esc_url( 'https://www.trustpilot.com/review/ultimatebeaver.com' ),
	
						// Step 2B i.e. negative.
						'plugin_rating_title'   => __( 'Thank you for your feedback', 'uabb' ),
						'plugin_rating_content' => __( 'We value your input. How can we improve your experience?', 'uabb' ),
					),
				)
			);
		}
	}

	/**
	 * Refresh the cached module usage counts and weekly KPI snapshot.
	 *
	 * Runs in a background cron context (weekly) so analytics data stays current
	 * without burdening admin-facing page loads. One weekly scan updates both
	 * `numeric_values` (via `uabbpro_module_usage_data_option`) and the KPI snapshot
	 * buffer (`uabbpro_kpi_daily_snapshots`).
	 *
	 * @since 1.36.17
	 * @access public
	 * @return void
	 */
	public static function uabb_check_modules_data_usage() {
		$transient_key        = 'uabbpro_module_usage_data';
		$module_usage         = get_transient( $transient_key );
		$needs_module_refresh = false === $module_usage || false === get_option( 'uabbpro_module_usage_data_option' );

		$snapshots             = get_option( 'uabbpro_kpi_daily_snapshots', array() );
		$today                 = current_time( 'Y-m-d' );
		$needs_snapshot_update = ! is_array( $snapshots ) || ! isset( $snapshots[ $today ] );

		if ( ! $needs_module_refresh && ! $needs_snapshot_update ) {
			return;
		}

		$filtered_module_usage = self::get_uabb_module_usage();

		set_transient( $transient_key, $filtered_module_usage, WEEK_IN_SECONDS );
		update_option( 'uabbpro_module_usage_data_option', $filtered_module_usage );
		self::save_kpi_snapshot( $filtered_module_usage );
	}

	/**
	 * Persist the latest KPI snapshot alongside the module usage refresh.
	 *
	 * Keyed by the cron-tick date in `Y-m-d` form. The last 3 entries are kept
	 * so a missed stats send self-heals on the next successful send — ClickHouse
	 * dedupes on `(date, kpi_name)` so re-shipping older snapshots is a no-op.
	 *
	 * `uabb_modules_in_use_total` is the total number of UABB module instances
	 * across all published BB posts on the site (sum of per-module counts). KPI
	 * name matches Lite so a single ClickHouse query covers both editions.
	 *
	 * @since x.x.x
	 * @param array<string, int> $module_usage UABB module usage counts keyed by slug.
	 * @return void
	 */
	private static function save_kpi_snapshot( $module_usage ) {
		$today = current_time( 'Y-m-d' );

		$total = is_array( $module_usage ) ? array_sum( array_map( 'intval', $module_usage ) ) : 0;

		$snapshots = get_option( 'uabbpro_kpi_daily_snapshots', array() );
		if ( ! is_array( $snapshots ) ) {
			$snapshots = array();
		}

		$snapshots[ $today ] = array(
			'numeric_values' => array(
				'uabb_modules_in_use_total' => $total,
			),
		);

		// Keep the three most recent snapshots — buffer for missed sends.
		krsort( $snapshots );
		$snapshots = array_slice( $snapshots, 0, 3, true );

		update_option( 'uabbpro_kpi_daily_snapshots', $snapshots, false );
	}

	/**
	 * Get UABB module usage statistics.
	 *
	 * @since 1.36.17
	 * @access public
	 * @return array<string, int>
	 */
	public static function get_uabb_module_usage() {

		if ( ! class_exists( 'FLBuilder' ) || ! class_exists( 'FLBuilderModel' ) ) {
			return array();
		}

		$uabb_modules_usage = array();

		/**
		 * Cap on how many BB-enabled posts the module-usage scan will walk.
		 * Prevents runaway memory use on sites with tens of thousands of posts.
		 *
		 * @since x.x.x
		 * @param int $cap Maximum posts to scan in a single cron tick.
		 */
		$post_cap = (int) apply_filters( 'uabb_pro_module_usage_post_cap', 5000 );
		if ( $post_cap < 1 ) {
			$post_cap = 5000;
		}

		$per_page = min( 500, $post_cap );
		$scanned  = 0;
		$paged    = 1;

		do {
			$args = array(
				'post_type'              => FLBuilderModel::get_post_types(),
				'post_status'            => 'publish',
				'meta_key'               => '_fl_builder_enabled',
				// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
				'meta_value'             => '1',
				'posts_per_page'         => $per_page,
				'paged'                  => $paged,
				'fields'                 => 'ids',
				'no_found_rows'          => true,
				'update_post_meta_cache' => false,
				'update_post_term_cache' => false,
			);

			$query    = new WP_Query( $args );
			$post_ids = isset( $query->posts ) ? $query->posts : array();

			if ( empty( $post_ids ) ) {
				break;
			}

			foreach ( $post_ids as $post_id ) {

				$meta = get_post_meta( (int) $post_id, '_fl_builder_data', true );

				if ( ! is_array( $meta ) && ! is_object( $meta ) ) {
					continue;
				}

				foreach ( (array) $meta as $node ) {

					if ( ! isset( $node->type ) || 'module' !== $node->type ) {
						continue;
					}

					if ( ! isset( $node->settings->type ) ) {
						continue;
					}

					$module_type = $node->settings->type;

					if ( self::is_uabb_module( $module_type ) ) {

						if ( ! isset( $uabb_modules_usage[ $module_type ] ) ) {
							$uabb_modules_usage[ $module_type ] = 0;
						}

						++$uabb_modules_usage[ $module_type ];
					}
				}
			}

			$batch_count = count( $post_ids );
			$scanned    += $batch_count;
			++$paged;

		} while ( $batch_count === $per_page && $scanned < $post_cap );

		arsort( $uabb_modules_usage );

		return $uabb_modules_usage;
	}

	/**
	 * Check if a module is a UABB module.
	 *
	 * @since 1.36.17
	 * @access private
	 * @param string $module_type Module slug.
	 * @return bool
	 */
	private static function is_uabb_module( $module_type ) {

		$all_modules = \BB_Ultimate_Addon_Helper::get_all_modules();

		foreach ( $all_modules as $pattern => $module_data ) {
			if ( 0 === strpos( $module_type, $pattern ) ) {
				return true;
			}
		}

		return false;
	}

}

UABBBuilderAdminSettings::init();
