<?php
/**
 * Visual Tour Class
 *
 * This class is to enable Visual Tour and all its functions.
 *
 * @package miniorange-sms-order-notification-otp-verification/helper
 * @since   1.0.0
 */

namespace WCSMSOTP\Helper;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

use WCSMSOTP\Traits\Instance;
use WCSMSOTP\Objects\BaseMessages;

/**
 * Visual Tour Class
 *
 * This class is to enable Visual Tour and all its functions.
 */
if ( ! class_exists( 'MOVisualTour' ) ) {
	/**
	 * Visual Tour Class
	 *
	 * This class is to enable Visual Tour and all its functions.
	 */
	class MOVisualTour {

		use Instance;

		/**
		 * Nonce name.
		 *
		 * @var string
		 */
		protected $nonce;

		/**
		 * Nonce key.
		 *
		 * @var string
		 */
		protected $nonce_key;

		/**
		 * Tour AJAX action name.
		 *
		 * @var string
		 */
		protected $tour_ajax_action;

		/**
		 * Constructor.
		 *
		 * Initializes the visual tour class and sets up hooks.
		 */
		protected function __construct() {
			$this->nonce            = 'mo_admin_actions';
			$this->nonce_key        = 'security';
			$this->tour_ajax_action = 'miniorange-tour-taken';

			if ( function_exists( 'add_action' ) ) {
				add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_visual_tour_script' ) );
				add_action( "wp_ajax_{$this->tour_ajax_action}", array( $this, 'update_tour_taken' ) );
				// Note: Tour should only be available to logged-in users, removing nopriv action.
			}
		}

		/**
		 * Update tour taken status.
		 *
		 * Adds TourTaken variable in Options for the page that has tour completed.
		 *
		 * @return void
		 */
		public function update_tour_taken() {
			// Check user permissions.
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'miniorange-sms-order-notification-otp-verification' ) ) );
				return;
			}

			// Verify nonce.
			if ( ! isset( $_POST['security'] ) || ! is_string( $_POST['security'] ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Invalid security token.', 'miniorange-sms-order-notification-otp-verification' ) ) );
				return;
			}

			$nonce = sanitize_text_field( wp_unslash( $_POST['security'] ) );
			if ( ! wp_verify_nonce( $nonce, $this->nonce ) ) {
				if ( ! class_exists( 'MoUtility' ) || ! class_exists( 'MoMessages' ) || ! class_exists( 'BaseMessages' ) || ! class_exists( 'MoConstants' ) ) {
					wp_send_json_error( array( 'message' => esc_html__( 'Invalid security token.', 'miniorange-sms-order-notification-otp-verification' ) ) );
					return;
				}
				wp_send_json(
					MoUtility::create_json(
						MoMessages::showMessage( BaseMessages::INVALID_OP ),
						MoConstants::ERROR_JSON_TYPE
					)
				);
				return;
			}

			$this->validate_ajax_request();

			// Validate and sanitize input.
			if ( ! isset( $_POST['pageID'] ) || ! is_string( $_POST['pageID'] ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Invalid page ID.', 'miniorange-sms-order-notification-otp-verification' ) ) );
				return;
			}

			if ( ! isset( $_POST['doneTour'] ) || ! is_string( $_POST['doneTour'] ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Invalid tour status.', 'miniorange-sms-order-notification-otp-verification' ) ) );
				return;
			}

			$page_id   = sanitize_key( wp_unslash( $_POST['pageID'] ) );
			$done_tour = sanitize_text_field( wp_unslash( $_POST['doneTour'] ) );

			if ( empty( $page_id ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Page ID cannot be empty.', 'miniorange-sms-order-notification-otp-verification' ) ) );
				return;
			}

			if ( function_exists( 'update_mo_wc_option' ) ) {
				update_mo_wc_option( 'tourTaken_' . $page_id, $done_tour );
				wp_send_json_success( array( 'message' => esc_html__( 'Tour status updated.', 'miniorange-sms-order-notification-otp-verification' ) ) );
			} else {
				wp_send_json_error( array( 'message' => esc_html__( 'Update function not available.', 'miniorange-sms-order-notification-otp-verification' ) ) );
			}
		}

		/**
		 * Validate AJAX request.
		 *
		 * Checks if the request made is a valid ajax request or not.
		 * Only checks the nonce value for now.
		 *
		 * @return void
		 */
		protected function validate_ajax_request() {
			if ( ! isset( $_POST[ $this->nonce_key ] ) || ! is_string( $_POST[ $this->nonce_key ] ) ) {
				if ( ! class_exists( 'MoUtility' ) || ! class_exists( 'MoMessages' ) || ! class_exists( 'MoConstants' ) ) {
					wp_send_json_error( array( 'message' => esc_html__( 'Invalid security token.', 'miniorange-sms-order-notification-otp-verification' ) ) );
					return;
				}
				wp_send_json(
					MoUtility::create_json(
						MoMessages::showMessage( MoMessages::INVALID_OP ),
						MoConstants::ERROR_JSON_TYPE
					)
				);
				return;
			}

			$nonce = sanitize_text_field( wp_unslash( $_POST[ $this->nonce_key ] ) );
			if ( ! wp_verify_nonce( $nonce, $this->nonce ) ) {
				if ( ! class_exists( 'MoUtility' ) || ! class_exists( 'MoMessages' ) || ! class_exists( 'MoConstants' ) ) {
					wp_send_json_error( array( 'message' => esc_html__( 'Invalid security token.', 'miniorange-sms-order-notification-otp-verification' ) ) );
					return;
				}
				wp_send_json(
					MoUtility::create_json(
						MoMessages::showMessage( MoMessages::INVALID_OP ),
						MoConstants::ERROR_JSON_TYPE
					)
				);
			}
		}

		/**
		 * Enqueue visual tour script.
		 *
		 * Function called by Enqueue Hook to register and localize the script and
		 * script variables.
		 *
		 * @return void
		 */
		public function enqueue_visual_tour_script() {
			if ( ! defined( 'MOV_WC_URL' ) || ! defined( 'MOV_WC_VERSION' ) ) {
				return;
			}

			$script_url = esc_url_raw( MOV_WC_URL . 'includes/js/visualTour.js?version=' . MOV_WC_VERSION );
			$style_url  = esc_url_raw( MOV_WC_URL . 'includes/css/mo-card.css' );

			wp_register_script( 'tourScript', $script_url, array( 'jquery' ), MOV_WC_VERSION, false );

			// Sanitize and validate $_GET parameter.
			$page = '';
			// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Reading URL parameters for display, not processing form submission.
			if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) {
				$page = sanitize_key( wp_unslash( $_GET['page'] ) );
			}
			// phpcs:enable WordPress.Security.NonceVerification.Recommended

			// Sanitize $_GET array for currentPage.
			$current_page = array();
			// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Reading URL parameters for display, not processing form submission.
			if ( isset( $_GET ) && is_array( $_GET ) ) {
				$get_data = wp_unslash( $_GET ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Will be sanitized below.
				// phpcs:enable WordPress.Security.NonceVerification.Recommended
				foreach ( $get_data as $key => $value ) {
					$sanitized_key = sanitize_key( $key );
					if ( is_string( $value ) ) {
						$current_page[ $sanitized_key ] = sanitize_text_field( $value );
					} elseif ( is_array( $value ) ) {
						$current_page[ $sanitized_key ] = array_map( 'sanitize_text_field', $value );
					}
				}
			}

			// Get AJAX URL - use admin_url if custom function doesn't exist.
			$ajax_url = admin_url( 'admin-ajax.php' );
			if ( function_exists( 'wp_wc_ajax_url' ) ) {
				$custom_ajax_url = wp_wc_ajax_url();
				if ( is_string( $custom_ajax_url ) && ! empty( $custom_ajax_url ) ) {
					$ajax_url = esc_url_raw( $custom_ajax_url );
				}
			}

			$tour_data  = $this->get_tour_data( $page );
			$tour_taken = '';
			if ( function_exists( 'get_mo_wc_option' ) && ! empty( $page ) ) {
				$tour_taken = get_mo_wc_option( 'tourTaken_' . $page );
				$tour_taken = is_string( $tour_taken ) ? esc_html( $tour_taken ) : '';
			}

			wp_localize_script(
				'tourScript',
				'moTour',
				array(
					'siteURL'     => $ajax_url,
					'currentPage' => $current_page,
					'tnonce'      => wp_create_nonce( $this->nonce ),
					'pageID'      => esc_attr( $page ),
					'tourData'    => $tour_data,
					'tourTaken'   => $tour_taken,
					'ajaxAction'  => esc_attr( $this->tour_ajax_action ),
					'nonceKey'    => wp_create_nonce( $this->nonce_key ),
				)
			);
			wp_enqueue_script( 'tourScript' );
			wp_enqueue_style( 'mo_visual_tour_style', $style_url, '', MOV_WC_VERSION );
		}

		/**
		 * Tour data template.
		 *
		 * Creates a tour card template array.
		 *
		 * @param string $target_e      jQuery Selector for the target element.
		 * @param string $point_to_sale  The direction to point. Place the card on the other side.
		 * @param string $titile_html    Title of the card, can be string, HTML or empty.
		 * @param string $content_html   Description of the card, can be string, HTML or empty.
		 * @param string $button_html    Text on the Next Button.
		 * @param string $img            Image name.
		 * @param int    $size           Size of the card, 0=small, 1=medium, 2=big.
		 * @return array Tour card array.
		 */
		public function tour_template( $target_e, $point_to_sale, $titile_html, $content_html, $button_html, $img, $size ) {
			// Validate and sanitize inputs.
			$target_e      = is_string( $target_e ) ? esc_attr( $target_e ) : '';
			$point_to_sale = is_string( $point_to_sale ) ? esc_attr( $point_to_sale ) : 'left';
			$titile_html   = is_string( $titile_html ) ? wp_kses_post( $titile_html ) : '';
			$content_html  = is_string( $content_html ) ? wp_kses_post( $content_html ) : '';
			$button_html   = is_string( $button_html ) ? esc_html( $button_html ) : '';
			$img           = is_string( $img ) ? sanitize_file_name( $img ) : '';
			$size          = absint( $size );
			if ( $size > 2 ) {
				$size = 2;
			}

			$card_size       = array( 'small', 'medium', 'big' );
			$card_size_value = isset( $card_size[ $size ] ) ? $card_size[ $size ] : 'medium';

			$img_url = '';
			if ( ! empty( $img ) && defined( 'MOV_WC_URL' ) ) {
				$img_path = 'includes/images/tourIcons/' . $img;
				$img_url  = esc_url_raw( MOV_WC_URL . $img_path );
			}

			return array(
				'targetE'     => $target_e,
				'pointToSide' => $point_to_sale,
				'titleHTML'   => $titile_html,
				'contentHTML' => $content_html,
				'buttonText'  => $button_html,
				'img'         => $img_url,
				'cardSize'    => $card_size_value,
			);
		}


		/**
		 * Get tour data.
		 *
		 * This function returns the array containing the tour elements for the current page.
		 *
		 * @param string $page_id Current page/tab.
		 * @return array Tour data for current tab.
		 */
		public function get_tour_data( $page_id ) {
			if ( ! is_string( $page_id ) ) {
				$page_id = '';
			}
			$page_id = sanitize_key( $page_id );

			$tour_data = array(
				'mowcnotifications'   => $this->get_notification_page_pointers(),
				'mowcotpformsettings' => $this->get_form_settings_pointers(),
				'mowcotpsettings'     => $this->get_otp_settings_pointers(),
				'mowcgatewaysettings' => $this->get_config_page_pointers(),
				'mowcwhatsapp'        => $this->get_whatsapp_page_pointers(),
				'mowcaddon'           => $this->get_addon_page_pointers(),
			);

			$mo_tabs = $this->get_tabs_pointers();
			if ( class_exists( 'MoUtility' ) && method_exists( 'MoUtility', 'micr' ) && method_exists( 'MoUtility', 'mclv' ) ) {
				if ( MoUtility::micr() && MoUtility::mclv() ) {
					$tour_data['mowcsettings'] = $this->get_account_page_pointers();
				}
			}

			if ( function_exists( 'get_mo_wc_option' ) && ! get_mo_wc_option( 'tourTaken_mowcsettings' ) ) {
				if ( is_array( $tour_data['mowcnotifications'] ) && is_array( $mo_tabs ) ) {
					$tour_data['mowcnotifications'] = array_merge( $tour_data['mowcnotifications'], $mo_tabs );
				}
			}

			if ( class_exists( 'MoUtility' ) && method_exists( 'MoUtility', 'sanitize_check' ) ) {
				return MoUtility::sanitize_check( $page_id, $tour_data );
			}

			return isset( $tour_data[ $page_id ] ) ? $tour_data[ $page_id ] : array();
		}

		/**
		 * Get tabs pointers.
		 *
		 * This function returns the array containing the tab details for the current page.
		 *
		 * @return array Tab data for current tab.
		 */
		private function get_tabs_pointers() {
			return array(
				$this->tour_template(
					'Notifications',
					'left',
					'<br>',
					'This is Notification settings page. Enable/Disable Notifications for admin, users and vendors',
					'Next',
					'formSettings.svg',
					1
				),
				$this->tour_template(
					'tabID',
					'left',
					'<h1>Form Settings</h1>',
					'Enable OTP Verification on WooCommerce Forms.',
					'Next',
					'formSettings.svg',
					1
				),
				$this->tour_template(
					'GatewaySettings',
					'left',
					'<h1>Gateway Settings</h1>',
					'Click here to check the Custom SMS & Email gateway settings.',
					'Next',
					'emailSmsTemplate.svg',
					1
				),

				$this->tour_template(
					'OTPSettings',
					'left',
					'<h1>Settings</h1>',
					'Click here to check extra OTP settings like Country code dropdown.',
					'Next',
					'settingsTab.svg',
					1
				),

				$this->tour_template(
					'WhatsAppTab',
					'left',
					'<h1>WhatsApp</h1>',
					'Click here to check the WhatsApp OTP & Notification integrations.',
					'Next',
					'settingsTab.svg',
					1
				),

				$this->tour_template(
					'addOnsTab',
					'left',
					'<h1>WhatsApp</h1>',
					'Click here to check the premium Addons.',
					'Next',
					'settingsTab.svg',
					1
				),

				$this->tour_template(
					'account',
					'left',
					'<h1>Start Using the Plugin</h1>',
					'Check your profile details here.<br> Register with us to get started.',
					'Next',
					'addOnSetting.svg',
					1
				),

				$this->tour_template(
					'LicensingPlanButton',
					'left',
					'<h1>Upgrade or Recharge</h1>',
					'Check our cool Pricing Plans for everyone here.',
					'Next',
					'upgrade.svg',
					1
				),

				$this->tour_template(
					'Setup_guide',
					'left',
					'<h1>How to setup plugin?</h1>',
					'<br>Check the plugin setup guide here.',
					'Next',
					'faq.svg',
					1
				),

				$this->tour_template(
					'demoButton',
					'left',
					'<h1>Need Demo?</h1>',
					'<br>Contact us for the demo of the plugin.',
					'Next',
					'faq.svg',
					1
				),

				$this->tour_template(
					'faqButton',
					'left',
					'<h1>Any Questions?</h1>',
					'Check our FAQ page for more information.',
					'Next',
					'faq.svg',
					1
				),

				$this->tour_template(
					'mowc_contact_us',
					'down',
					'<h1>Any Queries?</h1>',
					'Click here to leave us an email.',
					'Next',
					'help.svg',
					1
				),

				$this->tour_template(
					'restart_tour_button',
					'right',
					'<h1>Thank You!</h1>',
					'Click here to Restart the Tour for current tab.',
					'Next',
					'replay.svg',
					1
				),
			);
		}

		/**
		 * Get notification page pointers.
		 *
		 * This function returns the array containing the main page details.
		 *
		 * @return array Tab data for starting page.
		 */
		private function get_notification_page_pointers() {
			return array(
				$this->tour_template(
					'WcNotifSubTab',
					'up',
					'<br>',
					'Enable notifications on WooCommerce order status updates.',
					'Next',
					'messages.svg',
					1
				),

				$this->tour_template(
					'formNotifSubTab',
					'up',
					'<br>',
					'Enable Notifications on submission of popular contact form.',
					'Next',
					'messages.svg',
					1
				),

				$this->tour_template(
					'dokanNotifSubTab',
					'up',
					'<h1>Dokan Notifications</h1>',
					'<br>Enable Dokan Vendor Notifications here.',
					'Next',
					'messages.svg',
					1
				),
				$this->tour_template(
					'wcfmNotifSubTab',
					'up',
					'<h1>WCFM Notifications</h1>',
					'<br>Enable WCFM (WooCommerce Frontend Manager Plugins) Notifications here.',
					'Next',
					'messages.svg',
					1
				),
			);
		}


		/**
		 * Get OTP settings pointers.
		 *
		 * This function returns the array containing the otp settings page details.
		 *
		 * @return array Tab data for otp settings page.
		 */
		private function get_otp_settings_pointers() {
			return array(
				$this->tour_template(
					'mowc_dropdown_settings',
					'right',
					'<h1>Country Code</h1>',
					'Enable country code dropdown.',
					'Next',
					'maps-and-flags.svg',
					1
				),

				$this->tour_template(
					'country_code_settings',
					'up',
					'<h1>Country Code</h1>',
					'Set your default Country Code here.',
					'Next',
					'maps-and-flags.svg',
					1
				),

				$this->tour_template(
					'dropdownEnable',
					'up',
					'<br>',
					'Enable this to show country code drop down in your Form.',
					'Next',
					'drop-down-list.svg',
					1
				),
			);
		}

		/**
		 * Get config page pointers.
		 *
		 * This function returns the gateway page pointers.
		 *
		 * @return array Gateway page pointers.
		 */
		private function get_config_page_pointers() {
			return array(
				$this->tour_template(
					'mowc_gateway_settings',
					'right',
					'<br>',
					'This is a Gateway settings page. Check the gateways supported in our premium plugin.',
					'Next',
					'formSettings.svg',
					1
				),
			);
		}

		/**
		 * Get form settings pointers.
		 *
		 * This function returns the array containing the common message page details.
		 *
		 * @return array Tab data for common message page.
		 */
		private function get_form_settings_pointers() {
			return array(
				$this->tour_template(
					'configured_mo_forms',
					'right',
					'<br>',
					'This is a Form settings page. Enable OTP Verification over Phone or Email on WooCommerce forms.',
					'Next',
					'formSettings.svg',
					1
				),
			);
		}

		/**
		 * Get WhatsApp page pointers.
		 *
		 * This function returns the array containing the design settings page details.
		 *
		 * @return array Tab data for design settings page.
		 */
		private function get_whatsapp_page_pointers() {
			return array(
				$this->tour_template(
					'mowc_whatsapp_pricing',
					'right',
					'<h1>WhatsApp Plans</h1>',
					'Check out our WhatsApp plans and feature list here.',
					'Next',
					'addOns.svg',
					1
				),
			);
		}

		/**
		 * Get addon page pointers.
		 *
		 * This function returns the array containing the addon settings page details.
		 *
		 * @return array Tab data for addon settings tab.
		 */
		private function get_addon_page_pointers() {
			return array(
				$this->tour_template(
					'addOnsTable',
					'right',
					'<h1>AddOns</h1>',
					'Check out our cool AddOns for WooCommerce and Ultimate Member.',
					'Next',
					'addOns.svg',
					1
				),
			);
		}
		/**
		 * Get account page pointers.
		 *
		 * This function returns the array containing the account settings page details.
		 *
		 * @return array Tab data for account settings page.
		 */
		private function get_account_page_pointers() {
			return array(
				$this->tour_template(
					'check_btn',
					'right',
					'<h1>Check Licence</h1>',
					"Don't forget to check your Licence here After Upgrade.",
					'Next',
					'account.svg',
					2
				),
			);
		}
	}
}
