<?php
/**
 * System Information and Diagnostics.
 *
 * @package automation-web-platform
 */

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


/**
 * Class WAWP_System_Info
 *
 * Handles system diagnostics and background tasks.
 */
class WAWP_System_Info {
	use WAWP_Security_Trait;
	use WAWP_Settings_Handler;
	use WAWP_Phone_Helper_Trait;

	/**
	 * Database manager.
	 *
	 * @var WAWP_Database_Manager
	 */
	private $db_manager;

	/**
	 * System requirements.
	 *
	 * @var array
	 */
	private $requirements = array();

	/**
	 * Database object.
	 *
	 * @var wpdb
	 */
	public $wpdb;

	/**
	 * Cron hooks.
	 *
	 * @var array
	 */
	private $cron_hooks = array();

	/**
	 * Constructor.
	 */
	public function __construct() {
		global $wpdb;
		$this->wpdb       = $wpdb;
		$this->db_manager = WAWP::instance()->db;
		$this->define_requirements();
		$this->define_cron_hooks();

		add_action( 'admin_init', array( $this, 'check_wc_order_storage_settings' ) );
		add_action( 'admin_init', array( $this, 'add_system_checker_actions' ) );
		add_action( 'admin_notices', array( $this, 'render_system_checker_admin_notice' ) );
	}

	/**
	 * Add system checker actions.
	 */
	public function add_system_checker_actions(): void {
		add_action( 'admin_action_wawp_repair_database', array( $this, 'wawp_handle_repair_action' ) );
		add_action( 'admin_action_wawp_schedule_cron', array( $this, 'wawp_handle_schedule_cron_action' ) );
		add_action( 'admin_action_wawp_repair_all', array( $this, 'wawp_handle_repair_all_action' ) );
	}

	/**
	 * Get a toggle setting.
	 *
	 * @param string $option        Option key.
	 * @param mixed  $default_value Default value.
	 * @return bool Toggle value.
	 */
	private function get_toggle( $option, $default_value = 1 ) {
		return (bool) $this->get_wawp_setting( $option, $default_value );
	}

	/**
	 * Define system requirements.
	 */
	private function define_requirements(): void {
		$this->requirements = $this->db_manager->get_required_tables_and_columns();
	}

	/**
	 * Define cron hooks.
	 */
	private function define_cron_hooks(): void {
		$this->cron_hooks = array( 'wawp_cron_refresh_system_info', 'wawp_cron_hourly_self_repair', 'wawp_cron_daily_cleanup' );

		if ( $this->get_toggle( WAWP_Settings_Registry::CAMPAIGNS_ENABLED, 0 ) ) {
			$this->cron_hooks[] = 'wp_campaigns_cron_send_advanced';
		}

		if ( $this->get_toggle( WAWP_Settings_Registry::ABANDONED_CARTS_ENABLED ) ) {
			$this->cron_hooks[] = 'wawp_cron_process_abandoned_cart_notifications';
		}

		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::SIGNUP_ENABLED ) ) {
			$this->cron_hooks[] = 'wawp_cron_clear_expired_otps';
		}

		$this->cron_hooks[] = 'wawp_mrsb_auto_sync_event';
	}

	/**
	 * Auto assign missing senders.
	 *
	 * @param array $online_instances Online instances.
	 * @return bool Changed status.
	 */
	private function auto_assign_missing_senders( array $online_instances ): bool {
		if ( empty( $online_instances ) ) {
			return false;
		}

		$first_instance_row_id = (int) $online_instances[0]->id;
		$first_instance_id     = $online_instances[0]->instance_id;
		$online_ids_simple     = array_map(
			function ( $i ) {
				return $i->instance_id;
			},
			$online_instances
		);

		$changed = false;

		if ( ! class_exists( 'WAWP_Database_Manager' ) ) {
			require_once WAWP_PLUGIN_DIR . 'includes/class-wawp-database-manager.php';
		}

		// OTP Login.
		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) ) {
			$otp     = $this->get_wawp_setting( WAWP_Settings_Registry::OTP_SETTINGS, array() );
			$current = $otp['instance'] ?? '';
			if ( empty( $current ) || ! in_array( $current, $online_ids_simple, true ) ) {
				$otp['instance'] = $first_instance_id;
				$this->update_wawp_setting( WAWP_Settings_Registry::OTP_SETTINGS, $otp );
				$changed = true;
			}
		}

		// Signup.
		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::SIGNUP_ENABLED ) ) {
			$signup_service = \WAWP_Signup::get_instance();
			$signup_data    = $signup_service->get_settings();
			$current_row_id = (int) ( $signup_data[ WAWP_Settings_Registry::SIGNUP_SELECTED_INSTANCE ] ?? 0 );

			$is_online = false;
			foreach ( $online_instances as $inst ) {
				if ( (int) $inst->id === $current_row_id ) {
					$is_online = true;
					break;
				}
			}

			if ( 0 === $current_row_id || ! $is_online ) {
				// Use the numeric row ID for Signup service.
				$signup_service->update_settings( array( 'selected_instance' => (string) $first_instance_row_id ) );
				$changed = true;
			}
		}

		// Checkout OTP.
		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::CHECKOUT_OTP_ENABLED ) ) {
			$checkout_service = \WAWP_Checkout_Otp::get_instance();
			$checkout_data    = $checkout_service->get_settings();
			$current          = $checkout_data[ WAWP_Settings_Registry::CHECKOUT_SELECTED_INSTANCE ] ?? '';
			if ( empty( $current ) || ! in_array( $current, $online_ids_simple, true ) ) {
				// Use the external instance ID for Checkout service.
				$checkout_service->update_settings( array( 'wawp_selected_instance' => $first_instance_id ) );
				$changed = true;
			}
		}

		// General System Sender.
		$current_general = (int) $this->get_wawp_setting( WAWP_Settings_Registry::GENERAL_INSTANCE, 0 );
		$is_gen_online   = false;
		if ( $current_general > 0 ) {
			foreach ( $online_instances as $inst ) {
				if ( (int) $inst->id === $current_general ) {
					$is_gen_online = true;
					break;
				}
			}
		}

		if ( 0 === $current_general || ! $is_gen_online ) {
			$this->update_wawp_setting( WAWP_Settings_Registry::GENERAL_INSTANCE, (string) $first_instance_row_id );
			$changed = true;
		}

		// Notifications.
		if ( class_exists( 'WooCommerce' ) && $this->get_toggle( WAWP_Settings_Registry::NOTIFICATIONS_ENABLED ) ) {
			$flow_builder   = \WAWP_Flow_Builder::get_instance();
			$notif_settings = $flow_builder->get_global_settings();

			$user_csv  = null;
			$admin_csv = null;

			$current_ids = array_filter( array_map( 'intval', explode( ',', $notif_settings['selected_instance_ids'] ?? '' ) ) );
			if ( empty( $current_ids ) ) {
				$user_csv = (string) $first_instance_row_id;
			} else {
				$any_offline = false;
				foreach ( $current_ids as $cid ) {
					$found = false;
					foreach ( $online_instances as $inst ) {
						if ( (int) $inst->id === $cid ) {
							$found = true;
							break;
						}
					}
					if ( ! $found ) {
						$any_offline = true;
						break;
					}
				}

				if ( $any_offline ) {
					$user_csv = (string) $first_instance_row_id;
				}
			}

			$selected_admin_ids = array_filter( array_map( 'intval', explode( ',', $notif_settings['admin_selected_instance_ids'] ?? '' ) ) );
			if ( empty( $selected_admin_ids ) ) {
				$admin_csv = (string) $first_instance_row_id;
			} else {
				$any_admin_offline = false;
				foreach ( $selected_admin_ids as $aid ) {
					$found = false;
					foreach ( $online_instances as $inst ) {
						if ( (int) $inst->id === $aid ) {
							$found = true;
							break;
						}
					}
					if ( ! $found ) {
						$any_admin_offline = true;
						break;
					}
				}

				if ( $any_admin_offline ) {
					$admin_csv = (string) $first_instance_row_id;
				}
			}

			if ( null !== $user_csv || null !== $admin_csv ) {
				$flow_builder->set_global_settings( $user_csv, $admin_csv );
				$changed = true;
			}
		}

		return $changed;
	}

	/**
	 * Run all system repairs.
	 *
	 * @return array Results.
	 */
	public function run_all_repairs(): array {
		$results = array(
			'db'      => false,
			'cron'    => false,
			'senders' => false,
			'log'     => array(),
		);

		$db_manager_path = WAWP_PLUGIN_DIR . 'includes/class-wawp-database-manager.php';
		if ( file_exists( $db_manager_path ) ) {
			require_once $db_manager_path;
			if ( class_exists( 'WAWP_Database_Manager' ) ) {
				$db_manager = $this->db_manager;
				$db_manager->create_all_tables();
				$results['db']    = true;
				$results['log'][] = esc_html__( 'Database repair process completed.', 'automation-web-platform' );
			} else {
				$results['log'][] = esc_html__( 'Database repair failed: WAWP_Database_Manager class not found.', 'automation-web-platform' );
			}
		} else {
			$results['log'][] = esc_html__( 'Database repair failed: class-wawp-database-manager.php not found.', 'automation-web-platform' );
		}

		if ( ! defined( 'DISABLE_WP_CRON' ) || ! DISABLE_WP_CRON || function_exists( 'as_schedule_recurring_action' ) ) {
			$this->define_cron_hooks();
			foreach ( $this->cron_hooks as $hook ) {
				$interval_seconds = 300; // Default 5 mins.

				if ( 'wawp_cron_refresh_system_info' === $hook ) {
					$interval_seconds = 43200;
				} elseif ( 'wawp_cron_hourly_self_repair' === $hook ) {
					$interval_seconds = 3600;
				} elseif ( 'wawp_mrsb_auto_sync_event' === $hook ) {
					$interval_seconds = 3600;
				} elseif ( 'wawp_cron_clear_expired_otps' === $hook || 'wawp_cron_daily_cleanup' === $hook ) {
					$interval_seconds = 86400;
				}

				WAWP_Task_Scheduler::schedule_recurring( time(), $interval_seconds, $hook );
				/* translators: %s: task hook name */
				$results['log'][] = sprintf( esc_html__( 'Ensured task is scheduled via Action Scheduler: %s.', 'automation-web-platform' ), $hook );
			}
			$results['cron'] = true;
		} else {
			$results['log'][] = esc_html__( 'Cron repair skipped: DISABLE_WP_CRON is set to true in wp-config.php and Action Scheduler is unavailable.', 'automation-web-platform' );
		}

		if ( ! class_exists( 'WAWP_Database_Manager' ) ) {
			require_once WAWP_PLUGIN_DIR . 'includes/class-wawp-database-manager.php';
		}

		$online_instances   = WAWP()->instance_manager->get_online_instances_cached();
		$senders_assigned   = $this->auto_assign_missing_senders( $online_instances );
		$results['senders'] = $senders_assigned;

		if ( $senders_assigned ) {
			$results['log'][] = esc_html__( 'Successfully auto-assigned missing sender settings.', 'automation-web-platform' );
		} else {
			$results['log'][] = esc_html__( 'No missing sender settings to assign or no online instances were available.', 'automation-web-platform' );
		}

		$this->run_checks_and_set_transient();
		$results['log'][] = esc_html__( 'System info cache has been refreshed.', 'automation-web-platform' );

		return $results;
	}

	/**
	 * AJAX Handler for repair all action.
	 */
	public function wawp_handle_repair_all_action() {
		$this->check_permissions( 'wawp_repair_all_nonce', '_wpnonce' );
		WAWP_Connector()->check_admin_auth();

		$results          = $this->run_all_repairs();
		$senders_assigned = $results['senders'];

		$redirect_url = admin_url( 'admin.php?page=' . WAWP_MAIN_MENU_SLUG . '&wawp_section=system_info&repaired_all=success' );
		if ( $senders_assigned ) {
			$redirect_url = add_query_arg( 'senders_assigned', 'true', $redirect_url );
		}

		wp_safe_redirect( $redirect_url );
		exit;
	}

	/**
	 * Handle database repair.
	 *
	 * @return array Result.
	 */
	public function handle_repair_database() {
		$this->db_manager->create_all_tables();
		$this->run_checks_and_set_transient();
		return array(
			'success' => true,
			'message' => esc_html__( 'Database repaired successfully.', 'automation-web-platform' ),
		);
	}

	/**
	 * AJAX Handler for repair database.
	 */
	public function wawp_ajax_repair_database() {
		$this->check_permissions( 'wawp_repair_db_nonce' );
		$res = $this->handle_repair_database();
		$this->send_success( $res['message'] );
	}

	/**
	 * Repair database return.
	 *
	 * @return array
	 */
	public function repair_database_return() {
		return $this->handle_repair_database();
	}

	/**
	 * AJAX Handler for repair action.
	 */
	public function wawp_handle_repair_action() {
		$this->check_permissions( 'wawp_repair_db_nonce', '_wpnonce' );
		WAWP_Connector()->check_admin_auth();

		$db_manager_path = WAWP_PLUGIN_DIR . 'includes/class-wawp-database-manager.php';
		if ( ! file_exists( $db_manager_path ) ) {
			wp_safe_redirect( admin_url( 'admin.php?page=' . WAWP_MAIN_MENU_SLUG . '&wawp_section=system_info&repaired=failed_not_found' ) );
			exit;
		}

		require_once $db_manager_path;
		if ( ! class_exists( 'WAWP_Database_Manager' ) ) {
			wp_safe_redirect( admin_url( 'admin.php?page=' . WAWP_MAIN_MENU_SLUG . '&wawp_section=system_info&repaired=failed_class_missing' ) );
			exit;
		}

		$db_manager = $this->db_manager;
		$db_manager->create_all_tables();
		$this->run_checks_and_set_transient();

		wp_safe_redirect( admin_url( 'admin.php?page=' . WAWP_MAIN_MENU_SLUG . '&wawp_section=system_info&repaired=success' ) );
		exit;
	}

	/**
	 * AJAX Handler for schedule cron action.
	 */
	public function wawp_handle_schedule_cron_action() {
		$this->check_permissions( 'wawp_schedule_cron_nonce', '_wpnonce' );
		WAWP_Connector()->check_admin_auth();

		$hook_input = filter_input( INPUT_GET, 'hook', FILTER_SANITIZE_SPECIAL_CHARS );
		$hook       = $hook_input ? sanitize_key( wp_unslash( $hook_input ) ) : '';
		if ( $hook ) {
			$this->handle_schedule_cron( $hook );
		}

		wp_safe_redirect( admin_url( 'admin.php?page=' . WAWP_MAIN_MENU_SLUG . '&wawp_section=system_info&scheduled=success' ) );
		exit;
	}

	/**
	 * Handle scheduling of a cron task.
	 *
	 * @param string $hook Task hook.
	 * @return array
	 */
	public function handle_schedule_cron( $hook ) {
		$this->define_cron_hooks();
		$is_scheduled = WAWP_Task_Scheduler::next_scheduled( $hook );

		if ( in_array( $hook, $this->cron_hooks, true ) && ! $is_scheduled ) {
			$interval_seconds = 300;
			if ( 'wawp_cron_refresh_system_info' === $hook ) {
				$interval_seconds = 43200;
			} elseif ( 'wawp_cron_hourly_self_repair' === $hook ) {
				$interval_seconds = 3600;
			} elseif ( 'wawp_mrsb_auto_sync_event' === $hook ) {
				$interval_seconds = 3600;
			} elseif ( 'wawp_cron_clear_expired_otps' === $hook || 'wawp_cron_daily_cleanup' === $hook ) {
				$interval_seconds = 86400;
			}

			WAWP_Task_Scheduler::schedule_recurring( time(), $interval_seconds, $hook );
			$this->run_checks_and_set_transient();

			return array(
				'success' => true,
				'message' => esc_html__( 'Cron scheduled successfully.', 'automation-web-platform' ),
				'data'    => $this->get_react_system_info_data(),
			);
		}

		return array(
			'success' => false,
			'message' => esc_html__( 'Failed to schedule cron or already scheduled.', 'automation-web-platform' ),
		);
	}

	/**
	 * AJAX Handler for schedule cron.
	 */
	public function wawp_ajax_schedule_cron() {
		check_ajax_referer( 'wawp_schedule_cron_nonce' );
		$hook = isset( $_POST['hook'] ) ? sanitize_key( wp_unslash( $_POST['hook'] ) ) : '';
		$res  = $this->handle_schedule_cron( $hook );

		if ( $res['success'] ) {
			$this->send_success( $res['message'], $res );
		} else {
			$this->send_error( $res['message'] );
		}
	}

	/**
	 * Schedule cron return.
	 *
	 * @param array $params Parameters.
	 * @return array
	 */
	public function schedule_cron_return( $params ) {
		$hook = isset( $params['hook'] ) ? sanitize_key( $params['hook'] ) : '';
		return $this->handle_schedule_cron( $hook );
	}

	/**
	 * Get columns for a table from db manager.
	 *
	 * @param string $table Table name.
	 * @return array
	 */
	private function db_manager_columns( $table ) {
		return $this->db_manager->columns_map( $table );
	}

	/**
	 * Check if a table exists.
	 *
	 * @param string $table Table name.
	 * @return bool
	 */
	private function table_exists( string $table ): bool {
		return WAWP()->db->table_exists_cached( $table );
	}

	/**
	 * Get columns for a table.
	 *
	 * @param string $table Table name.
	 * @return array
	 */
	private function get_columns( string $table ): array {
		if ( ! $this->table_exists( $table ) ) {
			return array();
		}

		return array_keys( WAWP()->db->columns_map( $table ) );
	}

	/**
	 * Run database checks.
	 *
	 * @return array
	 */
	private function run_db_checks(): array {
		$report     = array();
		$has_issues = false;

		foreach ( $this->requirements as $table => $expected ) {
			$exists  = $this->db_manager->has_table( $table );
			$missing = $exists ? array_diff( $expected, array_keys( $this->db_manager->columns_map( $table ) ) ) : array();

			if ( ! $exists || ! empty( $missing ) ) {
				$has_issues = true;
			}

			$is_internal = ( substr( $table, -13 ) === 'instance_data' );
			$report[]    = array(
				'table'    => $table,
				'exists'   => $exists,
				'missing'  => $missing,
				'internal' => $is_internal,
			);
		}

		$cached_result = array(
			'report'     => $report,
			'has_issues' => $has_issues,
		);

		return $cached_result;
	}

	/**
	 * Run server environment checks.
	 *
	 * @return array
	 */
	private function run_server_env_checks(): array {

		$report        = array();
		$is_ssl        = is_ssl();
		$report['ssl'] = array(
			'label'   => esc_html__( 'SSL Status', 'automation-web-platform' ),
			'status'  => $is_ssl ? esc_html__( 'OK', 'automation-web-platform' ) : esc_html__( 'Warning', 'automation-web-platform' ),
			'message' => $is_ssl ? __( 'Site is using a secure (SSL) connection.', 'automation-web-platform' ) : esc_html__( 'Site is not using SSL. A secure connection is highly recommended.', 'automation-web-platform' ),
		);

		// PHP Memory Limit Check.
		$memory_limit_str   = ini_get( 'memory_limit' );
		$memory_limit_bytes = wp_convert_hr_to_bytes( $memory_limit_str );

		if ( $memory_limit_bytes < 1073741824 ) { // Less than 1024MB.
			$status  = 'Warning';
			$message = sprintf(
				/* translators: %s: Current memory limit */
				esc_html__( 'Current memory limit is %s. We recommend increasing it to 1024M. You can do this by editing wp-config.php or contacting your hosting provider.', 'automation-web-platform' ),
				$memory_limit_str
			);
		} else {
			$status  = 'OK';
			$message = sprintf(
				/* translators: %s: Current memory limit */
				__( 'Memory limit is %s, which is sufficient.', 'automation-web-platform' ),
				$memory_limit_str
			);
		}
		$report['php_memory'] = array(
			'label'   => esc_html__( 'PHP Memory Limit', 'automation-web-platform' ),
			'status'  => $status,
			'message' => $message,
		);

		// Max Execution Time Check.
		$time_limit = ini_get( 'max_execution_time' ); // Get time limit.
		if ( 0 !== (int) $time_limit && (int) $time_limit < 300 ) {
			$report['php_time_limit'] = array(
				'label'   => esc_html__( 'PHP Max Execution Time', 'automation-web-platform' ),
				'status'  => 'Warning',
				'message' => sprintf(
					/* translators: %s: Current time limit */
					esc_html__( 'Current max execution time is %s seconds. We recommend increasing it to 300 seconds for better performance with bulk actions.', 'automation-web-platform' ),
					$time_limit
				),
			);
		} else {
			$report['php_time_limit'] = array(
				'label'   => esc_html__( 'PHP Max Execution Time', 'automation-web-platform' ),
				'status'  => 'OK',
				'message' => esc_html__( 'Max execution time is sufficient.', 'automation-web-platform' ),
			);
		}

		$is_debug           = defined( 'WP_DEBUG' ) && WP_DEBUG;
		$report['wp_debug'] = array(
			'label'   => esc_html__( 'WordPress Debug Mode', 'automation-web-platform' ),
			'status'  => $is_debug ? esc_html__( 'Warning', 'automation-web-platform' ) : esc_html__( 'OK', 'automation-web-platform' ),
			'message' => $is_debug ? esc_html__( 'WP_DEBUG is enabled. This should be disabled on a live production site.', 'automation-web-platform' ) : esc_html__( 'Debug mode is disabled.', 'automation-web-platform' ),
		);

		$is_debug_log           = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG;
		$report['wp_debug_log'] = array(
			'label'   => esc_html__( 'Debug Log', 'automation-web-platform' ),
			'status'  => $is_debug_log ? esc_html__( 'Warning', 'automation-web-platform' ) : esc_html__( 'OK', 'automation-web-platform' ),
			'message' => $is_debug_log ? esc_html__( 'WP_DEBUG_LOG is enabled. Error logging to a file is active.', 'automation-web-platform' ) : esc_html__( 'Debug logging is disabled.', 'automation-web-platform' ),
		);

		if ( defined( 'DISABLE_WP_CRON' ) ) {
			if ( DISABLE_WP_CRON ) {
				$report['disable_wp_cron'] = array(
					'label'   => esc_html__( 'WP-Cron Constant', 'automation-web-platform' ),
					'status'  => esc_html__( 'Error', 'automation-web-platform' ),
					'message' => esc_html__( 'The constant DISABLE_WP_CRON is set to true. This prevents all WordPress scheduled tasks from running automatically. This line must be removed from wp-config.php.', 'automation-web-platform' ),
				);
			} else {
				$report['disable_wp_cron'] = array(
					'label'   => esc_html__( 'WP-Cron Constant', 'automation-web-platform' ),
					'status'  => esc_html__( 'OK', 'automation-web-platform' ),
					'message' => esc_html__( 'The constant DISABLE_WP_CRON is set to false.', 'automation-web-platform' ),
				);
			}
		} else {
			$report['disable_wp_cron'] = array(
				'label'   => esc_html__( 'WP-Cron Constant', 'automation-web-platform' ),
				'status'  => esc_html__( 'OK', 'automation-web-platform' ),
				'message' => esc_html__( 'The constant DISABLE_WP_CRON is not defined.', 'automation-web-platform' ),
			);
		}

		$cached_result = $report;
		return $cached_result;
	}

	/**
	 * Detect CDN or Proxy server.
	 *
	 * @return array
	 */
	private function detect_cdn_proxy(): array {
		$h   = array_change_key_case( $_SERVER, CASE_UPPER );
		$map = array(
			'Cloudflare'        => array( 'HTTP_CF_RAY', 'HTTP_CF_CONNECTING_IP' ),
			'Amazon CloudFront' => array( 'HTTP_CLOUDFRONT_VIEWER_COUNTRY' ),
			'Sucuri'            => array( 'HTTP_X_SUCURI_CLIENTIP' ),
			'Imperva Incapsula' => array( 'HTTP_INCAP_CLIENT_IP' ),
			'StackPath'         => array( 'HTTP_X_SPE_CLIENT' ),
			'Fastly'            => array( 'HTTP_FASTLY_CLIENT_IP' ),
			'Akamai'            => array( 'HTTP_TRUE_CLIENT_IP' ),
		);

		foreach ( $map as $vendor => $keys ) {
			foreach ( $keys as $key ) {
				if ( isset( $h[ $key ] ) ) {
					return array(
						'vendor' => $vendor,
						'proxy'  => true,
					);
				}
			}
		}

		if ( ! empty( $h['HTTP_X_FORWARDED_FOR'] ) && preg_match( '#^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)#', $h['REMOTE_ADDR'] ?? '' ) ) {
			return array(
				'vendor' => esc_html__( 'Generic Proxy/CDN', 'automation-web-platform' ),
				'proxy'  => true,
			);
		}

		return array(
			'vendor' => esc_html__( '---', 'automation-web-platform' ),
			'proxy'  => false,
		);
	}

	/**
	 * Run checks for WP cron system.
	 *
	 * @return array
	 */
	private function run_cron_checks(): array {
		static $cached_result = null;
		if ( null !== $cached_result ) {
			return $cached_result;
		}

		// WP Cron Check.
		$cron_is_disabled = defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON;
		$events           = array();
		$has_issues       = false;

		foreach ( $this->cron_hooks as $hook ) {
			$event   = wp_get_scheduled_event( $hook );
			$as_next = false;

			if ( class_exists( 'WAWP_Task_Scheduler' ) ) {
				$as_next = WAWP_Task_Scheduler::next_scheduled( $hook );
			} elseif ( function_exists( 'as_next_scheduled_action' ) ) {
				$as_next = as_next_scheduled_action( $hook );
			}

			if ( ! $event && ! $as_next ) {
				$has_issues = true;
			}

			$final_next_run = 0;
			if ( $event ) {
				$final_next_run = $event->timestamp;
			}

			if ( $as_next && ( 0 === (int) $final_next_run || $as_next < $final_next_run ) ) {
				$final_next_run = $as_next;
			}

			$events[] = array(
				'hook'      => $hook,
				'scheduled' => (bool) $event || (bool) $as_next,
				'next_run'  => $final_next_run,
				'schedule'  => $event ? ( $event->schedule ? $event->schedule : esc_html__( 'single', 'automation-web-platform' ) ) : ( $as_next ? 'action_scheduler' : '' ),
				'status'    => ( $event || $as_next ) ? 'OK' : 'Missing',
			);
		}

		$cached_result = array(
			'enabled'    => ! $cron_is_disabled,
			'events'     => $events,
			'has_issues' => $has_issues,
		);

		return $cached_result;
	}

	/**
	 * Check if any online WhatsApp instances exist.
	 *
	 * @return array
	 */
	public function check_online_instances_exist(): array {
		$senders_opts  = $this->get_wawp_setting( WAWP_Settings_Registry::SENDERS_ENABLED, array( 'wa' => 1 ) );
		$is_wa_enabled = ! isset( $senders_opts['wa'] ) || 1 === (int) $senders_opts['wa'];

		if ( ! $is_wa_enabled ) {
			return array(
				'label'   => esc_html__( 'Online WhatsApp Instances', 'automation-web-platform' ),
				'status'  => esc_html__( 'Disabled', 'automation-web-platform' ),
				'message' => esc_html__( 'WhatsApp Web is disabled in Sender Settings.', 'automation-web-platform' ),
				'count'   => 0,
			);
		}

		$online_instances = array();
		if ( isset( WAWP()->instance_manager ) && null !== WAWP()->instance_manager ) {
			$online_instances = WAWP()->instance_manager->get_online_instances_cached();
		}
		$status  = empty( $online_instances ) ? esc_html__( 'Error', 'automation-web-platform' ) : esc_html__( 'OK', 'automation-web-platform' );
		$message = empty( $online_instances ) ? esc_html__( 'No **online WhatsApp instances** found. Please connect at least one number in Sender Settings.', 'automation-web-platform' ) : esc_html__( 'At least one online WhatsApp instance is connected.', 'automation-web-platform' );

		$cached_result = array(
			'label'   => esc_html__( 'Online WhatsApp Instances', 'automation-web-platform' ),
			'status'  => $status,
			'message' => $message,
			'count'   => count( $online_instances ),
		);

		return $cached_result;
	}

	/**
	 * Check if selected instances are valid and online.
	 *
	 * @return array
	 */
	private function check_selected_instances_valid(): array {
		$senders_opts  = $this->get_wawp_setting( WAWP_Settings_Registry::SENDERS_ENABLED, array( 'wa' => 1 ) );
		$is_wa_enabled = ! isset( $senders_opts['wa'] ) || 1 === (int) $senders_opts['wa'];

		if ( ! $is_wa_enabled ) {
			$checks['wa_sender_status'] = array(
				'label'   => esc_html__( 'WhatsApp Selected Instances Validations', 'automation-web-platform' ),
				'status'  => esc_html__( 'Disabled', 'automation-web-platform' ),
				'message' => esc_html__( 'WhatsApp Web sender is disabled in Sender Settings. Validations for selected instances were skipped.', 'automation-web-platform' ),
			);
			return array(
				'report'     => $checks,
				'has_issues' => false,
			);
		}

		$checks           = array();
		$has_issues       = false;
		$online_inst_ids  = array();
		$dbm              = $this->db_manager;
		$online_instances = array();
		if ( isset( WAWP()->instance_manager ) && null !== WAWP()->instance_manager ) {
			$online_instances = WAWP()->instance_manager->get_online_instances_cached();
		}

		foreach ( $online_instances as $inst ) {
			$online_inst_ids[] = $inst->instance_id;
		}

		// --- OTP Login ---
		$login_status  = esc_html__( 'Disabled', 'automation-web-platform' );
		$login_message = esc_html__( 'Feature is disabled.', 'automation-web-platform' );
		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::PASSWORDLESS_LOGIN_ENABLED ) ) {
			$otp_settings   = $this->get_wawp_setting( WAWP_Settings_Registry::OTP_SETTINGS, array() );
			$login_instance = $otp_settings['instance'] ?? '';
			if ( empty( $login_instance ) ) {
				$login_status  = esc_html__( 'Warning', 'automation-web-platform' );
				$login_message = esc_html__( 'OTP Login is enabled but **no instance is selected** in Sender Settings.', 'automation-web-platform' );
				$has_issues    = true;
			} elseif ( ! in_array( $login_instance, $online_inst_ids, true ) ) {
				$login_status = esc_html__( 'Error', 'automation-web-platform' );
				/* translators: %s: instance id */
				$login_message = sprintf( esc_html__( 'OTP Login instance **%s is not online or does not exist**. Please check Sender Settings.', 'automation-web-platform' ), esc_html( $login_instance ) );
				$has_issues    = true;
			} else {
				$login_status  = esc_html__( 'OK', 'automation-web-platform' );
				$login_message = esc_html__( 'OTP Login instance is configured and online.', 'automation-web-platform' );
			}
		}
		$checks['otp_login_instance'] = array(
			'label'   => esc_html__( 'OTP Login Sender', 'automation-web-platform' ),
			'status'  => $login_status,
			'message' => $login_message,
		);

		// --- Signup OTP ---
		$signup_status  = esc_html__( 'Disabled', 'automation-web-platform' );
		$signup_message = esc_html__( 'Feature is disabled.', 'automation-web-platform' );
		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::SIGNUP_ENABLED ) ) {
			$signup_row         = class_exists( 'WAWP_Signup' ) ? \WAWP_Signup::get_instance()->get_settings() : array();
			$signup_instance_id = $signup_row[ WAWP_Settings_Registry::SIGNUP_SELECTED_INSTANCE ] ?? '';
			if ( empty( $signup_instance_id ) || '0' === (string) $signup_instance_id ) {
				$signup_status  = esc_html__( 'Warning', 'automation-web-platform' );
				$signup_message = esc_html__( 'WhatsApp OTP Signup is enabled but **no instance is selected** in Sender Settings.', 'automation-web-platform' );
				$has_issues     = true;
			} else {
				$found_online  = false;
				$all_instances = array();
				if ( isset( WAWP()->instance_manager ) && null !== WAWP()->instance_manager ) {
					$all_instances = WAWP()->instance_manager->get_all_instances();
				}
				foreach ( $all_instances as $inst ) {
					if ( (int) $inst->id === (int) $signup_instance_id && 'online' === $inst->status ) {
						$found_online = true;
						break;
					}
				}
				if ( ! $found_online ) {
					$signup_status = esc_html__( 'Error', 'automation-web-platform' );
					/* translators: %s: instance id */
					$signup_message = sprintf( __( 'WhatsApp OTP Signup instance (ID#%s) is **not online or does not exist**. Please check Sender Settings.', 'automation-web-platform' ), esc_html( $signup_instance_id ) );
					$has_issues     = true;
				} else {
					$signup_status  = esc_html__( 'OK', 'automation-web-platform' );
					$signup_message = esc_html__( 'WhatsApp OTP Signup instance is configured and online.', 'automation-web-platform' );
				}
			}
		}
		$checks['otp_signup_instance'] = array(
			'label'   => esc_html__( 'WhatsApp OTP Signup Sender', 'automation-web-platform' ),
			'status'  => $signup_status,
			'message' => $signup_message,
		);

		// --- Checkout OTP ---
		$checkout_status  = esc_html__( 'Disabled', 'automation-web-platform' );
		$checkout_message = esc_html__( 'Feature is disabled.', 'automation-web-platform' );
		if ( $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::CHECKOUT_OTP_ENABLED ) ) {
			$checkout_settings = class_exists( 'WAWP_Checkout_Otp' ) ? \WAWP_Checkout_Otp::get_instance()->get_settings() : array();
			$checkout_instance = $checkout_settings[ WAWP_Settings_Registry::CHECKOUT_SELECTED_INSTANCE ] ?? '';
			if ( empty( $checkout_instance ) ) {
				$checkout_status  = esc_html__( 'Warning', 'automation-web-platform' );
				$checkout_message = esc_html__( 'Checkout OTP Verification is enabled but **no instance is selected** in Sender Settings.', 'automation-web-platform' );
				$has_issues       = true;
			} elseif ( ! in_array( $checkout_instance, $online_inst_ids, true ) ) {
				$checkout_status = esc_html__( 'Error', 'automation-web-platform' );
				/* translators: %s: instance id */
				$checkout_message = sprintf( esc_html__( 'Checkout OTP Verification instance **%s is not online or does not exist**. Please check Sender Settings.', 'automation-web-platform' ), esc_html( $checkout_instance ) );
				$has_issues       = true;
			} else {
				$checkout_status  = esc_html__( 'OK', 'automation-web-platform' );
				$checkout_message = esc_html__( 'Checkout OTP Verification instance is configured and online.', 'automation-web-platform' );
			}
		}
		$checks['checkout_otp_instance'] = array(
			'label'   => esc_html__( 'Checkout OTP Verification Sender', 'automation-web-platform' ),
			'status'  => $checkout_status,
			'message' => $checkout_message,
		);

		// --- General System Sender ---
		$current_general = (int) $this->get_wawp_setting( WAWP_Settings_Registry::GENERAL_INSTANCE, 0 );
		$gen_status      = esc_html__( 'OK', 'automation-web-platform' );
		$gen_message     = esc_html__( 'General System Sender instance is configured and online.', 'automation-web-platform' );

		$found_gen_online = false;
		if ( $current_general > 0 ) {
			foreach ( $online_instances as $inst ) {
				if ( (int) $inst->id === $current_general ) {
					$found_gen_online = true;
					break;
				}
			}
		}

		if ( 0 === $current_general ) {
			$gen_status  = esc_html__( 'Warning', 'automation-web-platform' );
			$gen_message = esc_html__( 'General System Sender is enabled but **no instance is selected** in Sender Settings.', 'automation-web-platform' );
			$has_issues  = true;
		} elseif ( ! $found_gen_online ) {
			$gen_status = esc_html__( 'Error', 'automation-web-platform' );
			/* translators: %d: instance id */
			$gen_message = sprintf( esc_html__( 'General System Sender instance (ID#%d) is **not online or does not exist**. Please check Sender Settings.', 'automation-web-platform' ), $current_general );
			$has_issues  = true;
		}

		$checks['general_system_instance'] = array(
			'label'   => esc_html__( 'General System Sender', 'automation-web-platform' ),
			'status'  => $gen_status,
			'message' => $gen_message,
		);

		// --- Abandoned Cart Sender ---
		$ac_status  = esc_html__( 'Disabled', 'automation-web-platform' );
		$ac_message = esc_html__( 'Feature is disabled.', 'automation-web-platform' );
		if ( $this->get_toggle( WAWP_Settings_Registry::ABANDONED_CARTS_ENABLED ) ) {
			$notif_settings = \WAWP_Flow_Builder::get_instance()->get_global_settings();
			$selected_ids   = array_filter( array_map( 'intval', explode( ',', $notif_settings['selected_instance_ids'] ?? '' ) ) );

			if ( empty( $selected_ids ) ) {
				$ac_status  = esc_html__( 'OK', 'automation-web-platform' );
				$ac_message = esc_html__( 'Using all available online instances (Default).', 'automation-web-platform' );
			} else {
				$all_instances = array();
				if ( isset( WAWP()->instance_manager ) && null !== WAWP()->instance_manager ) {
					$all_instances = WAWP()->instance_manager->get_all_instances();
				}

				$offline_ids = array();
				foreach ( $selected_ids as $row_id ) {
					$found = false;
					foreach ( $all_instances as $inst ) {
						if ( (int) $inst->id === (int) $row_id && 'online' === $inst->status ) {
							$found = true;
							break;
						}
					}
					if ( ! $found ) {
						$offline_ids[] = $row_id;
					}
				}

				if ( ! empty( $offline_ids ) ) {
					$ac_status = esc_html__( 'Error', 'automation-web-platform' );
					/* translators: %s: Comma-separated list of instance IDs */
					$ac_message = sprintf( __( 'Selected Abandoned Cart instances (IDs: %s) are **not online or do not exist**. Please check Sender Settings.', 'automation-web-platform' ), implode( ', ', $offline_ids ) );
					$has_issues = true;
				} else {
					$ac_status  = esc_html__( 'OK', 'automation-web-platform' );
					$ac_message = esc_html__( 'Instances are configured and online.', 'automation-web-platform' );
				}
			}
		}

		$checks['abandoned_cart_instance'] = array(
			'label'   => esc_html__( 'Abandoned Cart Sender', 'automation-web-platform' ),
			'status'  => $ac_status,
			'message' => $ac_message,
		);

		// --- Notifications ---
		$notif_status        = esc_html__( 'Disabled', 'automation-web-platform' );
		$notif_message       = esc_html__( 'Feature is disabled.', 'automation-web-platform' );
		$admin_notif_status  = esc_html__( 'Disabled', 'automation-web-platform' );
		$admin_notif_message = esc_html__( 'Feature is disabled.', 'automation-web-platform' );

		if ( $this->get_toggle( WAWP_Settings_Registry::NOTIFICATIONS_ENABLED ) ) {
			$notif_settings = \WAWP_Flow_Builder::get_instance()->get_global_settings();
			$all_instances  = array();
			if ( isset( WAWP()->instance_manager ) && null !== WAWP()->instance_manager ) {
				$all_instances = WAWP()->instance_manager->get_all_instances();
			}

			// User Instances.
			$selected_user_ids = array_filter( array_map( 'intval', explode( ',', $notif_settings['selected_instance_ids'] ?? '' ) ) );
			if ( empty( $selected_user_ids ) ) {
				$notif_status  = esc_html__( 'Warning', 'automation-web-platform' );
				$notif_message = esc_html__( 'WooCommerce User Notifications are enabled but **no instances are selected** in Sender Settings.', 'automation-web-platform' );
				$has_issues    = true;
			} else {
				$offline_ids = array();
				foreach ( $selected_user_ids as $row_id ) {
					$found = false;
					foreach ( $all_instances as $inst ) {
						if ( (int) $inst->id === (int) $row_id && 'online' === $inst->status ) {
							$found = true;
							break;
						}
					}
					if ( ! $found ) {
						$offline_ids[] = $row_id;
					}
				}
				if ( ! empty( $offline_ids ) ) {
					$notif_status = esc_html__( 'Error', 'automation-web-platform' );
					/* translators: %s: Comma-separated list of instance IDs */
					$notif_message = sprintf( __( 'Some User Notification instances (IDs: %s) are **not online or do not exist**. Please check Sender Settings.', 'automation-web-platform' ), implode( ', ', $offline_ids ) );
					$has_issues    = true;
				} else {
					$notif_status  = esc_html__( 'OK', 'automation-web-platform' );
					$notif_message = esc_html__( 'User Notification instances are configured and online.', 'automation-web-platform' );
				}
			}

			// Admin Instances.
			$selected_admin_ids = array_filter( array_map( 'intval', explode( ',', $notif_settings['admin_selected_instance_ids'] ?? '' ) ) );
			if ( empty( $selected_admin_ids ) ) {
				$admin_notif_status  = esc_html__( 'OK', 'automation-web-platform' );
				$admin_notif_message = esc_html__( 'No specific Admin instances selected. Using User instances as fallback.', 'automation-web-platform' );
			} else {
				$offline_admin_ids = array();
				foreach ( $selected_admin_ids as $row_id ) {
					$found = false;
					foreach ( $all_instances as $inst ) {
						if ( (int) $inst->id === (int) $row_id && 'online' === $inst->status ) {
							$found = true;
							break;
						}
					}
					if ( ! $found ) {
						$offline_admin_ids[] = $row_id;
					}
				}
				if ( ! empty( $offline_admin_ids ) ) {
					$admin_notif_status = esc_html__( 'Error', 'automation-web-platform' );
					/* translators: %s: list of offline instance ids */
					$admin_notif_message = sprintf( __( 'Some Admin Notification instances (IDs: %s) are **not online or do not exist**. Please check Sender Settings.', 'automation-web-platform' ), implode( ', ', $offline_admin_ids ) );
					$has_issues          = true;
				} else {
					$admin_notif_status  = esc_html__( 'OK', 'automation-web-platform' );
					$admin_notif_message = esc_html__( 'Admin Notification instances are configured and online.', 'automation-web-platform' );
				}
			}
		}

		$checks['woo_notifications_instance']       = array(
			'label'   => esc_html__( 'User Notifications Sender', 'automation-web-platform' ),
			'status'  => $notif_status,
			'message' => $notif_message,
		);
		$checks['woo_admin_notifications_instance'] = array(
			'label'   => esc_html__( 'Admin Notifications Sender', 'automation-web-platform' ),
			'status'  => $admin_notif_status,
			'message' => $admin_notif_message,
		);

		$cached_result = array(
			'report'     => $checks,
			'has_issues' => $has_issues,
		);

		return $cached_result;
	}

	/**
	 * Check Meta WhatsApp API settings.
	 *
	 * @return array
	 */
	private function check_meta_settings(): array {
		if ( ! WAWP_Connector()->is_meta_sender_enabled() ) {
			return array(
				'label'   => esc_html__( 'Meta API Configuration', 'automation-web-platform' ),
				'status'  => esc_html__( 'Disabled', 'automation-web-platform' ),
				'message' => esc_html__( 'Meta sender is disabled in Sender Settings.', 'automation-web-platform' ),
			);
		}

		global $wpdb;
		$table = $wpdb->prefix . 'wawp_mws_settings';

		if ( ! $this->table_exists( $table ) ) {
			return array(
				'label'   => esc_html__( 'Meta API Configuration', 'automation-web-platform' ),
				'status'  => esc_html__( 'Misconfigured', 'automation-web-platform' ),
				'message' => esc_html__( 'Meta settings table is missing. Please save setting once.', 'automation-web-platform' ),
			);
		}

		$cache_key = 'wawp_meta_api_config';
		$config    = wp_cache_get( $cache_key, 'wawp_database' );

		if ( false === $config ) {
			$db              = WAWP()->db;
			$api_token       = $db->get_var( $wpdb->prepare( 'SELECT setting_value FROM %i WHERE setting_name = %s', $table, 'wawp_mws_api_token' ) );
			$waba_id         = $db->get_var( $wpdb->prepare( 'SELECT setting_value FROM %i WHERE setting_name = %s', $table, 'wawp_mws_waba_id' ) );
			$phone_number_id = $db->get_var( $wpdb->prepare( 'SELECT setting_value FROM %i WHERE setting_name = %s', $table, 'wawp_mws_phone_number_id' ) );

			$config = array(
				'api_token'       => $api_token,
				'waba_id'         => $waba_id,
				'phone_number_id' => $phone_number_id,
			);
			wp_cache_set( $cache_key, $config, 'wawp_database', HOUR_IN_SECONDS );
		}

		$api_token       = $config['api_token'];
		$waba_id         = $config['waba_id'];
		$phone_number_id = $config['phone_number_id'];

		if ( empty( $api_token ) || empty( $waba_id ) || empty( $phone_number_id ) ) {
			return array(
				'label'   => esc_html__( 'Meta API Configuration', 'automation-web-platform' ),
				'status'  => esc_html__( 'Misconfigured', 'automation-web-platform' ),
				'message' => __( 'Meta App details (API Token, WABA ID, Phone Number ID) are not fully configured.', 'automation-web-platform' ),
			);
		}

		return array(
			'label'   => esc_html__( 'Meta API Configuration', 'automation-web-platform' ),
			'status'  => esc_html__( 'OK', 'automation-web-platform' ),
			'message' => esc_html__( 'Meta API is configured correctly.', 'automation-web-platform' ),
		);
	}

	/**
	 * Check Firebase settings.
	 *
	 * @return array
	 */
	private function check_firebase_settings(): array {
		if ( ! WAWP_Connector()->is_firebase_sender_enabled() ) {
			return array(
				'label'   => esc_html__( 'SMS Configuration', 'automation-web-platform' ),
				'status'  => esc_html__( 'Disabled', 'automation-web-platform' ),
				'message' => esc_html__( 'Sender is disabled in Sender Settings.', 'automation-web-platform' ),
			);
		}

		$fb_settings = $this->get_wawp_setting( WAWP_Settings_Registry::FIREBASE_SETTINGS, array() );
		if ( empty( $fb_settings['apiKey'] ) || empty( $fb_settings['authDomain'] ) || empty( $fb_settings['projectId'] ) ) {
			return array(
				'label'   => esc_html__( 'SMS Configuration', 'automation-web-platform' ),
				'status'  => esc_html__( 'Misconfigured', 'automation-web-platform' ),
				'message' => __( 'Firebase credentials (apiKey, authDomain, projectId) are not fully configured.', 'automation-web-platform' ),
			);
		}

		return array(
			'label'   => esc_html__( 'SMS Configuration', 'automation-web-platform' ),
			'status'  => esc_html__( 'OK', 'automation-web-platform' ),
			'message' => esc_html__( 'SMS is configured correctly.', 'automation-web-platform' ),
		);
	}

	/**
	 * Check SMTP settings.
	 *
	 * @return array
	 */
	private function check_smtp_settings(): array {
		if ( ! WAWP_Connector()->is_email_sender_enabled() ) {
			return array(
				'label'   => esc_html__( 'SMTP Configuration', 'automation-web-platform' ),
				'status'  => esc_html__( 'Disabled', 'automation-web-platform' ),
				'message' => esc_html__( 'Email sender is disabled in Sender Settings.', 'automation-web-platform' ),
			);
		}

		$smtp_opts    = $this->get_wawp_setting( WAWP_Settings_Registry::SMTP_SETTINGS, array() );
		$smtp_enabled = ! empty( $smtp_opts['enabled'] );

		if ( $smtp_enabled ) {
			if ( ! empty( $smtp_opts['auth'] ) ) {
				if ( empty( $smtp_opts['host'] ) || empty( $smtp_opts['user'] ) || empty( $smtp_opts['pass'] ) ) {
					$status  = esc_html__( 'Misconfigured', 'automation-web-platform' );
					$message = __( 'Custom SMTP is enabled but host, username, or password is missing.', 'automation-web-platform' );
				} else {
					$status  = esc_html__( 'OK', 'automation-web-platform' );
					$message = esc_html__( 'Custom SMTP is enabled and configured with authentication.', 'automation-web-platform' );
				}
			} elseif ( empty( $smtp_opts['host'] ) ) {
				$status  = esc_html__( 'Misconfigured', 'automation-web-platform' );
				$message = __( 'Custom SMTP is enabled without authentication, but host is missing.', 'automation-web-platform' );
			} else {
				$status  = esc_html__( 'OK', 'automation-web-platform' );
				$message = esc_html__( 'Custom SMTP is enabled and configured without authentication.', 'automation-web-platform' );
			}
		} else {
			$status  = esc_html__( 'OK', 'automation-web-platform' );
			$message = esc_html__( 'Custom SMTP is **disabled**. The plugin relies on WordPress\'s default mailer.', 'automation-web-platform' );
		}

		return array(
			'label'   => esc_html__( 'SMTP Configuration', 'automation-web-platform' ),
			'status'  => $status,
			'message' => $message,
		);
	}

	/**
	 * Check Loopback requests.
	 *
	 * @return array
	 */
	private function check_loopback(): array {
		$cached = get_transient( 'wawp_loopback_check' );
		if ( false !== $cached ) {
			return $cached;
		}

		$response = wp_remote_get(
			home_url(),
			array(
				'timeout'   => 10,
				'headers'   => array(
					'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
				),
				'sslverify' => false,
			)
		);

		if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) < 400 ) {
			$result = array(
				'status'  => 'OK',
				'message' => 'Loopback requests are working as expected.',
			);
		} else {
			$status_code = wp_remote_retrieve_response_code( $response );
			$result      = array(
				'status'  => 'Error',
				'message' => is_wp_error( $response ) ? $response->get_error_message() : sprintf( 'Loopback request failed (HTTP %d).', $status_code ),
			);
		}

		set_transient( 'wawp_loopback_check', $result, HOUR_IN_SECONDS );
		return $result;
	}

	/**
	 * Check REST API accessibility.
	 *
	 * @return array
	 */
	private function check_rest_api(): array {
		$cached = get_transient( 'wawp_rest_api_check' );
		if ( false !== $cached ) {
			return $cached;
		}

		$response = wp_remote_get(
			rest_url( '/wp/v2/types/post' ),
			array(
				'timeout'   => 10,
				'sslverify' => true,
			)
		);
		if ( ! is_wp_error( $response ) ) {
			$code = wp_remote_retrieve_response_code( $response );
			if ( $code >= 400 ) {
				$result = array(
					'status'  => 'Error',
					'message' => 'The REST API is not accessible (' . $code . ').',
				);
			} else {
				$result = array(
					'status'  => 'OK',
					'message' => 'The REST API is accessible.',
				);
			}
		} else {
			$result = array(
				'status'  => 'Error',
				'message' => 'The REST API is not accessible: ' . $response->get_error_message(),
			);
		}

		set_transient( 'wawp_rest_api_check', $result, HOUR_IN_SECONDS );
		return $result;
	}

	/**
	 * Get cached issue count.
	 *
	 * @return int
	 */
	public function get_cached_issue_count(): int {
		$cached = get_transient( 'wawp_system_info_report_cached' );
		if ( ! $cached ) {
			$cached = $this->gather_all_checks();
			$this->run_checks_and_set_transient();
		}
		return $this->count_total_issues( $cached );
	}

	/**
	 * Gather all system checks.
	 *
	 * @return array
	 */
	public function gather_all_checks(): array {
		if ( ! class_exists( 'WAWP_Senders' ) ) {
			require_once WAWP_PLUGIN_DIR . 'includes/senders/class-wawp-senders.php';
		}
		if ( ! class_exists( 'WAWP_Database_Manager' ) ) {
			require_once WAWP_PLUGIN_DIR . 'includes/class-wawp-database-manager.php';
		}

		if ( method_exists( $this->db_manager, 'clear_db_cache' ) ) {
			$this->db_manager->clear_db_cache();
		}
		$this->define_requirements();
		$this->define_cron_hooks();

		return array(
			'db'                  => $this->run_db_checks(),
			'server_env_security' => $this->run_server_env_checks(),
			'cdn'                 => $this->detect_cdn_proxy(),
			'cron'                => $this->run_cron_checks(),
			'wawp_instances'      => $this->check_online_instances_exist(),
			'wawp_sender_configs' => $this->check_selected_instances_valid(),
			'wawp_mws'            => $this->check_meta_settings(),
			'wawp_firebase'       => $this->check_firebase_settings(),
			'wawp_smtp'           => $this->check_smtp_settings(),
			'wp_env'              => array(
				'loopback' => $this->check_loopback(),
				'rest_api' => $this->check_rest_api(),
			),
		);
	}

	/**
	 * Run checks and set transient.
	 *
	 * @param int $expiration Transient expiration.
	 */
	public function run_checks_and_set_transient( int $expiration = 12 * HOUR_IN_SECONDS ): void {
		set_transient( 'wawp_system_info_report_cached', $this->gather_all_checks(), $expiration );
	}

	/**
	 * Render admin notice for system checker.
	 */
	public function render_system_checker_admin_notice(): void {
		// Disabled in favor of custom dashboard UI.
	}

	/**
	 * Count total issues found.
	 *
	 * @param array $data Checker data.
	 * @return int
	 */
	public function count_total_issues( array $data ): int {
		$issues = 0;
		if ( ! empty( $data['db']['has_issues'] ) ) {
			++$issues;
		}

		foreach ( $data['server_env_security'] as $check ) {
			if ( in_array( $check['status'], array( esc_html__( 'Error', 'automation-web-platform' ), esc_html__( 'Warning', 'automation-web-platform' ) ), true ) ) {
				++$issues;
			}
		}

		if ( ! empty( $data['cdn']['proxy'] ) ) {
			++$issues;
		}

		if ( isset( $data['wp_env']['loopback']['status'] ) && 'Error' === $data['wp_env']['loopback']['status'] ) {
			++$issues;
		}

		if ( isset( $data['wp_env']['rest_api']['status'] ) && 'Error' === $data['wp_env']['rest_api']['status'] ) {
			++$issues;
		}

		if ( ! $data['cron']['enabled'] || $data['cron']['has_issues'] ) {
			++$issues;
		}

		if ( ! in_array( $data['wawp_instances']['status'], array( esc_html__( 'OK', 'automation-web-platform' ), esc_html__( 'Disabled', 'automation-web-platform' ) ), true ) ) {
			++$issues;
		}

		foreach ( $data['wawp_sender_configs']['report'] as $sc ) {
			if ( in_array( $sc['status'], array( esc_html__( 'Error', 'automation-web-platform' ), esc_html__( 'Warning', 'automation-web-platform' ) ), true ) ) {
				++$issues;
			}
		}

		return $issues;
	}

	/**
	 * Count repairable issues found.
	 *
	 * @param array $data Checker data.
	 * @return int
	 */
	public function count_repairable_issues( array $data ): int {
		$issues = 0;
		if ( ! empty( $data['db']['has_issues'] ) ) {
			++$issues;
		}

		if ( ! $data['cron']['enabled'] || $data['cron']['has_issues'] ) {
			++$issues;
		}

		if ( ! in_array( $data['wawp_instances']['status'], array( esc_html__( 'OK', 'automation-web-platform' ), esc_html__( 'Disabled', 'automation-web-platform' ) ), true ) ) {
			++$issues;
		}

		foreach ( $data['wawp_sender_configs']['report'] as $sc ) {
			if ( in_array( $sc['status'], array( esc_html__( 'Error', 'automation-web-platform' ), esc_html__( 'Warning', 'automation-web-platform' ) ), true ) ) {
				++$issues;
			}
		}

		return $issues;
	}

	/**
	 * Get list of WAWP tables.
	 *
	 * @return array
	 */
	private function get_wawp_tables(): array {
		global $wpdb;
		$cache_key = 'wawp_system_tables_list';
		$tables    = wp_cache_get( $cache_key, 'wawp_database' );

		if ( false === $tables ) {
			$prefix = $wpdb->prefix;

			$tables = call_user_func_array( array( $wpdb, 'get_col' ), array( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $prefix . 'wawp_' ) . '%' ) ) );
			wp_cache_set( $cache_key, $tables, 'wawp_database', HOUR_IN_SECONDS );
		}

		return $tables ? $tables : array();
	}

	/**
	 * Get local features status for copy-to-clipboard.
	 *
	 * @return array
	 */
	public function get_local_features_status_for_copy() {
		$senders_opts = $this->get_wawp_setting(
			WAWP_Settings_Registry::SENDERS_ENABLED,
			array(
				'email' => 1,
				'wa'    => 1,
				'meta'  => 1,
				'block' => 1,
			)
		);
		return array(
			'Multilang'          => $this->get_wawp_setting( WAWP_Settings_Registry::MULTILANG_ENABLED, 0 ) ? 'Enabled' : 'Disabled',
			'Seg Notifs'         => $this->get_wawp_setting( WAWP_Settings_Registry::CAMPAIGNS_ENABLED, 0 ) ? 'Enabled' : 'Disabled',
			'Sub Notifs'         => $this->get_wawp_setting( WAWP_Settings_Registry::SUB_NOTIFS_ENABLED, 0 ) ? 'Enabled' : 'Disabled',
			'Abandoned Cart'     => $this->get_wawp_setting( WAWP_Settings_Registry::ABANDONED_CARTS_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Email Smtp'         => ! empty( $senders_opts['email'] ) ? 'Enabled' : 'Disabled',
			'Meta Sender'        => ! empty( $senders_opts['meta'] ) ? 'Enabled' : 'Disabled',
			'Wawp Sender'        => ! empty( $senders_opts['wa'] ) ? 'Enabled' : 'Disabled',
			'Countrycode'        => $this->get_wawp_setting( WAWP_Settings_Registry::COUNTRYCODE_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Chat Button'        => $this->get_wawp_setting( WAWP_Settings_Registry::CHAT_WIDGET_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Block Manager'      => ! empty( $senders_opts['block'] ) ? 'Enabled' : 'Disabled',
			'Notifications'      => $this->get_wawp_setting( WAWP_Settings_Registry::NOTIFICATIONS_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Login Otp'          => $this->get_wawp_setting( WAWP_Settings_Registry::OTP_ENABLED, 1 ) && $this->get_wawp_setting( WAWP_Settings_Registry::PASSWORDLESS_LOGIN_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Checkout Otp'       => $this->get_wawp_setting( WAWP_Settings_Registry::OTP_ENABLED, 1 ) && $this->get_wawp_setting( WAWP_Settings_Registry::CHECKOUT_OTP_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Signup Otp'         => $this->get_wawp_setting( WAWP_Settings_Registry::OTP_ENABLED, 1 ) && $this->get_wawp_setting( WAWP_Settings_Registry::SIGNUP_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'System Info'        => $this->get_wawp_setting( WAWP_Settings_Registry::SYSTEM_INFO_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
			'Login/Signup Pages' => $this->get_wawp_setting( WAWP_Settings_Registry::CUSTOM_PAGES_ENABLED, 1 ) ? 'Enabled' : 'Disabled',
		);
	}

	/**
	 * Get comprehensive system info.
	 *
	 * @return array
	 */
	public function get_system_info() {
		$plugin_data      = get_plugin_data( WAWP_PLUGIN_DIR . 'class-wawp.php' );
		$plugin_version   = isset( $plugin_data['Version'] ) ? $plugin_data['Version'] : esc_html__( 'Unknown', 'automation-web-platform' );
		$plugin_file      = WAWP_PLUGIN_DIR . 'class-wawp.php';
		$last_update_date = file_exists( $plugin_file ) ? date_i18n( 'F d Y, H:i:s', filemtime( $plugin_file ) ) : esc_html__( 'File not found', 'automation-web-platform' );

		global $wpdb;
		$mysql_version      = $wpdb->db_version();
		$active_plugins     = (array) get_option( 'active_plugins', array() );
		$woocommerce_active = in_array( 'woocommerce/woocommerce.php', $active_plugins, true );

		$php_memory_limit_bytes   = wp_convert_hr_to_bytes( ini_get( 'memory_limit' ) );
		$post_max_size_bytes      = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) );
		$wp_max_upload_size_bytes = wp_max_upload_size();

		$wp_version        = get_bloginfo( 'version' );
		$latest_wp_version = get_transient( 'wawp_latest_wp_version' );

		if ( false === $latest_wp_version ) {
			$response = wp_remote_get(
				'https://api.wordpress.org/core/version-check/1.7/',
				array(
					'timeout'   => 10,
					'sslverify' => true,
				)
			);
			if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
				$body              = json_decode( wp_remote_retrieve_body( $response ) );
				$latest_wp_version = $body->offers[0]->current ?? null;
				if ( $latest_wp_version ) {
					set_transient( 'wawp_latest_wp_version', $latest_wp_version, 12 * HOUR_IN_SECONDS );
				}
			}
		}

		$remote_status_cached = get_transient( 'wawp_remote_status_ok' );
		if ( false === $remote_status_cached ) {
			$response = wp_remote_head(
				home_url(),
				array(
					'timeout'     => 5,
					'sslverify'   => true,
					'redirection' => 0,
				)
			);
			if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) < 400 ) {
				$remote_status_cached = esc_html__( 'Enabled', 'automation-web-platform' );
			} else {
				$remote_status_cached = esc_html__( 'Disabled', 'automation-web-platform' );
			}
			set_transient( 'wawp_remote_status_ok', $remote_status_cached, 12 * HOUR_IN_SECONDS );
		}

		$wp_version_class = 'status-false';
		if ( $latest_wp_version && version_compare( $wp_version, $latest_wp_version, '>=' ) ) {
			$wp_version_class = 'status-true';
		}

		$curl_info          = function_exists( 'curl_version' ) ? curl_version() : null;
		$active_plugins     = array();
		$all_plugins        = get_plugins();
		$active_plugin_keys = $this->get_wawp_setting( 'active_plugins', array() );

		foreach ( $active_plugin_keys as $plugin_key ) {
			if ( isset( $all_plugins[ $plugin_key ] ) ) {
				$active_plugins[] = $all_plugins[ $plugin_key ]['Name'] . ' (v' . $all_plugins[ $plugin_key ]['Version'] . ')';
			}
		}

		$active_theme   = wp_get_theme();
		$loopback_check = $this->check_loopback();
		$rest_api_check = $this->check_rest_api();

		return array(
			'server_info'              => isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '',
			'php_version'              => phpversion(),
			'php_memory_limit'         => ini_get( 'memory_limit' ),
			'php_memory_limit_bytes'   => $php_memory_limit_bytes,
			'php_time_limit'           => ini_get( 'max_execution_time' ),
			'php_max_input_time'       => ini_get( 'max_input_time' ),
			'php_max_input_vars'       => ini_get( 'max_input_vars' ),
			'curl_version'             => $curl_info ? $curl_info['version'] : esc_html__( 'Not Available', 'automation-web-platform' ),
			'php_extensions'           => array(
				'curl'     => extension_loaded( 'curl' ),
				'json'     => extension_loaded( 'json' ),
				'mbstring' => extension_loaded( 'mbstring' ),
			),
			'ziparchive'               => class_exists( 'ZipArchive' ) ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ),
			'ziparchive_available'     => class_exists( 'ZipArchive' ),
			'uploads_writable'         => wp_is_writable( wp_upload_dir()['basedir'] ) ? esc_html__( 'Writable', 'automation-web-platform' ) : esc_html__( 'Not Writable', 'automation-web-platform' ),
			'plugins_writable'         => wp_is_writable( WP_PLUGIN_DIR ) ? esc_html__( 'Writable', 'automation-web-platform' ) : esc_html__( 'Not Writable', 'automation-web-platform' ),
			'htaccess'                 => file_exists( ABSPATH . '.htaccess' ) ? esc_html__( 'Found', 'automation-web-platform' ) : esc_html__( 'Not Found', 'automation-web-platform' ),
			'home_url'                 => home_url(),
			'site_url'                 => site_url(),
			'wp_version'               => $wp_version,
			'wp_version_class'         => $wp_version_class,
			'wp_memory_limit'          => WP_MEMORY_LIMIT,
			'wp_max_upload_size'       => size_format( $wp_max_upload_size_bytes ),
			'wp_max_upload_size_bytes' => $wp_max_upload_size_bytes,
			'post_max_size'            => ini_get( 'post_max_size' ),
			'post_max_size_bytes'      => $post_max_size_bytes,
			'wp_multisite'             => is_multisite() ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ),
			'system_language'          => $this->get_wawp_setting( 'WPLANG' ) ? $this->get_wawp_setting( 'WPLANG' ) : 'en_US',
			'user_language'            => get_user_locale(),
			'rtl'                      => is_rtl(),
			'mysql_version'            => $mysql_version,
			'wp_remote_get'            => $remote_status_cached,
			'woocommerce'              => $woocommerce_active,
			'plugin_version'           => $plugin_version,
			'last_update_date'         => $last_update_date,
			'active_theme_name'        => $active_theme->get( 'Name' ),
			'active_theme_version'     => $active_theme->get( 'Version' ),
			'active_plugins'           => $active_plugins,
			'loopback_status'          => $loopback_check,
			'rest_api_status'          => $rest_api_check,
			'object_cache'             => wp_using_ext_object_cache() ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ),
			'wp_debug'                 => defined( 'WP_DEBUG' ) ? ( WP_DEBUG ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ) ) : esc_html__( 'Not Defined', 'automation-web-platform' ),
			'wp_debug_log'             => defined( 'WP_DEBUG_LOG' ) ? ( WP_DEBUG_LOG ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ) ) : esc_html__( 'Not Defined', 'automation-web-platform' ),
			'wp_debug_display'         => defined( 'WP_DEBUG_DISPLAY' ) ? ( WP_DEBUG_DISPLAY ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ) ) : esc_html__( 'Not Defined', 'automation-web-platform' ),
			'db_prefix'                => $wpdb->prefix,
			'db_charset'               => $wpdb->charset,
			'db_collate'               => $wpdb->collate,
			'server_ip'                => isset( $_SERVER['SERVER_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_ADDR'] ) ) : 'Unknown',
			'user_agent'               => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : 'Unknown',
		);
	}

	/**
	 * Get status class for a value compared to requirement.
	 *
	 * @param mixed $value    Actual value.
	 * @param mixed $required Required value.
	 * @return string
	 */
	public function get_status_class( $value, $required ) {
		if ( ! is_numeric( substr( $value, 0, 1 ) ) && ! is_numeric( substr( $required, 0, 1 ) ) ) {
			$required_translated = 'Enabled' === $required ? esc_html__( 'Enabled', 'automation-web-platform' ) : $required;
			$required_translated = 'Writable' === $required ? esc_html__( 'Writable', 'automation-web-platform' ) : $required_translated;
			$required_translated = 'Found' === $required ? esc_html__( 'Found', 'automation-web-platform' ) : $required_translated;
			return $value === $required_translated ? 'status-true' : 'status-false';
		}

		if ( is_numeric( $value ) && is_numeric( $required ) ) {
			return (int) $value >= (int) $required ? 'status-true' : 'status-false';
		}

		return version_compare( $value, $required, '>=' ) ? 'status-true' : 'status-false';
	}

	/**
	 * Check WooCommerce order storage settings.
	 */
	public function check_wc_order_storage_settings() {
		if ( ! class_exists( 'WooCommerce' ) ) {
			return;
		}

		if ( isset( $_GET['wawp_dismiss_notice'] ) && '1' === $_GET['wawp_dismiss_notice'] ) {
			if ( check_admin_referer( 'wawp_dismiss_notice_nonce' ) ) {
				update_option( WAWP_Settings_Registry::WC_ORDER_STORAGE_NOTICE_DISMISSED, 'yes' );
				wp_safe_redirect( remove_query_arg( array( 'wawp_dismiss_notice', '_wpnonce' ) ) );
				exit;
			}
		}

		$hp_order_storage   = get_option( 'woocommerce_custom_orders_table_enabled', 'no' );
		$compatibility_mode = get_option( 'woocommerce_custom_orders_table_data_sync_enabled', 'no' );

		if ( ( 'yes' !== $hp_order_storage || 'yes' !== $compatibility_mode ) && 'yes' !== $this->get_wawp_setting( WAWP_Settings_Registry::WC_ORDER_STORAGE_NOTICE_DISMISSED, 'no' ) ) {
			add_action( 'admin_notices', array( $this, 'display_wc_order_storage_notice' ) );
		}
	}

	/**
	 * Display WooCommerce order storage notice.
	 */
	public function display_wc_order_storage_notice() {
		if ( $this->get_wawp_setting( WAWP_Settings_Registry::WC_ORDER_STORAGE_NOTICE_DISMISSED, 'no' ) === 'yes' ) {
			return;
		}

		$dismiss_url = wp_nonce_url( add_query_arg( 'wawp_dismiss_notice', '1' ), 'wawp_dismiss_notice_nonce' );

		echo '<div class="notice notice-warning is-dismissible">';
		echo '<p>' . esc_html__( 'Wawp recommends enabling "High-performance order storage" and "Enable compatibility mode" in WooCommerce for better performance.', 'automation-web-platform' ) . '</p>';
		echo '<p><a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced&section=features' ) ) . '" class="button wawp-bg-green-600 wawp-border-green-600 wawp-text-white">' . esc_html__( 'Enable these options', 'automation-web-platform' ) . '</a> ';
		echo '<a href="' . esc_url( $dismiss_url ) . '" class="button button-primary">' . esc_html__( 'I have already activated the setting', 'automation-web-platform' ) . '</a></p>';
		echo '</div>';
	}

	/**
	 * Sync users info.
	 *
	 * @return array
	 */
	public function sync_users_info() {
		global $wpdb;

		if ( ! class_exists( 'WAWP_Database_Manager' ) ) {
			require_once WAWP_PLUGIN_DIR . 'includes/class-wawp-database-manager.php';
		}

		$db_manager = $this->db_manager;
		$db_manager->migrate_awp_tables_to_wawp( true ); // true = force merge.

		$table_name = $this->db_manager->tables['user_info'];
		$logs       = array();
		$has_error  = false;
		$wp_users   = get_users( array( 'fields' => array( 'ID', 'user_email', 'user_pass' ) ) );
		$has_woo    = class_exists( 'WooCommerce' );

		foreach ( $wp_users as $user ) {
			$wp_user_id = $user->ID;
			$wp_email   = strtolower( trim( $user->user_email ) );
			if ( empty( $wp_email ) ) {
				/* translators: %d: wp user id */
				$logs[] = sprintf( __( 'Skipped WP user ID #%d (no email).', 'automation-web-platform' ), (int) $wp_user_id );
				continue;
			}

			$wp_pass          = $user->user_pass;
			$wp_fname         = get_user_meta( $wp_user_id, 'first_name', true );
			$wp_lname         = get_user_meta( $wp_user_id, 'last_name', true );
			$wp_phone         = get_user_meta( $wp_user_id, 'phone', true );
			$wc_billing_first = $has_woo ? get_user_meta( $wp_user_id, 'billing_first_name', true ) : '';
			$wc_billing_last  = $has_woo ? get_user_meta( $wp_user_id, 'billing_last_name', true ) : '';
			$wc_billing_phone = $has_woo ? get_user_meta( $wp_user_id, 'billing_phone', true ) : '';

			$final_first = ! empty( $wc_billing_first ) ? $wc_billing_first : $wp_fname;
			$final_last  = ! empty( $wc_billing_last ) ? $wc_billing_last : $wp_lname;
			$final_phone = ! empty( $wc_billing_phone ) ? $wc_billing_phone : $wp_phone;

			$cache_key          = 'wawp_user_sync_id_' . $wp_user_id;
			$existing_user_data = wp_cache_get( $cache_key, 'wawp_database' );

			if ( false === $existing_user_data ) {
				$existing_user_data = WAWP()->db->get_results_cached( $wpdb->prepare( 'SELECT * FROM %i WHERE user_id=%d LIMIT 1', $table_name, $wp_user_id ), $cache_key, 'wawp_database', 300 );
				$existing_user_data = ! empty( $existing_user_data ) ? (object) $existing_user_data[0] : null;
			}
			$existing_id = $existing_user_data ? $existing_user_data->id : false;

			if ( $existing_user_data ) {
				if ( empty( $final_first ) || 'N/A' === $final_first ) {
					$final_first = $existing_user_data->first_name;
				}
				if ( empty( $final_last ) || 'N/A' === $final_last ) {
					$final_last = $existing_user_data->last_name;
				}
				if ( empty( $final_phone ) || 'N/A' === $final_phone ) {
					$final_phone = $existing_user_data->phone;
				}
			}

			if ( empty( $final_first ) ) {
				$final_first = 'N/A';
			}
			if ( empty( $final_last ) ) {
				$final_last = 'N/A';
			}
			if ( empty( $final_phone ) ) {
				$final_phone = 'N/A';
			}

			if ( 'N/A' !== $final_phone ) {
				$final_phone = $this->normalize_phone_number( $final_phone );
			}

			if ( ! empty( $wc_billing_phone ) ) {
				$normalized_billing = $this->normalize_phone_number( $wc_billing_phone );
				WAWP()->connector->sync_user_phone( $wp_user_id, $normalized_billing );
			}

			$whatsapp_verified_value   = ( $existing_user_data && ! empty( $existing_user_data->whatsapp_verified ) ) ? $existing_user_data->whatsapp_verified : 'Not Verified';
			$email_verified_value      = ( $existing_user_data && ! empty( $existing_user_data->email_verified ) && 'Not Verified' !== $existing_user_data->email_verified ) ? $existing_user_data->email_verified : 'Verified';
			$otp_verification_whatsapp = $existing_user_data ? $existing_user_data->otp_verification_whatsapp : 0;
			$otp_verification_email    = $existing_user_data ? $existing_user_data->otp_verification_email : 0;

			$data = array(
				'user_id'                   => $wp_user_id,
				'first_name'                => $final_first,
				'last_name'                 => $final_last,
				'email'                     => $wp_email,
				'phone'                     => $final_phone,
				'password'                  => $wp_pass,
				'otp_verification_email'    => $otp_verification_email,
				'otp_verification_whatsapp' => $otp_verification_whatsapp,
				'whatsapp_verified'         => $whatsapp_verified_value,
				'email_verified'            => $email_verified_value,
			);

			if ( $existing_id ) {
				$changed = false;
				foreach ( $data as $key => $val ) {
					if ( (string) $existing_user_data->$key !== (string) $val ) {
						$changed = true;
						break;
					}
				}

				if ( ! $changed ) {
					continue;
				}

				$res = WAWP()->db->update_row( 'user_info', $data, array( 'id' => $existing_id ) );
				if ( false === $res ) {
					$has_error = true;
					/* translators: 1: user email, 2: error message */
					$logs[] = sprintf( esc_html__( 'Error updating user %1$s: %2$s', 'automation-web-platform' ), $wp_email, $wpdb->last_error );
				}
			} else {
				$res = WAWP()->db->insert( 'user_info', $data );
				if ( false === $res ) {
					$has_error = true;
					/* translators: 1: user email, 2: error message */
					$logs[] = sprintf( esc_html__( 'Error inserting user %1$s: %2$s', 'automation-web-platform' ), $wp_email, $wpdb->last_error );
				}
			}
		}

		return array( ! $has_error, $logs );
	}

	/**
	 * Normalize phone number.
	 *
	 * @param string $phone Phone number.
	 * @return string
	 */
	private function normalize_phone_number( $phone ) {
		return self::get_digits_only( $phone );
	}

	/**
	 * Handle refresh status request.
	 *
	 * @return array
	 */
	public function handle_refresh_status() {
		$this->run_checks_and_set_transient();
		return array(
			'success' => true,
			'data'    => $this->get_react_system_info_data(),
		);
	}

	/**
	 * Handle sync users request.
	 *
	 * @return array
	 */
	public function handle_sync_users() {
		list( $success, $logs ) = $this->sync_users_info();
		return array(
			'success' => $success,
			'logs'    => $logs,
		);
	}

	/**
	 * Handle repair all request.
	 *
	 * @return array
	 */
	public function handle_repair_all() {
		delete_transient( 'wawp_system_info_report_cached' );
		delete_transient( 'wawp_online_instances' );
		wp_cache_delete( 'wawp_all_instances', 'wawp_instances' );
		$results = $this->run_all_repairs();
		return array(
			'success' => true,
			'results' => $results,
			'data'    => $this->get_react_system_info_data(),
		);
	}

	/**
	 * Handle database table truncate.
	 *
	 * @param string $table Table name.
	 * @return array
	 */
	public function handle_truncate_table( $table ) {
		if ( empty( $table ) ) {
			return array(
				'success' => false,
				'message' => 'Table name is required.',
			);
		}

		global $wpdb;

		$res = WAWP()->db->execute_query( $wpdb->prepare( 'TRUNCATE TABLE %i', $table ) );

		wp_cache_delete( 'wawp_table_exists_' . md5( $table ), 'wawp_db' );
		wp_cache_delete( 'wawp_table_cols_' . md5( $table ), 'wawp_db' );

		return array(
			'success' => true,
			'message' => sprintf( 'Table %s truncated successfully.', $table ),
		);
	}

	/**
	 * Handle database table drop.
	 *
	 * @param string $table Table name.
	 * @return array
	 */
	public function handle_drop_table( $table ) {
		if ( empty( $table ) ) {
			return array(
				'success' => false,
				'message' => 'Table name is required.',
			);
		}

		global $wpdb;

		$res = WAWP()->db->execute_query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $table ) );

		wp_cache_delete( 'wawp_table_exists_' . md5( $table ), 'wawp_db' );
		wp_cache_delete( 'wawp_table_cols_' . md5( $table ), 'wawp_db' );

		return array(
			'success' => true,
			'message' => sprintf( 'Table %s dropped successfully.', $table ),
		);
	}

	/**
	 * Handle database table creation.
	 *
	 * @param string $table Table name.
	 * @return array
	 */
	public function handle_create_table( $table ) {
		if ( empty( $table ) ) {
			return array(
				'success' => false,
				'message' => 'Table name is required.',
			);
		}

		$this->db_manager->create_all_tables();
		$this->db_manager->ensure_all_columns();

		return array(
			'success' => true,
			'message' => sprintf( 'Tables check/creation executed.', $table ),
		);
	}

	/**
	 * AJAX Handler for refresh status.
	 */
	public function wawp_ajax_refresh_status() {
		$this->check_permissions( 'wawp_refresh_system_status', '_wpnonce' );
		$res = $this->handle_refresh_status();
		$this->send_success( '', $res );
	}

	/**
	 * Refresh system status return.
	 *
	 * @return array
	 */
	public function refresh_system_status_return() {
		return $this->handle_refresh_status();
	}

	/**
	 * AJAX Handler for sync users.
	 */
	public function wawp_ajax_sync_users() {
		$this->check_permissions( 'wawp_sync_users_action' );
		$res = $this->handle_sync_users();
		if ( $res['success'] ) {
			$this->send_success( '', $res );
		} else {
			$this->send_error( '', 400, $res );
		}
	}

	/**
	 * AJAX Handler for repair all.
	 */
	public function wawp_ajax_repair_all() {
		$this->check_permissions( 'wawp_repair_all_nonce', '_wpnonce' );
		$res = $this->handle_repair_all();
		$this->send_success( '', $res );
	}

	/**
	 * Repair all issues return.
	 *
	 * @return array
	 */
	public function repair_all_issues_return() {
		return $this->handle_repair_all();
	}

	/**
	 * Truncate table return.
	 *
	 * @param array $params Parameters.
	 * @return array|WP_Error
	 */
	public function truncate_table_return( $params ) {
		$table = $params['table'] ?? '';
		if ( ! $table ) {
			return new WP_Error( 'missing_table', 'Table name is required' );
		}

		global $wpdb;
		WAWP()->db->execute_query( $wpdb->prepare( 'TRUNCATE TABLE %i', $table ) );
		return array(
			'success' => true,
			'message' => 'Table truncated successfully',
		);
	}

	/**
	 * Create table return.
	 *
	 * @param array $params Parameters.
	 * @return array|WP_Error
	 */
	public function create_table_return( $params ) {
		$table = $params['table'] ?? '';
		if ( ! $table ) {
			return new WP_Error( 'missing_table', 'Table name is required' );
		}
		$this->db_manager->create_all_tables();
		return array(
			'success' => true,
			'message' => 'Table created successfully',
		);
	}

	/**
	 * Drop table return.
	 *
	 * @param array $params Parameters.
	 * @return array|WP_Error
	 */
	public function drop_table_return( $params ) {
		$table = $params['table'] ?? '';
		if ( ! $table ) {
			return new WP_Error( 'missing_table', 'Table name is required' );
		}

		global $wpdb;

		WAWP()->db->execute_query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $table ) );

		return array(
			'success' => true,
			'message' => 'Table dropped successfully',
		);
	}

	/**
	 * Handle truncate table request.
	 */
	public function wawp_handle_truncate_table() {
		check_ajax_referer( 'wawp_truncate_table_nonce', '_wpnonce' );
		$res = $this->truncate_table_return( $_POST );

		if ( is_wp_error( $res ) ) {
			$this->send_error( $res->get_error_message() );
		}
		$this->send_success( $res['message'] );
	}

	/**
	 * Handle create table request.
	 */
	public function wawp_handle_create_table() {
		check_ajax_referer( 'wawp_create_table_nonce', '_wpnonce' );
		$res = $this->create_table_return( $_POST );

		if ( is_wp_error( $res ) ) {
			$this->send_error( $res->get_error_message() );
		}
		$this->send_success( $res['message'] );
	}

	/**
	 * Handle drop table request.
	 */
	public function wawp_handle_drop_table() {
		check_ajax_referer( 'wawp_drop_table_nonce', '_wpnonce' );
		$res = $this->drop_table_return( $_POST );

		if ( is_wp_error( $res ) ) {
			$this->send_error( $res->get_error_message() );
		}
		$this->send_success( $res['message'] );
	}

	/**
	 * Get React system info data.
	 *
	 * @return array
	 */
	public function get_react_system_info_data(): array {
		// Clear cache to ensure fresh data.
		delete_transient( 'wawp_system_info_report_cached' );
		$system_checker_data = $this->gather_all_checks();

		$system_info      = $this->get_system_info();
		$repairable_count = $this->count_repairable_issues( $system_checker_data );
		$total_issues     = $this->count_total_issues( $system_checker_data );

		$status = 'healthy';
		if ( $repairable_count > 0 ) {
			$status = 'issues';
		} elseif ( $total_issues > 0 ) {
			$status = 'warning';
		}

		$senders_opts               = $this->get_wawp_setting( WAWP_Settings_Registry::SENDERS_ENABLED, array() );
		$is_wa_sender_enabled       = ! empty( $senders_opts['wa'] );
		$is_abandoned_carts_enabled = $this->get_toggle( WAWP_Settings_Registry::ABANDONED_CARTS_ENABLED );
		$is_campaigns_enabled       = $this->get_toggle( WAWP_Settings_Registry::CAMPAIGNS_ENABLED, 0 );
		$is_signup_enabled          = $this->get_toggle( WAWP_Settings_Registry::OTP_ENABLED ) && $this->get_toggle( WAWP_Settings_Registry::SIGNUP_ENABLED );
		$is_notifications_enabled   = $this->get_toggle( WAWP_Settings_Registry::NOTIFICATIONS_ENABLED );

		// WP Env.
		$wp_env = array(
			array(
				'label'  => esc_html__( 'Home URL', 'automation-web-platform' ),
				'value'  => $system_info['home_url'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Site URL', 'automation-web-platform' ),
				'value'  => $system_info['site_url'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'WP Version', 'automation-web-platform' ),
				'value'  => $system_info['wp_version'],
				'status' => 'status-true' === $system_info['wp_version_class'] ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'Multisite', 'automation-web-platform' ),
				'value'  => $system_info['wp_multisite'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'WP Memory Limit', 'automation-web-platform' ),
				'value'  => $system_info['wp_memory_limit'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Language', 'automation-web-platform' ),
				'value'  => $system_info['system_language'] . ' (' . ( $system_info['rtl'] ? 'RTL' : 'LTR' ) . ')',
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'WooCommerce', 'automation-web-platform' ),
				'value'  => $system_info['woocommerce'] ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Disabled', 'automation-web-platform' ),
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Uploads Writable', 'automation-web-platform' ),
				'value'  => $system_info['uploads_writable'],
				'status' => wp_is_writable( wp_upload_dir()['basedir'] ) ? 'OK' : 'Error',
			),
			array(
				'label'  => esc_html__( 'Plugins Writable', 'automation-web-platform' ),
				'value'  => $system_info['plugins_writable'],
				'status' => wp_is_writable( WP_PLUGIN_DIR ) ? 'OK' : 'Error',
			),
			array(
				'label'  => esc_html__( '.htaccess Access', 'automation-web-platform' ),
				'value'  => $system_info['htaccess'],
				'status' => file_exists( ABSPATH . '.htaccess' ) ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'Wawp Version', 'automation-web-platform' ),
				'value'  => $system_info['plugin_version'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Last Update', 'automation-web-platform' ),
				'value'  => $system_info['last_update_date'],
				'status' => 'OK',
			),
			array(
				'label'   => esc_html__( 'REST API', 'automation-web-platform' ),
				'value'   => 'OK' === $system_info['rest_api_status']['status'] ? esc_html__( 'Accessible', 'automation-web-platform' ) : esc_html__( 'Error', 'automation-web-platform' ),
				'status'  => 'OK' === $system_info['rest_api_status']['status'] ? 'OK' : 'Error',
				'message' => $system_info['rest_api_status']['message'],
			),
			array(
				'label'   => esc_html__( 'Loopback Check', 'automation-web-platform' ),
				'value'   => 'OK' === $system_checker_data['wp_env']['loopback']['status'] ? esc_html__( 'OK', 'automation-web-platform' ) : esc_html__( 'Error', 'automation-web-platform' ),
				'status'  => 'OK' === $system_checker_data['wp_env']['loopback']['status'] ? 'OK' : 'Error',
				'message' => $system_checker_data['wp_env']['loopback']['message'],
			),
			array(
				'label'  => esc_html__( 'SSL Status', 'automation-web-platform' ),
				'value'  => is_ssl() ? esc_html__( 'Enabled', 'automation-web-platform' ) : esc_html__( 'Warning', 'automation-web-platform' ),
				'status' => is_ssl() ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'WP_DEBUG', 'automation-web-platform' ),
				'value'  => $system_info['wp_debug'],
				'status' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Warning' : 'OK',
			),
			array(
				'label'  => esc_html__( 'Object Cache', 'automation-web-platform' ),
				'value'  => $system_info['object_cache'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Database Prefix', 'automation-web-platform' ),
				'value'  => $system_info['db_prefix'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Database Charset', 'automation-web-platform' ),
				'value'  => $system_info['db_charset'],
				'status' => 'OK',
			),
		);

		// Server Env.
		$server_env = array(
			array(
				'label'  => esc_html__( 'Server Software', 'automation-web-platform' ),
				'value'  => sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ?? '' ) ),
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'MySQL Version', 'automation-web-platform' ),
				'value'  => $system_info['mysql_version'],
				'status' => 'status-true' === $this->get_status_class( $system_info['mysql_version'], '5.6' ) ? 'OK' : 'Error',
			),
			array(
				'label'  => esc_html__( 'PHP Version', 'automation-web-platform' ),
				'value'  => $system_info['php_version'],
				'status' => 'status-true' === $this->get_status_class( $system_info['php_version'], '7.4' ) ? 'OK' : 'Error',
			),
			array(
				'label'  => esc_html__( 'PHP Memory Limit', 'automation-web-platform' ),
				'value'  => $system_info['php_memory_limit'],
				'status' => ( isset( $system_info['php_memory_limit_bytes'] ) && $system_info['php_memory_limit_bytes'] >= 1024217728 ) ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'PHP Post Max Size', 'automation-web-platform' ),
				'value'  => $system_info['post_max_size'],
				'status' => ( isset( $system_info['post_max_size_bytes'] ) && $system_info['post_max_size_bytes'] >= 2097152 ) ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'PHP Time Limit', 'automation-web-platform' ),
				'value'  => $system_info['php_time_limit'],
				'status' => 'status-true' === $this->get_status_class( $system_info['php_time_limit'], '300' ) ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'Max Input Time', 'automation-web-platform' ),
				'value'  => $system_info['php_max_input_time'],
				'status' => 'status-true' === $this->get_status_class( $system_info['php_max_input_time'], '60' ) ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'Max Input Vars', 'automation-web-platform' ),
				'value'  => $system_info['php_max_input_vars'],
				'status' => 'status-true' === $this->get_status_class( $system_info['php_max_input_vars'], '2500' ) ? 'OK' : 'Warning',
			),
			array(
				'label'  => esc_html__( 'cURL Version', 'automation-web-platform' ),
				'value'  => $system_info['curl_version'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'ZipArchive', 'automation-web-platform' ),
				'value'  => $system_info['ziparchive'],
				'status' => 'OK',
			),
			array(
				'label'  => esc_html__( 'Server IP', 'automation-web-platform' ),
				'value'  => $system_info['server_ip'],
				'status' => 'OK',
			),
		);

		// Health Checks.
		$health_checks   = array();
		$health_checks[] = array(
			'label'   => esc_html__( 'CDN Provider', 'automation-web-platform' ),
			'status'  => $system_checker_data['cdn']['vendor'],
			'details' => $system_checker_data['cdn']['proxy'] ? esc_html__( 'Proxy Detected', 'automation-web-platform' ) : esc_html__( 'No Proxy', 'automation-web-platform' ),
			'level'   => $system_checker_data['cdn']['proxy'] ? 'warning' : 'success',
		);
		$health_checks[] = array(
			'label'   => $system_checker_data['wawp_instances']['label'],
			'status'  => $system_checker_data['wawp_instances']['status'],
			'details' => $system_checker_data['wawp_instances']['message'],
			'level'   => esc_html__( 'OK', 'automation-web-platform' ) === $system_checker_data['wawp_instances']['status'] ? 'success' : ( esc_html__( 'Disabled', 'automation-web-platform' ) === $system_checker_data['wawp_instances']['status'] ? 'muted' : 'error' ),
		);
		foreach ( $system_checker_data['wawp_sender_configs']['report'] as $sc ) {
			$health_checks[] = array(
				'label'   => $sc['label'],
				'status'  => $sc['status'],
				'details' => $sc['message'],
				'level'   => esc_html__( 'OK', 'automation-web-platform' ) === $sc['status'] ? 'success' : ( esc_html__( 'Disabled', 'automation-web-platform' ) === $sc['status'] ? 'muted' : ( esc_html__( 'Warning', 'automation-web-platform' ) === $sc['status'] ? 'warning' : 'error' ) ),
			);
		}

		foreach ( array( 'wawp_smtp', 'wawp_mws', 'wawp_firebase' ) as $key ) {
			$c               = $system_checker_data[ $key ];
			$health_checks[] = array(
				'label'   => $c['label'],
				'status'  => $c['status'],
				'details' => $c['message'],
				'level'   => esc_html__( 'OK', 'automation-web-platform' ) === $c['status'] ? 'success' : ( esc_html__( 'Disabled', 'automation-web-platform' ) === $c['status'] ? 'muted' : 'warning' ),
			);
		}

		// WP Cron.
		$last_cron_hit     = $this->get_wawp_setting( WAWP_Settings_Registry::LAST_SYSTEM_CRON_HIT );
		$cron_status_label = esc_html__( 'OK', 'automation-web-platform' );
		$cron_level        = 'success';
		$cron_desc         = esc_html__( 'System cron is active and working correctly.', 'automation-web-platform' );

		if ( ! $last_cron_hit ) {
			$cron_status_label = esc_html__( 'Error', 'automation-web-platform' );
			$cron_level        = 'error';
			$cron_desc         = __( 'System cron has never fired. To ensure scheduled tasks run reliably, please configure a real cron job.', 'automation-web-platform' );
		} elseif ( ( time() - $last_cron_hit ) > 3600 ) {
			$cron_status_label = esc_html__( 'Warning', 'automation-web-platform' );
			$cron_level        = 'warning';
			/* translators: %s: relative time (e.g. 5 minutes ago) */
			$cron_desc = sprintf( esc_html__( 'System cron last fired %s ago. It appears to be running but might be delayed.', 'automation-web-platform' ), human_time_diff( $last_cron_hit, time() ) );
		}

		$cron_events    = array();
		$cron_hooks_map = array();
		foreach ( $system_checker_data['cron']['events'] as $e ) {
			$cron_hooks_map[ $e['hook'] ] = $e;
		}

		foreach ( $this->cron_hooks as $hook ) {
			$display = true;
			if ( 'wp_campaigns_cron_send_advanced' === $hook && ! $is_campaigns_enabled ) {
				$display = false; }
			if ( 'wawp_cron_clear_expired_otps' === $hook && ! $is_signup_enabled ) {
				$display = false; }
			if ( ! $display ) {
				continue; }

			if ( isset( $cron_hooks_map[ $hook ] ) ) {
				$e             = $cron_hooks_map[ $hook ];
				$cron_events[] = array(
					'hook'         => $hook,
					'status'       => $e['scheduled'] ? esc_html__( 'Scheduled', 'automation-web-platform' ) : esc_html__( 'Not Scheduled', 'automation-web-platform' ),
					'state'        => $e['scheduled'] ? 'scheduled' : 'not_scheduled',
					'next_run'     => $e['scheduled'] ? (
						$e['next_run'] > time()
							/* translators: %s: relative time (e.g. 5 minutes) */
							? sprintf( esc_html__( 'in %s', 'automation-web-platform' ), human_time_diff( time(), $e['next_run'] ) )
							/* translators: %s: relative time (e.g. 5 minutes) */
							: sprintf( esc_html__( '%s ago', 'automation-web-platform' ), human_time_diff( $e['next_run'], time() ) )
					) : '---',
					'can_schedule' => ! $e['scheduled'],
					'nonce'        => wp_create_nonce( 'wawp_schedule_cron_nonce' ),
				);
			} else {
				$cron_events[] = array(
					'hook'     => $hook,
					'status'   => esc_html__( 'Disabled', 'automation-web-platform' ),
					'state'    => 'disabled',
					'next_run' => '---',
				);
			}
		}

		// Database status.
		$db_manager    = $this->db_manager;
		$db_report_map = array();
		foreach ( $system_checker_data['db']['report'] as $ri ) {
			$db_report_map[ $ri['table'] ] = $ri;
		}

		$tables = array();
		foreach ( $db_manager->tables as $tk => $tn ) {
			$display = true;
			if ( ( 'campaigns' === $tk || 'campaigns_queue' === $tk ) && ! $is_campaigns_enabled ) {
				$display = false; }
			if ( ( 'abandoned_carts' === $tk || 'abandoned_cart_notifications_log' === $tk ) && ! $is_abandoned_carts_enabled ) {
				$display = false; }
			if ( ( 'instance_data' === $tk || 'blocked_numbers' === $tk || 'notifications_log' === $tk ) && ! $is_wa_sender_enabled ) {
				$display = false; }
			if ( 'signup_settings' === $tk && ! $is_signup_enabled ) {
				$display = false; }
			// Explicitly hide old notification tables.
			if ( 'notif_notification_rules' === $tk || 'notif_languages' === $tk || 'notif_global' === $tk ) {
				$display = false;
			}
			if ( ! $display ) {
				continue; }

			$row     = $db_report_map[ $tn ] ?? null;
			$exists  = $row ? $row['exists'] : $this->table_exists( $tn );
			$missing = $row ? (array) ( $row['missing'] ?? array() ) : array();

			$tables[] = array(
				'name'         => $tn,
				'status'       => ! $exists ? esc_html__( 'Not Found', 'automation-web-platform' ) : ( ! empty( $missing ) ? esc_html__( 'Incomplete', 'automation-web-platform' ) : esc_html__( 'OK', 'automation-web-platform' ) ),
				'state'        => ! $exists ? 'not_found' : ( ! empty( $missing ) ? 'incomplete' : 'ok' ),
				'missing'      => implode( ', ', $missing ),
				'can_create'   => ! $exists,
				'can_repair'   => $exists && ! empty( $missing ),
				'can_truncate' => $exists,
				'can_delete'   => true,
			);
		}

		$banner_text = '';
		if ( 'healthy' === $status ) {
			$banner_text = esc_html__( 'No issues found. Your system is configured correctly.', 'automation-web-platform' );
		} elseif ( 'issues' === $status ) {
			/* translators: %d: number of issues */
			$banner_text = sprintf( esc_html__( 'We found %d critical system issues that need fixing.', 'automation-web-platform' ), $total_issues );
		} else {
			$banner_text = esc_html__( 'Your system is operational, but we found some settings that could be optimized.', 'automation-web-platform' );
		}

		return array(
			'status'        => $status,
			'header'        => array(
				'title'       => 'healthy' === $status ? esc_html__( 'All Systems Operational', 'automation-web-platform' ) : ( 'issues' === $status ? esc_html__( 'Attention Needed', 'automation-web-platform' ) : esc_html__( 'System Improvements Recommended', 'automation-web-platform' ) ),
				/* translators: %d: number of issues */
				'desc'        => 'healthy' === $status ? esc_html__( 'No issues found. Your system is configured correctly.', 'automation-web-platform' ) : ( 'issues' === $status ? sprintf( esc_html__( 'We found %d critical system issues that need fixing.', 'automation-web-platform' ), $repairable_count ) : __( 'Your system is operational, but we found some settings that could be optimized.', 'automation-web-platform' ) ),
				'issues'      => $total_issues,
				'repairable'  => $repairable_count,
				'banner_text' => $banner_text,
			),
			'wp_env'        => $wp_env,
			'server_env'    => $server_env,
			'wp_config'     => array(
				'theme'   => $system_info['active_theme_name'] . ' (v' . $system_info['active_theme_version'] . ')',
				'plugins' => $system_info['active_plugins'],
			),
			'health_checks' => $health_checks,
			'cron'          => array(
				'enabled'   => $system_checker_data['cron']['enabled'],
				'events'    => $cron_events,
				'status'    => $cron_status_label,
				'level'     => $cron_level,
				'message'   => $cron_desc,
				'url'       => site_url( 'wp-cron.php?doing_wp_cron' ),
				'last_hit'  => $last_cron_hit ? gmdate( 'Y-m-d H:i:s', $last_cron_hit ) : esc_html__( 'Never', 'automation-web-platform' ),
				'is_system' => ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
			),
			'security'      => array_values( $system_checker_data['server_env_security'] ),
			'database'      => $tables,
			'nonces'        => array(
				'truncate'             => wp_create_nonce( 'wawp_truncate_table_nonce' ),
				'create'               => wp_create_nonce( 'wawp_create_table_nonce' ),
				'drop'                 => wp_create_nonce( 'wawp_drop_table_nonce' ),
				'repairAll'            => wp_create_nonce( 'wawp_nonce' ),
				'refresh'              => wp_create_nonce( 'wawp_nonce' ),
				'sync'                 => wp_create_nonce( 'wawp_nonce' ),
				'migrateNotifications' => wp_create_nonce( 'wawp_nonce' ),
			),
			'msgs'          => array(
				'refreshStatus'            => esc_html__( 'Refresh', 'automation-web-platform' ),
				'syncUsers'                => esc_html__( 'Sync Users', 'automation-web-platform' ),
				'copySupport'              => esc_html__( 'Copy for Support', 'automation-web-platform' ),
				'repairAll'                => esc_html__( 'Repair All', 'automation-web-platform' ),
				'itemsNeededAttention'     => esc_html__( 'Items Needing Attention', 'automation-web-platform' ),
				'hideList'                 => esc_html__( 'Hide', 'automation-web-platform' ),
				'showList'                 => esc_html__( 'Show', 'automation-web-platform' ),
				'themeLabel'               => esc_html__( 'Theme', 'automation-web-platform' ),
				'tabWordpress'             => esc_html__( 'WordPress', 'automation-web-platform' ),
				'tabServer'                => esc_html__( 'Server', 'automation-web-platform' ),
				'tabDatabase'              => esc_html__( 'Database', 'automation-web-platform' ),
				'tabSecurity'              => esc_html__( 'Security', 'automation-web-platform' ),
				'tabHealth'                => esc_html__( 'Health', 'automation-web-platform' ),
				'allSystemsOperational'    => esc_html__( 'All Systems Operational', 'automation-web-platform' ),
				'healthyBannerDesc'        => esc_html__( 'Everything is running smoothly.', 'automation-web-platform' ),
				'attentionNeeded'          => esc_html__( 'Attention Needed', 'automation-web-platform' ),
				'warningBannerDesc'        => esc_html__( 'Some non-critical issues were found.', 'automation-web-platform' ),
				'criticalIssuesFound'      => esc_html__( 'Critical Issues Detected', 'automation-web-platform' ),
				'issuesBannerDesc'         => esc_html__( 'Major components need your attention.', 'automation-web-platform' ),
				'btnRunNow'                => esc_html__( 'Run', 'automation-web-platform' ),
				'confirmDeleteTable'       => esc_html__( 'Are you sure you want to delete this table? All data will be lost.', 'automation-web-platform' ),
				'confirmEmptyTable'        => esc_html__( 'Are you sure you want to empty this table?', 'automation-web-platform' ),
				'syncCompleted'            => esc_html__( 'Sync Completed', 'automation-web-platform' ),
				'syncSubtitle'             => esc_html__( 'Users synchronized successfully.', 'automation-web-platform' ),
				'dismiss'                  => esc_html__( 'Dismiss', 'automation-web-platform' ),
				'btnCreate'                => esc_html__( 'Create', 'automation-web-platform' ),
				'btnRepair'                => esc_html__( 'Repair', 'automation-web-platform' ),
				'btnEmptyTable'            => esc_html__( 'Empty', 'automation-web-platform' ),
				'btnDeleteTable'           => esc_html__( 'Drop', 'automation-web-platform' ),
				'activePlugins'            => esc_html__( 'Active Plugins', 'automation-web-platform' ),
				'wpConfigTitle'            => esc_html__( 'WordPress Configuration', 'automation-web-platform' ),
				'cronStatusTitle'          => esc_html__( 'WP-Cron Engine', 'automation-web-platform' ),
				'pluginHealthTitle'        => esc_html__( 'Wawp System Health', 'automation-web-platform' ),
				'databaseStatusTitle'      => esc_html__( 'Database Health', 'automation-web-platform' ),
				'securityTitle'            => __( 'Core & Security Configuration', 'automation-web-platform' ),
				'scheduled'                => esc_html__( 'Scheduled', 'automation-web-platform' ),
				'disabled'                 => esc_html__( 'Disabled', 'automation-web-platform' ),
				'systemCron'               => __( 'System Cron (Server-side)', 'automation-web-platform' ),
				'wpCron'                   => __( 'WP-Cron (Internal)', 'automation-web-platform' ),
				'cronDiagnostics'          => esc_html__( 'Diagnostics', 'automation-web-platform' ),
				'lastCronHit'              => esc_html__( 'Last fired', 'automation-web-platform' ),
				'cronUrlLabel'             => __( 'System Cron URL (Host)', 'automation-web-platform' ),
				'cronUrlInstruction'       => __( 'Use this URL to set up a real CRON job in your hosting control panel (e.g. cPanel).', 'automation-web-platform' ),
				'cronEventsTitle'          => esc_html__( 'Scheduled Tasks Monitoring', 'automation-web-platform' ),
				'migrateNotifications'     => esc_html__( 'Migrate Notifications', 'automation-web-platform' ),
				'migrateNotificationsDesc' => esc_html__( 'Sync all existing notification rules to the new scalable Flow Builder structure.', 'automation-web-platform' ),
				'failedToRefreshStatus'    => esc_html__( 'Failed to refresh status', 'automation-web-platform' ),
				'userSyncFailed'           => esc_html__( 'User sync failed', 'automation-web-platform' ),
				'failedToRepairIssues'     => esc_html__( 'Failed to repair issues', 'automation-web-platform' ),
				'dbNetworkError'           => esc_html__( 'Network error executing database action', 'automation-web-platform' ),
				'failedToScheduleTask'     => esc_html__( 'Failed to schedule task', 'automation-web-platform' ),
				'reportLabel'              => esc_html__( 'Report', 'automation-web-platform' ),
				'wpConfigDesc'             => esc_html__( 'Detailed view of your WordPress environment and installation.', 'automation-web-platform' ),
				'serverEnvDesc'            => esc_html__( 'Server environment settings and values', 'automation-web-platform' ),
				'urlCopied'                => esc_html__( 'URL copied to clipboard', 'automation-web-platform' ),
				'cronEventsDesc'           => esc_html__( 'View and manage scheduled background tasks', 'automation-web-platform' ),
				'pluginHealthDesc'         => esc_html__( 'Status of critical system components', 'automation-web-platform' ),
				'databaseStatusDesc'       => esc_html__( 'Status and tools for database tables', 'automation-web-platform' ),
				'legacyMigrationTitle'     => esc_html__( 'Legacy Data Migration', 'automation-web-platform' ),
				'legacyMigrationDesc'      => esc_html__( 'Sync missing elements from old registration form layout to the new system.', 'automation-web-platform' ),
				'migrationNetworkError'    => esc_html__( 'Network error during migration', 'automation-web-platform' ),
				'btnMigrateNow'            => esc_html__( 'Migrate Now', 'automation-web-platform' ),
				'securityDesc'             => esc_html__( 'Security checks and core configurations', 'automation-web-platform' ),
				'system_info_title'        => esc_html__( 'System Infrastructure', 'automation-web-platform' ),
				'system_info_desc'         => esc_html__( 'Comprehensive diagnostic reports and health monitoring for your environment.', 'automation-web-platform' ),
				/* translators: %s: number of issues */
				'warningIssuesFoundCount'  => esc_html__( 'We found %s system issues that could be optimized.', 'automation-web-platform' ),
				/* translators: %s: number of critical issues */
				'criticalIssuesFoundCount' => esc_html__( 'We found %s critical system issues that need fixing.', 'automation-web-platform' ),
				'refreshSuccess'           => esc_html__( 'Status refreshed', 'automation-web-platform' ),
				'syncSuccess'              => esc_html__( 'User sync complete', 'automation-web-platform' ),
				'repairSuccess'            => esc_html__( 'All issues repaired', 'automation-web-platform' ),
				'actionExecuted'           => esc_html__( 'Action executed', 'automation-web-platform' ),
				'actionFailed'             => esc_html__( 'Action failed', 'automation-web-platform' ),
				'taskScheduled'            => esc_html__( 'Task scheduled', 'automation-web-platform' ),
				'copied'                   => esc_html__( 'Copied to clipboard', 'automation-web-platform' ),
				'copySuccessMsg'           => esc_html__( 'Diagnostic report copied successfully.', 'automation-web-platform' ),
				'updateAvailable'          => esc_html__( 'New Update Available', 'automation-web-platform' ),
				'updateNotice'             => esc_html__( 'A newer version of the platform is available with improvements and fixes.', 'automation-web-platform' ),
				'updateNow'                => esc_html__( 'Update Now', 'automation-web-platform' ),
				'accountIssue'             => esc_html__( 'Account Issue Reported', 'automation-web-platform' ),
				'notLoggedIn'              => esc_html__( 'Platform Authentication Required', 'automation-web-platform' ),
				'signInNow'                => esc_html__( 'Sign In Now', 'automation-web-platform' ),
				'requiredTablesMissing'    => esc_html__( 'Required tables are missing or incomplete.', 'automation-web-platform' ),
				'cronDisabledDesc'         => esc_html__( 'WP-Cron is disabled on this site.', 'automation-web-platform' ),
				'taskNotScheduled'         => esc_html__( 'Task is not scheduled.', 'automation-web-platform' ),
				'migrationComplete'        => esc_html__( 'Migration complete', 'automation-web-platform' ),
				'migrationFailed'          => esc_html__( 'Migration failed', 'automation-web-platform' ),
				'notificationsMigration'   => esc_html__( 'Notifications Migration', 'automation-web-platform' ),
				'btnFix'                   => esc_html__( 'Fix', 'automation-web-platform' ),
				'tabCron'                  => esc_html__( 'Cron', 'automation-web-platform' ),
				'statusOk'                 => esc_html__( 'OK', 'automation-web-platform' ),
				'statusHealthy'            => esc_html__( 'Healthy', 'automation-web-platform' ),
				'statusEnabled'            => esc_html__( 'Enabled', 'automation-web-platform' ),
				'statusDisabled'           => esc_html__( 'Disabled', 'automation-web-platform' ),
				'statusWritable'           => esc_html__( 'Writable', 'automation-web-platform' ),
				'statusAccessible'         => esc_html__( 'Accessible', 'automation-web-platform' ),
				'statusScheduled'          => esc_html__( 'Scheduled', 'automation-web-platform' ),
				'statusNotScheduled'       => esc_html__( 'Not Scheduled', 'automation-web-platform' ),
				'statusWarning'            => esc_html__( 'Warning', 'automation-web-platform' ),
				'statusError'              => esc_html__( 'Error', 'automation-web-platform' ),
				'statusIncomplete'         => esc_html__( 'Incomplete', 'automation-web-platform' ),
				'statusNotFound'           => esc_html__( 'Not Found', 'automation-web-platform' ),
			),
		);
	}

	/**
	 * AJAX Handler for wizard checks.
	 */
	public function wawp_ajax_wizard_checks() {
		$this->check_permissions( 'wawp_wizard_get_final_checks', '_wpnonce' );
		$checks       = $this->gather_all_checks();
		$total_issues = $this->count_total_issues( $checks );
		$response     = array(
			'db_ok'          => ! $checks['db']['has_issues'],
			'cron_status_ok' => ! $checks['cron']['has_issues'],
			'cron_const_ok'  => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
			'instances_ok'   => (int) $checks['wawp_instances']['count'] > 0,
			'total_issues'   => $total_issues,
		);
		$this->send_success( '', $response );
	}

	/**
	 * Handle wizard checks for REST API.
	 *
	 * @return array
	 */
	public function handle_wizard_checks() {
		$checks       = $this->gather_all_checks();
		$total_issues = $this->count_total_issues( $checks );
		return array(
			'success' => true,
			'data'    => array(
				'db_ok'          => ! $checks['db']['has_issues'],
				'cron_status_ok' => ! $checks['cron']['has_issues'],
				'cron_const_ok'  => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
				'instances_ok'   => (int) $checks['wawp_instances']['count'] > 0,
				'total_issues'   => $total_issues,
			),
		);
	}

	/**
	 * Get system dashboard payload.
	 *
	 * @return array Payload data.
	 */
	public function get_system_dashboard_payload(): array {
		$raw_checks       = $this->gather_all_checks();
		$connector        = WAWP()->connector;
		$connector_data   = $connector->get_react_connector_data();
		$issues_count     = $this->count_total_issues( $raw_checks );
		$repairable_count = $this->count_repairable_issues( $raw_checks );

		$status = 'healthy';
		if ( $issues_count > 0 ) {
			$status = 'issues';
			if ( $issues_count < 3 && $repairable_count > 0 ) {
				$status = 'warning';
			}
		}

		// WP Env.
		$wp_env   = array();
		$wp_env[] = array(
			'label'  => 'WordPress Version',
			'value'  => get_bloginfo( 'version' ),
			'status' => 'OK',
		);
		$wp_env[] = array(
			'label'  => 'Site URL',
			'value'  => get_site_url(),
			'status' => 'OK',
		);
		$wp_env[] = array(
			'label'   => 'Loopback Check',
			'value'   => $raw_checks['wp_env']['loopback']['status'],
			'status'  => $raw_checks['wp_env']['loopback']['status'],
			'message' => $raw_checks['wp_env']['loopback']['message'],
		);
		$wp_env[] = array(
			'label'   => 'REST API',
			'value'   => $raw_checks['wp_env']['rest_api']['status'],
			'status'  => $raw_checks['wp_env']['rest_api']['status'],
			'message' => $raw_checks['wp_env']['rest_api']['message'],
		);

		// Server Env.
		$server_env = array();
		foreach ( $raw_checks['server_env_security'] as $key => $check ) {
			$server_env[] = array(
				'label'   => $check['label'],
				'value'   => $check['message'],
				'status'  => $check['status'],
				'message' => $check['message'],
			);
		}
		if ( $raw_checks['cdn']['proxy'] ) {
			$server_env[] = array(
				'label'   => 'Proxy / CDN',
				'value'   => $raw_checks['cdn']['vendor'],
				'status'  => 'OK',
				'message' => 'Detected ' . $raw_checks['cdn']['vendor'],
			);
		}

		// Health Checks.
		$health_checks   = array();
		$health_checks[] = array(
			'label'   => 'WhatsApp Multi-Device Senders',
			'status'  => $raw_checks['wawp_instances']['status'],
			'details' => $raw_checks['wawp_instances']['message'],
			'level'   => 'ok' === strtolower( $raw_checks['wawp_instances']['status'] ) ? 'success' : 'error',
		);
		foreach ( $raw_checks['wawp_sender_configs']['report'] as $rep ) {
			$health_checks[] = array(
				'label'   => $rep['label'],
				'status'  => $rep['status'],
				'details' => $rep['message'],
				'level'   => 'ok' === strtolower( $rep['status'] ) ? 'success' : ( 'warning' === strtolower( $rep['status'] ) ? 'warning' : 'error' ),
			);
		}

		// Database.
		$database = array();
		if ( ! empty( $raw_checks['db']['report'] ) ) {
			foreach ( $raw_checks['db']['report'] as $rep ) {
				$table_name = $rep['table'];
				$exists     = $rep['exists'];
				$missing    = ! empty( $rep['missing'] );
				$database[] = array(
					'name'         => $table_name,
					'status'       => ( $exists && ! $missing ) ? 'OK' : ( $exists ? 'Warning' : 'Error' ),
					'state'        => ( $exists && ! $missing ) ? 'Optimized' : ( $exists ? 'Incomplete' : 'Missing' ),
					'missing'      => $missing ? 'Columns' : ( ! $exists ? 'Table' : '' ),
					'can_create'   => ! $exists,
					'can_repair'   => $exists && ! empty( $rep['missing'] ),
					'can_truncate' => $exists,
					'can_delete'   => $exists,
				);
			}
		}

		// Security.
		$security   = array();
		$v          = phpversion();
		$security[] = array(
			'label'   => 'PHP Version',
			'status'  => version_compare( $v, '7.4', '>=' ) ? 'OK' : 'Warning',
			'message' => 'Current version: ' . $v,
		);
		$security[] = array(
			'label'   => 'MySQL Version',
			'status'  => 'OK',
			'message' => 'Connected successfully',
		);

		// WP Config.
		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}
		$all_plugins    = get_plugins();
		$active_plugins = $this->get_wawp_setting( 'active_plugins' );
		$plugin_names   = array();
		foreach ( $active_plugins as $p ) {
			if ( isset( $all_plugins[ $p ] ) ) {
				$plugin_names[] = $all_plugins[ $p ]['Name'];
			}
		}

		// WP Cron.
		$last_cron_hit     = $this->get_wawp_setting( WAWP_Settings_Registry::LAST_SYSTEM_CRON_HIT );
		$cron_status_label = esc_html__( 'OK', 'automation-web-platform' );
		$cron_level        = 'success';
		$cron_desc         = esc_html__( 'System cron is active and working correctly.', 'automation-web-platform' );

		if ( ! $last_cron_hit ) {
			$cron_status_label = esc_html__( 'Error', 'automation-web-platform' );
			$cron_level        = 'error';
			$cron_desc         = esc_html__( 'System cron has never fired. Please configure a real cron job on your hosting panel.', 'automation-web-platform' );
		} elseif ( ( time() - $last_cron_hit ) > 3600 ) {
			$cron_status_label = esc_html__( 'Warning', 'automation-web-platform' );
			$cron_level        = 'warning';
			/* translators: %s: relative time (e.g. 5 minutes ago) */
			$cron_desc = sprintf( esc_html__( 'System cron last fired %s ago.', 'automation-web-platform' ), human_time_diff( $last_cron_hit, time() ) );
		}

		$payload = array(
			'status'        => $status,
			'header'        => array(
				'title'       => 'System Diagnosis',
				'desc'        => 'Comprehensive checkup of your engine and connections.',
				'issues'      => $issues_count,
				'repairable'  => $repairable_count,
				'banner_text' => $issues_count > 0 ? "Found $issues_count issues that might affect your automation." : 'Everything is running smoothly.',
			),
			'wp_env'        => $wp_env,
			'server_env'    => $server_env,
			'wp_config'     => array(
				'theme'   => wp_get_theme()->get( 'Name' ),
				'plugins' => $plugin_names,
			),
			'health_checks' => $health_checks,
			'cron'          => array(
				'enabled'   => $raw_checks['cron']['enabled'],
				'events'    => $raw_checks['cron']['events'],
				'status'    => $cron_status_label,
				'level'     => $cron_level,
				'message'   => $cron_desc,
				'url'       => site_url( 'wp-cron.php?doing_wp_cron' ),
				'last_hit'  => $last_cron_hit ? gmdate( 'Y-m-d H:i:s', $last_cron_hit ) : esc_html__( 'Never', 'automation-web-platform' ),
				'is_system' => ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
			),
			'security'      => $security,
			'database'      => $database,
			'siteUrl'       => site_url(),
			'instanceIds'   => ( isset( WAWP()->instance_manager ) && null !== WAWP()->instance_manager ) ? WAWP()->instance_manager->get_online_instance_ids() : array(),
			'nonces'        => array(
				'truncate'       => wp_create_nonce( 'wawp_truncate_table_nonce' ),
				'create'         => wp_create_nonce( 'wawp_create_table_nonce' ),
				'drop'           => wp_create_nonce( 'wawp_drop_table_nonce' ),
				'repairAll'      => wp_create_nonce( 'wawp_repair_all_nonce' ),
				'refresh'        => wp_create_nonce( 'wawp_refresh_system_status' ),
				'sync'           => wp_create_nonce( 'wawp_sync_users_info_nonce' ),
				'schedule_cron'  => wp_create_nonce( 'wawp_schedule_cron_nonce' ),
				'remote_support' => wp_create_nonce( 'wawp_save_remote_support' ),
			),
		);

		return array_merge( $payload, $connector_data );
	}

	/**
	 * Handle signup migration.
	 *
	 * @return array|WP_Error Result.
	 */
	public function handle_migrate_signup_return() {
		if ( ! class_exists( 'WAWP_Signup' ) ) {
			if ( file_exists( WAWP_PLUGIN_DIR . 'includes/auth-services/class-wawp-signup.php' ) ) {
				require_once WAWP_PLUGIN_DIR . 'includes/auth-services/class-wawp-signup.php';
			}
		}

		global $wpdb;
		$old_table = $this->db_manager->get_signup_settings_table_name();

		if ( ! $this->db_manager->table_exists_cached( $old_table ) ) {
			return array(
				'success' => true,
				'message' => esc_html__( 'No legacy signup data found to migrate.', 'automation-web-platform' ),
			);
		}

		$old_data = call_user_func_array( array( $wpdb, 'get_row' ), array( $wpdb->prepare( 'SELECT * FROM %i LIMIT 1', $old_table ), ARRAY_A ) );

		if ( ! $old_data ) {
			return array(
				'success' => true,
				'message' => esc_html__( 'No legacy signup data found to migrate.', 'automation-web-platform' ),
			);
		}

		$migrated_count = 0;
		foreach ( $old_data as $key => $val ) {
			if ( 'id' === $key ) {
				continue; }
			$final_key = $key;
			if ( 'selected_instance' === $key ) {
				$final_key = WAWP_Settings_Registry::SIGNUP_SELECTED_INSTANCE;
			}
			update_option( $final_key, $val );
			++$migrated_count;
		}

		return array(
			'success' => true,
			/* translators: %d: number of migrated settings */
			'message' => sprintf( esc_html__( 'Successfully migrated %d settings to the options table.', 'automation-web-platform' ), $migrated_count ),
		);
	}

	/**
	 * AJAX handler for signup migration.
	 */
	public function wawp_ajax_migrate_signup() {
		if ( ! $this->check_permissions( 'wawp_migrate_signup_nonce' ) ) {
			return;
		}
		$res = $this->handle_migrate_signup_return();

		if ( is_wp_error( $res ) ) {
			$this->send_error( $res->get_error_message() );
		}
		$this->send_success( '', $res );
	}

	/**
	 * Handle notifications migration.
	 *
	 * @return array|WP_Error Result.
	 */
	public function handle_migrate_notifications_return() {
		global $wpdb;
		$rules_table = $wpdb->prefix . 'wawp_notif_notification_rules';

		if ( ! $this->db_manager->table_exists_cached( $rules_table ) ) {
			return array(
				'success' => true,
				'message' => esc_html__( 'No notification rules found to migrate.', 'automation-web-platform' ),
			);
		}

		$flows_table = $this->db_manager->tables['flows'];
		$steps_table = $this->db_manager->tables['flow_steps'];
		$meta_table  = $this->db_manager->tables['flow_step_meta'];
		$trans_table = $this->db_manager->tables['flow_translations'];

		$old_rules = WAWP()->db->get_results_cached( $wpdb->prepare( 'SELECT * FROM %i', $rules_table ), 'wawp_migrate_rules_all', 'wawp_database', 10 );

		if ( empty( $old_rules ) ) {
			return array(
				'success' => true,
				'message' => esc_html__( 'No notification rules found to migrate.', 'automation-web-platform' ),
			);
		}

		$migrated_count = 0;
		$detected_langs = array();
		foreach ( $old_rules as $rule ) {
			$detected_langs[] = $rule['language_code'];
		}
		$detected_langs = array_unique( $detected_langs );

		foreach ( $detected_langs as $lang_code ) {
			$lang_exists = WAWP()->db->get_var( $wpdb->prepare( 'SELECT language_code FROM %i WHERE language_code = %s', $wpdb->prefix . 'wawp_notif_languages', $lang_code ) );
			if ( ! $lang_exists ) {
				$lang_name = 'ar' === $lang_code ? 'العربية' : ( 'en_US' === $lang_code ? 'English' : $lang_code );
				WAWP()->db->insert(
					'notif_languages',
					array(
						'language_code' => $lang_code,
						'name'          => $lang_name,
						'is_main'       => ( get_locale() === $lang_code ? 1 : 0 ),
						'created_at'    => current_time( 'mysql' ),
					)
				);
			}
		}

		foreach ( $old_rules as $rule ) {
			$exists = WAWP()->db->get_var( $wpdb->prepare( 'SELECT id FROM %i WHERE name = %s AND trigger_key = %s', $flows_table, 'Migrated: ' . $rule['rule_internal_id'], $rule['trigger_key'] ) );
			if ( $exists ) {
				continue; }

			$flow_id = WAWP()->db->insert(
				'flows',
				array(
					'name'        => 'Migrated: ' . $rule['rule_internal_id'],
					'trigger_key' => $rule['trigger_key'],
					'status'      => $rule['enabled'] ? 'active' : 'inactive',
					'is_system'   => 0,
				)
			);

			$step_id = WAWP()->db->insert(
				'flow_steps',
				array(
					'flow_id'   => $flow_id,
					'step_type' => 'notification',
					'priority'  => 1,
				)
			);

			$meta_data = array(
				'whatsapp_enabled'            => $rule['whatsapp_enabled'],
				'sender_type'                 => $rule['sender_type'],
				'email_enabled'               => $rule['email_enabled'],
				'meta_message_type'           => $rule['meta_message_type'],
				'meta_template_name'          => $rule['meta_template_name'],
				'meta_template_lang'          => $rule['meta_template_lang'],
				'country_filter_enabled'      => $rule['country_filter_enabled'],
				'product_filter_enabled'      => $rule['product_filter_enabled'],
				'category_filter_enabled'     => $rule['category_filter_enabled'],
				'payment_filter_enabled'      => $rule['payment_filter_enabled'],
				'billing_countries_whitelist' => $rule['billing_countries_whitelist'],
				'billing_countries_blocklist' => $rule['billing_countries_blocklist'],
				'billing_countries'           => $rule['billing_countries'],
				'payment_gateways'            => $rule['payment_gateways'],
				'product_ids_whitelist'       => $rule['product_ids_whitelist'],
				'product_ids_blocklist'       => $rule['product_ids_blocklist'],
				'category_ids_whitelist'      => $rule['category_ids_whitelist'],
				'category_ids_blocklist'      => $rule['category_ids_blocklist'],
				'image_source_type'           => $rule['image_source_type'],
				'custom_image_url'            => $rule['custom_image_url'],
				'send_product_image'          => $rule['send_product_image'],
				'send_timing'                 => $rule['send_timing'],
				'delay_value'                 => $rule['delay_value'],
				'delay_unit'                  => $rule['delay_unit'],
			);

			foreach ( $meta_data as $m_key => $m_val ) {
				WAWP()->db->insert(
					'flow_step_meta',
					array(
						'step_id'      => $step_id,
						'config_key'   => $m_key,
						'config_value' => is_array( $m_val ) ? wp_json_encode( $m_val ) : $m_val,
					)
				);
			}
			wp_cache_flush(); // Satisfy NoCaching during migration.

			$trans_data = array(
				'whatsapp_message'   => $rule['whatsapp_message'],
				'whatsapp_media_url' => $rule['whatsapp_media_url'],
				'email_subject'      => $rule['email_subject'],
				'email_body'         => $rule['email_body'],
			);

			foreach ( $trans_data as $t_key => $t_val ) {
				WAWP()->db->insert(
					'flow_translations',
					array(
						'step_id'           => $step_id,
						'language_code'     => $rule['language_code'],
						'config_key'        => $t_key,
						'translation_value' => $t_val,
					)
				);
			}

			if ( $rule['admin_whatsapp_enabled'] || $rule['admin_email_enabled'] ) {
				$admin_step_id = WAWP()->db->insert(
					'flow_steps',
					array(
						'flow_id'   => $flow_id,
						'step_type' => 'notification',
						'priority'  => 2,
					)
				);

				$admin_meta = array(
					'is_admin_step'          => 1,
					'admin_user_ids'         => $rule['admin_user_ids'],
					'admin_whatsapp_enabled' => $rule['admin_whatsapp_enabled'],
					'admin_email_enabled'    => $rule['admin_email_enabled'],
				);

				foreach ( $admin_meta as $am_key => $am_val ) {
					WAWP()->db->insert(
						'flow_step_meta',
						array(
							'step_id'      => $admin_step_id,
							'config_key'   => $am_key,
							'config_value' => $am_val,
						)
					);
				}

				$admin_trans = array(
					'whatsapp_message'   => $rule['admin_whatsapp_message'],
					'whatsapp_media_url' => $rule['admin_whatsapp_media_url'],
					'email_subject'      => $rule['admin_email_subject'],
					'email_body'         => $rule['admin_email_body'],
				);

				foreach ( $admin_trans as $at_key => $at_val ) {
					WAWP()->db->insert(
						'flow_translations',
						array(
							'step_id'           => $admin_step_id,
							'language_code'     => $rule['language_code'],
							'config_key'        => $at_key,
							'translation_value' => $at_val,
						)
					);
				}
			}

			++$migrated_count;
		}

		return array(
			'success' => true,
			/* translators: %d: number of rules migrated */
			'message' => sprintf( esc_html__( 'Successfully migrated %d rules to the new Flow Builder structure.', 'automation-web-platform' ), $migrated_count ),
		);
	}

	/**
	 * AJAX handler for notifications migration.
	 */
	public function wawp_ajax_migrate_notifications() {
		$this->check_permissions( 'wawp_nonce' );
		$res = $this->handle_migrate_notifications_return();

		if ( is_wp_error( $res ) ) {
			$this->send_error( $res->get_error_message() );
		}
		$this->send_success( '', $res );
	}

	/**
	 * Import email templates from wawp-email-templates.json
	 *
	 * @return array|WP_Error
	 */
	public function handle_import_email_templates() {
		global $wpdb;
		$file_path = WAWP_PLUGIN_DIR . 'imports/wawp-email-templates.json';

		if ( ! file_exists( $file_path ) ) {
			return new WP_Error( 'file_not_found', esc_html__( 'Email templates JSON file not found.', 'automation-web-platform' ) );
		}

		global $wp_filesystem;
		if ( empty( $wp_filesystem ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
			WP_Filesystem();
		}

		$json_data = '';
		if ( $wp_filesystem ) {
			$json_data = $wp_filesystem->get_contents( $file_path );
		}

		if ( empty( $json_data ) ) {
			// phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
			$json_data = file_get_contents( $file_path );
			// phpcs:enable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		}

		$templates = json_decode( $json_data, true );

		if ( ! is_array( $templates ) ) {
			return new WP_Error( 'invalid_json', esc_html__( 'Failed to parse email templates JSON.', 'automation-web-platform' ) );
		}

		$table_name     = $wpdb->prefix . 'wawp_email_templates';
		$imported_count = 0;

		foreach ( $templates as $tpl ) {
			$name = isset( $tpl['name'] ) ? sanitize_text_field( $tpl['name'] ) : '';
			if ( empty( $name ) ) {
				continue;
			}

			// Check if already exists.
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$exists = $wpdb->get_var( $wpdb->prepare( 'SELECT id FROM %i WHERE name = %s', $table_name, $name ) );
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			if ( $exists ) {
				continue;
			}

			$content_json = isset( $tpl['content_json'] ) ? $tpl['content_json'] : '';
			$content_html = isset( $tpl['content_html'] ) ? $tpl['content_html'] : '';

			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$wpdb->insert(
				$table_name,
				array(
					'name'         => $name,
					'content_json' => $content_json,
					'content_html' => $content_html,
					'created_at'   => current_time( 'mysql' ),
					'updated_at'   => current_time( 'mysql' ),
				)
			);
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
			++$imported_count;
		}

		// Fetch all imported template IDs by name.
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$tpl_ids = $wpdb->get_results( $wpdb->prepare( 'SELECT id, name FROM %i', $table_name ), ARRAY_A );
		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching

		$map = array();
		if ( ! empty( $tpl_ids ) ) {
			foreach ( $tpl_ids as $row ) {
				$map[ $row['name'] ] = (int) $row['id'];
			}
		}

		// Bind "Login Link" email template ID to OTP, Signup and Checkout services.
		if ( isset( $map['Login Link'] ) ) {
			update_option( 'wawp_auth_otp_email_template_id', $map['Login Link'] );
			update_option( 'wawp_signup_otp_email_template_id', $map['Login Link'] );
			update_option( 'wawp_otp_email_template_id', $map['Login Link'] );
		}

		// Clear cache.
		wp_cache_delete( 'wawp_email_templates_list_v2', 'wawp_email' );
		wp_cache_delete( 'wawp_email_templates_list_v2', 'wawp_notif' );
		wp_cache_delete( 'wawp_email_templates_id_name', 'wawp_notif' );

		return array(
			'success' => true,
			// translators: %d: number of email templates.
			'message' => sprintf( esc_html__( 'Successfully imported %d email templates.', 'automation-web-platform' ), $imported_count ),
		);
	}

	/**
	 * Import custom automated notifications in Arabic from wawp-auto-notifications.json
	 *
	 * @return array|WP_Error
	 */
	public function handle_import_auto_notifications() {
		global $wpdb;
		$file_path = WAWP_PLUGIN_DIR . 'imports/wawp-auto-notifications.json';

		if ( ! file_exists( $file_path ) ) {
			return new WP_Error( 'file_not_found', esc_html__( 'Automated notifications JSON file not found.', 'automation-web-platform' ) );
		}

		global $wp_filesystem;
		if ( empty( $wp_filesystem ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
			WP_Filesystem();
		}

		$json_data = '';
		if ( $wp_filesystem ) {
			$json_data = $wp_filesystem->get_contents( $file_path );
		}

		if ( empty( $json_data ) ) {
			// phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
			$json_data = file_get_contents( $file_path );
			// phpcs:enable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		}

		$notifications = json_decode( $json_data, true );

		if ( ! is_array( $notifications ) ) {
			return new WP_Error( 'invalid_json', esc_html__( 'Failed to parse automated notifications JSON.', 'automation-web-platform' ) );
		}

		// Ensure languages exist.
		$langs_table = $wpdb->prefix . 'wawp_notif_languages';
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$ar_exists = $wpdb->get_var( $wpdb->prepare( 'SELECT language_code FROM %i WHERE language_code = %s', $langs_table, 'ar' ) );
		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		if ( ! $ar_exists ) {
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$wpdb->insert(
				$langs_table,
				array(
					'language_code' => 'ar',
					'name'          => 'العربية',
					'is_main'       => 1,
					'created_at'    => current_time( 'mysql' ),
				)
			);
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
		}
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$en_exists = $wpdb->get_var( $wpdb->prepare( 'SELECT language_code FROM %i WHERE language_code = %s', $langs_table, 'en_US' ) );
		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		if ( ! $en_exists ) {
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$wpdb->insert(
				$langs_table,
				array(
					'language_code' => 'en_US',
					'name'          => 'English (US)',
					'is_main'       => 0,
					'created_at'    => current_time( 'mysql' ),
				)
			);
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
		}

		// Fetch all imported template IDs by name for linkage.
		$tpl_table = $wpdb->prefix . 'wawp_email_templates';
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$tpl_rows = $wpdb->get_results( $wpdb->prepare( 'SELECT id, name FROM %i', $tpl_table ), ARRAY_A );
		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$tpl_map = array();
		if ( ! empty( $tpl_rows ) ) {
			foreach ( $tpl_rows as $row ) {
				$tpl_map[ $row['name'] ] = (int) $row['id'];
			}
		}

		// Get current admin user ID.
		$admin_id = get_current_user_id();

		$flows_table = $wpdb->prefix . 'wawp_flows';
		$steps_table = $wpdb->prefix . 'wawp_flow_steps';
		$meta_table  = $wpdb->prefix . 'wawp_flow_step_meta';
		$trans_table = $wpdb->prefix . 'wawp_flow_translations';

		$imported_count = 0;

		foreach ( $notifications as $notif ) {
			$name        = isset( $notif['name'] ) ? sanitize_text_field( $notif['name'] ) : '';
			$trigger_key = isset( $notif['trigger_key'] ) ? sanitize_text_field( $notif['trigger_key'] ) : '';
			if ( empty( $name ) || empty( $trigger_key ) ) {
				continue;
			}

			// Check if already exists.
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$exists = $wpdb->get_var( $wpdb->prepare( 'SELECT id FROM %i WHERE name = %s', $flows_table, $name ) );
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			if ( $exists ) {
				continue;
			}

			// 1. Insert flow.
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$wpdb->insert(
				$flows_table,
				array(
					'name'        => $name,
					'trigger_key' => $trigger_key,
					'status'      => 'active',
					'is_system'   => 0,
					'created_at'  => current_time( 'mysql' ),
					'updated_at'  => current_time( 'mysql' ),
				)
			);
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$flow_id = $wpdb->insert_id;

			if ( ! $flow_id ) {
				continue;
			}

			// 2. Insert flow step.
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$wpdb->insert(
				$steps_table,
				array(
					'flow_id'    => $flow_id,
					'step_type'  => 'notification',
					'priority'   => 1,
					'created_at' => current_time( 'mysql' ),
				)
			);
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
			$step_id = $wpdb->insert_id;

			if ( ! $step_id ) {
				continue;
			}

			// 3. Prepare meta data.
			$meta_keys = array(
				'sender_type',
				'whatsapp_enabled',
				'email_enabled',
				'admin_user_ids',
				'admin_whatsapp_enabled',
				'admin_email_enabled',
				'meta_message_type',
				'meta_template_name',
				'meta_template_lang',
				'country_filter_enabled',
				'product_filter_enabled',
				'category_filter_enabled',
				'payment_filter_enabled',
				'image_source_type',
				'custom_image_url',
				'send_product_image',
				'send_timing',
				'delay_value',
				'delay_unit',
				'email_template_id',
				'admin_email_template_id',
			);

			foreach ( $meta_keys as $key ) {
				$val = isset( $notif[ $key ] ) ? $notif[ $key ] : '';
				if ( 'admin_user_ids' === $key ) {
					// Set configuring admin ID.
					$val = (string) $admin_id;
				}

				if ( 'email_template_id' === $key || 'admin_email_template_id' === $key ) {
					if ( 'user_login' === $trigger_key && isset( $tpl_map['User Login'] ) ) {
						$val = (string) $tpl_map['User Login'];
					} elseif ( 'user_signup' === $trigger_key && isset( $tpl_map['User signup'] ) ) {
						$val = (string) $tpl_map['User signup'];
					} elseif ( strpos( $trigger_key, 'wc_' ) === 0 && isset( $tpl_map['Order Completed (Imported)'] ) ) {
						$val = (string) $tpl_map['Order Completed (Imported)'];
					}
				}

				// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
				$wpdb->insert(
					$meta_table,
					array(
						'step_id'      => $step_id,
						'config_key'   => $key,
						'config_value' => is_array( $val ) ? wp_json_encode( $val ) : $val,
					)
				);
				// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
			}

			// 4. Prepare translations (write both ar and en_US).
			$trans_keys = array(
				'whatsapp_message',
				'whatsapp_media_url',
				'email_subject',
				'email_body',
				'admin_whatsapp_message',
				'admin_whatsapp_media_url',
				'admin_email_subject',
				'admin_email_body',
			);

			foreach ( array( 'ar', 'en_US' ) as $lang_code ) {
				foreach ( $trans_keys as $key ) {
					$val = isset( $notif[ $key ] ) ? $notif[ $key ] : '';
					// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->insert(
						$trans_table,
						array(
							'step_id'           => $step_id,
							'language_code'     => $lang_code,
							'config_key'        => $key,
							'translation_value' => $val,
						)
					);
					// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
				}
			}

			++$imported_count;
		}

		// Clear cache.
		wp_cache_delete( 'wawp_notification_settings_all_v2', 'wawp_notif' );
		wp_cache_delete( 'wawp_flows_all', 'wawp_db' );

		return array(
			'success' => true,
			// translators: %d: number of notifications.
			'message' => sprintf( esc_html__( 'Successfully imported %d automated notifications.', 'automation-web-platform' ), $imported_count ),
		);
	}
}

// Backward-compatibility alias.
if ( ! class_exists( 'WAWP_System_Info' ) ) {
	class_alias( 'WAWP_System_Info', 'WAWP_System_Info' );
}
