<?php
/**
 * Default Popup Template Class
 *
 * This class handles all functionality related to the default popup template.
 * It extends the Template class and implements the MoITemplate interface.
 *
 * @package miniorange-sms-order-notification-otp-verification/helper/templates
 */

namespace WCSMSOTP\Helper\Templates;

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

use WCSMSOTP\Objects\MoITemplate;
use WCSMSOTP\Helper\MoUtility;
use WCSMSOTP\Objects\Template;
use WCSMSOTP\Traits\Instance;

/**
 * Default Popup Template Class
 *
 * This class handles all functionality related to the default popup template.
 * It extends the Template class and implements the MoITemplate interface.
 */
if ( ! class_exists( 'DefaultPopup' ) ) {
	/**
	 * Default Popup Template Class
	 *
	 * This class handles all functionality related to the default popup template.
	 * It extends the Template class and implements the MoITemplate interface.
	 */
	class DefaultPopup extends Template implements MoITemplate {

		use Instance;

		/**
		 * Constructor.
		 *
		 * Declares variables of the class on initialization.
		 */
		protected function __construct() {
			$this->key                = 'DEFAULT';
			$this->template_editor_id = 'customEmailMsgEditor';
			$this->required_tags      = array_merge( $this->required_tags, array( '{{OTP_FIELD_NAME}}' ) );
			parent::__construct();
		}

		/**
		 * Get default template HTML.
		 *
		 * This function initializes the default HTML of the PopUp Template
		 * to be used by the plugin. This function is called only during
		 * plugin activation or when user resets the templates. In both
		 * cases the plugin initializes the template to the default value
		 * that the plugin ships with.
		 *
		 * @param array $templates The template array to be populated.
		 * @note The html content has been minified for public release.
		 * @return array
		 */
		public function get_defaults( $templates ) {
			if ( ! is_array( $templates ) ) {
				$templates = array();
			}
			$template_url = MOV_WC_URL . 'includes/html/default.min.html';
			if ( ! is_string( $template_url ) || empty( $template_url ) ) {
				return $templates;
			}
			$pop_up_templates_request = wp_remote_get( esc_url_raw( $template_url ) );

			if ( is_wp_error( $pop_up_templates_request ) ) {
				return $templates;
			}
			$response_code = wp_remote_retrieve_response_code( $pop_up_templates_request );
			if ( 200 !== $response_code ) {
				return $templates;
			}
			$template_body = wp_remote_retrieve_body( $pop_up_templates_request );
			if ( ! empty( $template_body ) && is_string( $template_body ) ) {
				$templates[ $this->get_template_key() ] = $template_body;
			}
			return $templates;
		}

		/**
		 * Parse template and replace tags with appropriate content.
		 *
		 * This function is used to parse the template and replace the
		 * tags with the appropriate content. Some of the contents are
		 * not shown if the admin/user is just previewing the pop-up.
		 *
		 * @param string $template The HTML Template.
		 * @param string $message  The message to be shown in the popup.
		 * @param string $otp_type The otp type invoked.
		 * @param bool   $from_both Does user have the option to choose between email and sms verification.
		 * @return string
		 */
		public function parse( $template, $message, $otp_type, $from_both ) {
			$from_both        = (bool) $from_both;
			$from_both_string = $from_both ? 'true' : 'false';
			$otp_type         = sanitize_text_field( $otp_type );
			$message          = sanitize_text_field( $message );

			$required_scripts   = $this->getRequiredFormsSkeleton( $otp_type, $from_both_string );
			$extra_post_data    = $this->preview ? '' : mowc_extra_wc_post_data();
			$extra_form_fields  = $this->getExtraFormFields( $otp_type, $from_both_string );
			$extra_form_fields .= '<input type="hidden" name="option" value="' . esc_attr( 'miniorange-validate-otp-form' ) . '" />';
			$extra_form_fields .= '<input type="hidden" id="mopopup_wpnonce" name="mopopup_wpnonce" value="' . esc_attr( wp_create_nonce( $this->nonce ) ) . '"/>';

			$jquery_url = ! empty( $this->jquery_url ) ? esc_url( $this->jquery_url ) : '';
			$css_url    = defined( 'MOV_WC_CSS_URL' ) ? esc_url( MOV_WC_CSS_URL ) : '';
			$loader_img = ! empty( $this->img ) ? wp_kses_post( $this->img ) : '';

			$template = str_replace( '{{JQUERY}}', $jquery_url, $template );
			$template = str_replace( '{{FORM_ID}}', esc_attr( 'mo_validate_form' ), $template );
			$template = str_replace( '{{GO_BACK_ACTION_CALL}}', esc_js( 'mo_validation_goback();' ), $template );
			$template = str_replace( '{{OTP_MESSAGE_BOX}}', esc_attr( 'mo_message' ), $template );
			$template = str_replace( '{{MO_CSS_URL}}', $css_url, $template );
			$template = str_replace( '{{REQUIRED_FORMS_SCRIPTS}}', wp_kses( $required_scripts, MoUtility::mowc_allow_html_array() ), $template );
			$template = str_replace( '{{HEADER}}', esc_html( mowc_( 'Validate OTP (One Time Passcode)' ) ), $template );
			$template = str_replace( '{{GO_BACK}}', wp_kses_post( mowc_( '&larr; Go Back' ) ), $template );
			$template = str_replace( '{{MESSAGE}}', esc_html( mowc_( $message ) ), $template );
			$template = str_replace( '{{OTP_FIELD_NAME}}', esc_attr( 'mo_otp_token' ), $template );
			$template = str_replace( '{{OTP_FIELD_TITLE}}', esc_html( mowc_( 'Enter Code' ) ), $template );
			$template = str_replace( '{{BUTTON_TEXT}}', esc_html( mowc_( 'Validate OTP' ) ), $template );
			$template = str_replace( '{{REQUIRED_FIELDS}}', $extra_form_fields, $template );
			$template = str_replace( '{{LOADER_IMG}}', $loader_img, $template );
			$template = str_replace( '{{EXTRA_POST_DATA}}', $extra_post_data, $template );
			$template = str_replace( '{{RESEND_OTP}}', esc_html( mowc_( 'Resend OTP' ) ), $template );

			$template .= apply_filters( 'mowc_add_script', $template );
			return wp_kses( $template, MoUtility::mowc_allow_html_array() );
		}

		/**
		 * Get required forms skeleton HTML.
		 *
		 * This function is used to replace the {{REQUIRED_FORMS_SCRIPTS}} in the template
		 * with the appropriate scripts and forms. These forms and scripts are required
		 * for the popup to work.
		 *
		 * @param string $otp_type    The otp type invoked.
		 * @param string $from_both    Does user have the option to choose between email and sms verification.
		 * @return string
		 */
		private function getRequiredFormsSkeleton( $otp_type, $from_both ) {
			if ( ! is_string( $otp_type ) || ! is_string( $from_both ) ) {
				return '';
			}
			$otp_type  = sanitize_text_field( $otp_type );
			$from_both = sanitize_text_field( $from_both );

			$required_fields = '<form name="f" method="post" action="" id="validation_goBack_form">
			<input id="validation_goBack" name="option" value="' . esc_attr( 'validation_goBack' ) . '" type="hidden"/>
		</form>
		<form name="f" method="post" action="" id="verification_resend_otp_form">
			<input id="verification_resend_otp" name="option" value="' . esc_attr( 'verification_resend_otp' ) . '" type="hidden"/>
			<input name="otp_type" value="' . esc_attr( $otp_type ) . '" type="hidden"/>
			<input type="hidden" id="from_both" name="from_both" value="' . esc_attr( $from_both ) . '"/> {{EXTRA_POST_DATA}}
		</form>
		<form name="f" method="post" action="" id="goBack_choice_otp_form">
			<input id="verification_resend_otp" name="option" value="' . esc_attr( 'verification_resend_otp_both' ) . '" type="hidden"/>
			<input type="hidden" id="from_both" name="from_both" value="' . esc_attr( 'true' ) . '">{{EXTRA_POST_DATA}}</form>
		{{SCRIPTS}}';
			$required_fields = str_replace( '{{SCRIPTS}}', $this->getRequiredScripts(), $required_fields );
			return $required_fields;
		}

		/**
		 * Get required scripts HTML.
		 *
		 * This function is used to replace the {{SCRIPTS}} in the template
		 * with the appropriate scripts. These scripts are required
		 * for the popup to work. Scripts are not added if the form is in
		 * preview mode.
		 *
		 * @return string
		 */
		private function getRequiredScripts() {
			$scripts = '<style>.mo_customer_validation-modal{display:block!important}</style>';
			if ( ! $this->preview ) {
				do_action( 'mowc_include_js' );
				wp_register_script( 'moPopUps', MOV_WC_URL . 'includes/js/moDefaultPopUp.js', array( 'jquery' ), MOV_WC_VERSION, false );
				wp_localize_script(
					'moPopUps',
					'moPopUps',
					array()
				);
				wp_print_scripts( 'moPopUps' );
			} else {
				$form_id  = esc_js( 'mo_validate_form' );
				$scripts .= '<script>
				jQuery(document).ready(function($){
					$("#' . $form_id . '").submit(function(e){
						e.preventDefault();
					});
				});
				</script>';
			}
			return $scripts;
		}

		/**
		 * This function is used to load the required script for the catchy template.
		 *
		 * @return void
		 */
		public function getCatchyRequiredScripts() {
			$script_handle = 'mo-catchy-popup';
			if ( ! wp_script_is( $script_handle, 'registered' ) ) {
				wp_register_script(
					$script_handle,
					MOV_WC_URL . 'includes/js/moCatchyPopup.js',
					array(),
					MOV_WC_VERSION,
					false
				);
			}

			// Get OTP length from option.
			$otp_length = get_mo_wc_option( 'otp_length' ) ? get_mo_wc_option( 'otp_length' ) : 5;

			// Localize script with OTP length.
			wp_localize_script(
				$script_handle,
				'moCatchyPopup',
				array(
					'otpLength' => (string) $otp_length,
				)
			);

			// Print script immediately since this is called during HTML output.
			wp_print_scripts( $script_handle );
		}

		/**
		 * Get extra form fields HTML.
		 *
		 * This function is used to add the required input fields to the main otp form.
		 *
		 * @param string $otp_type  The otp type invoked.
		 * @param string $from_both  Does user have the option to choose between email and sms verification.
		 * @return string
		 */
		private function getExtraFormFields( $otp_type, $from_both ) {
			if ( ! is_string( $otp_type ) || ! is_string( $from_both ) ) {
				return '{{EXTRA_POST_DATA}}';
			}
			$otp_type  = sanitize_text_field( $otp_type );
			$from_both = sanitize_text_field( $from_both );

			return ' <input type="hidden" name="otp_type" value="' . esc_attr( $otp_type ) . '">
                 <input type="hidden" id="from_both" name="from_both" value="' . esc_attr( $from_both ) . '">
                 {{EXTRA_POST_DATA}}';
		}
	}

}
