<?php
/**
 * Gateway Functions Class
 *
 * This class handles all functionality related to gateway operations.
 * It implements the IGatewayFunctions interface and delegates calls
 * to the appropriate gateway implementation based on plugin type.
 *
 * @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\Objects\IGatewayFunctions;
use WCSMSOTP\Objects\NotificationSettings;
use WCSMSOTP\Traits\Instance;

/**
 * Gateway Functions Class
 *
 * This class handles all functionality related to gateway operations.
 * It implements the IGatewayFunctions interface and delegates calls
 * to the appropriate gateway implementation based on plugin type.
 */
if ( ! class_exists( 'GatewayFunctions' ) ) {
	/**
	 * Gateway Functions Class
	 *
	 * This class handles all functionality related to gateway operations.
	 * It implements the IGatewayFunctions interface and delegates calls
	 * to the appropriate gateway implementation based on plugin type.
	 */
	class GatewayFunctions implements IGatewayFunctions {

		use Instance;

		/**
		 * Gateway instance.
		 *
		 * This will be the object of the plugin specific functions
		 * from where plugin specific functions can be called out.
		 *
		 * @var IGatewayFunctions
		 */
		private $gateway;

		/**
		 * Plugin type to class map.
		 *
		 * Maps plugin types to their corresponding gateway class names.
		 *
		 * @var array<string, string>
		 */
		private $plugin_type_to_class = array(
			'MiniOrangeGateway'           => 'WCSMSOTP\Helper\MiniOrangeGateway',
			'CustomGatewayWithAddons'     => 'WCSMSOTP\Helper\CustomGatewayWithAddons',
			'CustomGatewayWithoutAddons'  => 'WCSMSOTP\Helper\CustomGatewayWithoutAddons',
			'TwilioGatewayWithAddons'     => 'WCSMSOTP\Helper\TwilioGatewayWithAddons',
			'EnterpriseGatewayWithAddons' => 'WCSMSOTP\Helper\EnterpriseGatewayWithAddons',
		);

		/**
		 * Constructor.
		 *
		 * Initializes the gateway instance based on the plugin type.
		 *
		 * @throws \Exception If the plugin type is invalid or the gateway class cannot be instantiated.
		 */
		public function __construct() {
			if ( ! defined( 'MOV_WC_TYPE' ) || ! is_string( MOV_WC_TYPE ) ) {
				throw new \Exception( 'Plugin type constant MOV_WC_TYPE is not defined or invalid.' );
			}
			$plugin_type = sanitize_text_field( MOV_WC_TYPE );
			if ( ! isset( $this->plugin_type_to_class[ $plugin_type ] ) ) {
				throw new \Exception( 'Invalid plugin type: ' . esc_html( $plugin_type ) );
			}
			$gateway_class = $this->plugin_type_to_class[ $plugin_type ];
			if ( ! class_exists( $gateway_class ) ) {
				throw new \Exception( 'Gateway class does not exist: ' . esc_html( $gateway_class ) );
			}
			$this->gateway = $gateway_class::instance();
			if ( ! ( $this->gateway instanceof IGatewayFunctions ) ) {
				throw new \Exception( 'Gateway instance does not implement IGatewayFunctions interface.' );
			}
		}

		/**
		 * Checks if the current plugin is MiniOrangeGateway Plugin
		 *
		 * @return bool
		 */
		public function is_mg() {
			return $this->gateway->is_mg();
		}

		/**
		 * Calls the Gateway Specific LoaddAddOn function
		 *
		 * @param string $folder LoadAddOns Directory.
		 */
		public function loadAddons( $folder ) {
			$this->gateway->loadAddons( $folder );
		}

		/**
		 * Register add-ons.
		 *
		 * Calls the Gateway specific register_addons function.
		 *
		 * @return void
		 */
		public function register_addons() {
			$this->gateway->register_addons();
		}

		/**
		 * Hourly sync.
		 *
		 * Calls the Gateway specific hourly_sync function.
		 *
		 * @return void
		 */
		public function hourly_sync() {
			$this->gateway->hourly_sync();
		}

		/**
		 * Custom WordPress mail from name.
		 *
		 * Calls the Gateway specific custom_wp_mail_from_name function.
		 *
		 * @param string $original_email_from From address in the email going out.
		 * @return string From email address in the email going out.
		 */
		public function custom_wp_mail_from_name( $original_email_from ) {
			if ( ! is_string( $original_email_from ) ) {
				return '';
			}
			$original_email_from = sanitize_email( $original_email_from );
			return $this->gateway->custom_wp_mail_from_name( $original_email_from );
		}

		/**
		 * Flush cache.
		 *
		 * Calls the Gateway specific flush_cache function.
		 *
		 * @return void
		 */
		public function flush_cache() {
			$this->gateway->flush_cache();
		}

		/**
		 * Validate license key.
		 *
		 * Calls the Gateway specific vlk function.
		 *
		 * @param array $post The POST data array.
		 * @return void
		 */
		public function vlk( $post ) {
			if ( ! is_array( $post ) ) {
				return;
			}
			$this->gateway->vlk( $post );
		}

		/**
		 * Configure SMS template.
		 *
		 * Calls the Gateway specific mo_configure_sms_template function.
		 *
		 * @param array $posted The POST data array.
		 * @return void
		 */
		public function mo_configure_sms_template( $posted ) {
			if ( ! is_array( $posted ) ) {
				return;
			}
			$this->gateway->mo_configure_sms_template( $posted );
		}

		/**
		 * Configure email template.
		 *
		 * Calls the Gateway specific mo_configure_email_template function.
		 *
		 * @param array $posted The POST data array.
		 * @return void
		 */
		public function mo_configure_email_template( $posted ) {
			if ( ! is_array( $posted ) ) {
				return;
			}
			$this->gateway->mo_configure_email_template( $posted );
		}

		/**
		 * Send OTP token.
		 *
		 * Calls the Gateway specific mo_send_otp_token function.
		 *
		 * @param string $auth_type OTP type - EMAIL or SMS.
		 * @param string $email     Email address of the user.
		 * @param string $phone     Phone number of the user.
		 * @return array Response array from the gateway.
		 */
		public function mo_send_otp_token( $auth_type, $email, $phone ) {
			if ( ! is_string( $auth_type ) || ! is_string( $email ) || ! is_string( $phone ) ) {
				return array();
			}
			$auth_type = sanitize_text_field( $auth_type );
			$email     = sanitize_email( $email );
			$phone     = sanitize_text_field( $phone );
			return $this->gateway->mo_send_otp_token( $auth_type, $email, $phone );
		}

		/**
		 * Check license validity.
		 *
		 * Calls the Gateway specific mclv function.
		 *
		 * @return bool True if license is valid, false otherwise.
		 */
		public function mclv() {
			return $this->gateway->mclv();
		}

		/**
		 * Check if gateway is configured.
		 *
		 * Calls the Gateway specific is_gateway_config function.
		 *
		 * @return bool True if gateway is configured, false otherwise.
		 */
		public function is_gateway_config() {
			return $this->gateway->is_gateway_config();
		}

		/**
		 * Validate OTP token.
		 *
		 * Calls the Gateway specific mo_validate_otp_token function.
		 *
		 * @param string $tx_id     Transaction ID from session.
		 * @param string $otp_token OTP token to validate.
		 * @return array Response array from the gateway.
		 */
		public function mowc_validate_otp_token( $tx_id, $otp_token ) {
			if ( ! is_string( $tx_id ) || ! is_string( $otp_token ) ) {
				return array();
			}
			$tx_id     = sanitize_text_field( $tx_id );
			$otp_token = sanitize_text_field( $otp_token );
			return $this->gateway->mowc_validate_otp_token( $tx_id, $otp_token );
		}

		/**
		 * Send notification.
		 *
		 * Calls the Gateway specific mo_send_notif function.
		 *
		 * @param NotificationSettings $settings Notification settings object.
		 * @return string Response from the gateway.
		 */
		public function mo_send_notif( NotificationSettings $settings ) {
			if ( ! is_object( $settings ) || ! ( $settings instanceof NotificationSettings ) ) {
				return '';
			}
			return $this->gateway->mo_send_notif( $settings );
		}

		/**
		 * Get application name.
		 *
		 * Returns the application name from the gateway.
		 *
		 * @return string Application name.
		 */
		public function get_application_name() {
			return $this->gateway->get_application_name();
		}

		/**
		 * Get config page pointers.
		 *
		 * Returns configuration page pointers from the gateway.
		 *
		 * @return array|string Configuration page pointers.
		 */
		public function get_config_page_pointers() {
			return $this->gateway->get_config_page_pointers();
		}
	}
}
