<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

if ( ! class_exists( 'SftcyWordformFormValidation' ) ) {
	class SftcyWordformFormValidation {
		public static $wordform_id                   = null;
		public static $wordform_captcha_session_name = '';
		public static $sc_wordform_validation_data   = array();
		public static $wordform_uploaded_validated_data = [];

		public static $validation_text_message                    = '';
		public static $validation_firstname_message               = '';
		public static $validation_lastname_message                = '';
		public static $validation_number_message                  = '';
		public static $validation_textarea_message                = '';
		public static $validation_richeditor_message             = '';
		public static $validation_range_message                   = '';
		public static $validation_url_message                     = '';
		public static $validation_tel_message                     = '';
		public static $validation_date_message                    = '';
		public static $validation_time_message                    = '';
		public static $validation_datetime_message                = '';
		public static $validation_address_message                 = '';
		public static $validation_maskinput_message               = '';
		public static $validation_rating_message                  = '';
		public static $validation_likert_message                  = '';
		public static $validation_signature_message               = '';
		public static $validation_gdpr_message                    = '';
		public static $validation_radio_message                   = '';
		public static $validation_checkbox_message                = '';
		public static $validation_select_message                  = '';
		public static $validation_email_message                   = '';
		public static $validation_payment_custom_amount_message   = '';
		public static $validation_payment_quantity_message        = '';
		public static $validation_payment_method_message          = '';

		public static $validation_captcha_empty_message           = '';
		public static $validation_captcha_wrong_message           = '';
		public static $validation_captcha_expire_message          = '';

		public static $validation_gcaptcha_error_message          = '';
		public static $validation_hcaptcha_error_message          = '';

		public static $validation_upload_required_message         = '';
		public static $validation_upload_allow_message   		  = '';
		public static $validation_upload_size_message   		  = '';	
		public static $validation_upload_allsize_message	      = '';
		public static $validation_upload_maxinput_message	      = '';

		public static $validation_form_submission_success_message = '';

		private static function wordform_normalize_iso_date( $value = '' ) {
			$value = sanitize_text_field( $value );
			return preg_match( '/^\d{4}-\d{2}-\d{2}$/', $value ) ? $value : '';
		}

		private static function wordform_normalize_iso_datetime( $value = '' ) {
			$value = str_replace( 'T', ' ', sanitize_text_field( $value ) );
			return preg_match( '/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}$/', $value ) ? $value : '';
		}

		private static function wordform_date_within_allowed_range( $value = '', $input_data = array() ) {
			$original_value   = trim( sanitize_text_field( $value ) );
			$normalized_value = self::wordform_normalize_iso_date( $value );
			if ( '' !== $original_value && '' === $normalized_value ) {
				return false;
			}
			if ( '' === $normalized_value ) {
				return true;
			}

			$min_date = isset( $input_data['minDate'] ) ? self::wordform_normalize_iso_date( $input_data['minDate'] ) : '';
			$max_date = isset( $input_data['maxDate'] ) ? self::wordform_normalize_iso_date( $input_data['maxDate'] ) : '';

			if ( isset( $input_data['disablePastDates'] ) && 'true' === (string) $input_data['disablePastDates'] ) {
				$today = current_time( 'Y-m-d' );
				if ( '' === $min_date || $today > $min_date ) {
					$min_date = $today;
				}
			}

			if ( isset( $input_data['disableFutureDates'] ) && 'true' === (string) $input_data['disableFutureDates'] ) {
				$today = current_time( 'Y-m-d' );
				if ( '' === $max_date || $today < $max_date ) {
					$max_date = $today;
				}
			}

			if ( '' !== $min_date && $normalized_value < $min_date ) {
				return false;
			}

			if ( '' !== $max_date && $normalized_value > $max_date ) {
				return false;
			}

			return true;
		}

		private static function wordform_datetime_within_allowed_range( $value = '', $input_data = array() ) {
			$original_value   = trim( sanitize_text_field( $value ) );
			$normalized_value = self::wordform_normalize_iso_datetime( $value );
			if ( '' !== $original_value && '' === $normalized_value ) {
				return false;
			}
			if ( '' === $normalized_value ) {
				return true;
			}

			$min_datetime = isset( $input_data['minDateTime'] ) ? self::wordform_normalize_iso_datetime( $input_data['minDateTime'] ) : '';
			$max_datetime = isset( $input_data['maxDateTime'] ) ? self::wordform_normalize_iso_datetime( $input_data['maxDateTime'] ) : '';

			if ( isset( $input_data['disablePastDates'] ) && 'true' === (string) $input_data['disablePastDates'] ) {
				$current_datetime = current_time( 'Y-m-d H:i' );
				if ( '' === $min_datetime || $current_datetime > $min_datetime ) {
					$min_datetime = $current_datetime;
				}
			}

			if ( isset( $input_data['disableFutureDates'] ) && 'true' === (string) $input_data['disableFutureDates'] ) {
				$current_datetime = current_time( 'Y-m-d H:i' );
				if ( '' === $max_datetime || $current_datetime < $max_datetime ) {
					$max_datetime = $current_datetime;
				}
			}

			if ( '' !== $min_datetime && $normalized_value < $min_datetime ) {
				return false;
			}

			if ( '' !== $max_datetime && $normalized_value > $max_datetime ) {
				return false;
			}

			return true;
		}

		/**
		 * Fetch & set validation messages
		 */
		public static function sc_wordform_set_validation_messages() {
			// check if set validation messages
			if ( isset( self::$wordform_id ) && self::$wordform_id ) {
				$fallback_messages   = SftcyWordformBase::wordform_default_validation_messages();
				$validation_messages = SftcyWordformBase::sc_wordform_get_validation_messages_data_by_formid( self::$wordform_id );

				// Text Validation Message
				self::$validation_text_message = isset( $validation_messages['text-msg'] ) ? sanitize_text_field( $validation_messages['text-msg'] ) : sanitize_text_field( $fallback_messages['text-msg'] );
				// Firstname Validation Message				
				self::$validation_firstname_message = isset( $validation_messages['firstname-msg'] ) ? sanitize_text_field( $validation_messages['firstname-msg'] ) : sanitize_text_field( $fallback_messages['firstname-msg'] );
				// Lastname Validation Message
				self::$validation_lastname_message = isset( $validation_messages['lastname-msg'] ) ? sanitize_text_field( $validation_messages['lastname-msg'] ) : sanitize_text_field( $fallback_messages['lastname-msg'] );
				// Number Validation Message
				self::$validation_number_message = isset( $validation_messages['number-msg'] ) ? sanitize_text_field( $validation_messages['number-msg'] ) : sanitize_text_field( $fallback_messages['number-msg'] );
				// Textarea Validation Message
				self::$validation_textarea_message = isset( $validation_messages['textarea-msg'] ) ? sanitize_text_field( $validation_messages['textarea-msg'] ) : sanitize_text_field( $fallback_messages['textarea-msg'] );
				// Rich Text Editor Validation Message
				self::$validation_richeditor_message = isset( $validation_messages['richeditor-msg'] ) ? sanitize_text_field( $validation_messages['richeditor-msg'] ) : sanitize_text_field( $fallback_messages['richeditor-msg'] );
				// Url Validation Message
				self::$validation_url_message = isset( $validation_messages['url-msg'] ) ? sanitize_text_field( $validation_messages['url-msg'] ) : sanitize_text_field( $fallback_messages['url-msg'] );
				// Range Validation Message
				self::$validation_range_message = isset( $validation_messages['range-msg'] ) ? sanitize_text_field( $validation_messages['range-msg'] ) : sanitize_text_field( $fallback_messages['range-msg'] );
				// Tel Validation Message
				self::$validation_tel_message = isset( $validation_messages['tel-msg'] ) ? sanitize_text_field( $validation_messages['tel-msg'] ) : sanitize_text_field( $fallback_messages['tel-msg'] );
				// Date Validation Message
				self::$validation_date_message = isset( $validation_messages['date-msg'] ) ? sanitize_text_field( $validation_messages['date-msg'] ) : sanitize_text_field( $fallback_messages['date-msg'] );
				// Time Validation Message
				self::$validation_time_message = isset( $validation_messages['time-msg'] ) ? sanitize_text_field( $validation_messages['time-msg'] ) : sanitize_text_field( $fallback_messages['time-msg'] );
				// DateTime Validation Message
				self::$validation_datetime_message = isset( $validation_messages['datetime-msg'] ) ? sanitize_text_field( $validation_messages['datetime-msg'] ) : sanitize_text_field( $fallback_messages['datetime-msg'] );
				// Address Validation Message
				self::$validation_address_message = isset( $validation_messages['address-msg'] ) ? sanitize_text_field( $validation_messages['address-msg'] ) : sanitize_text_field( $fallback_messages['address-msg'] );
				// Mask Input Validation Message
				self::$validation_maskinput_message = isset( $validation_messages['maskinput-msg'] ) ? sanitize_text_field( $validation_messages['maskinput-msg'] ) : sanitize_text_field( $fallback_messages['maskinput-msg'] );
				// Rating Validation Message
				self::$validation_rating_message = isset( $validation_messages['rating-msg'] ) ? sanitize_text_field( $validation_messages['rating-msg'] ) : sanitize_text_field( $fallback_messages['rating-msg'] );
				// Likert Validation Message
				self::$validation_likert_message = isset( $validation_messages['likert-msg'] ) ? sanitize_text_field( $validation_messages['likert-msg'] ) : sanitize_text_field( $fallback_messages['likert-msg'] );
				// Signature Validation Message
				self::$validation_signature_message = isset( $validation_messages['signature-msg'] ) ? sanitize_text_field( $validation_messages['signature-msg'] ) : sanitize_text_field( $fallback_messages['signature-msg'] );
				// GDPR Validation Message
				self::$validation_gdpr_message = isset( $validation_messages['gdpr-msg'] ) ? sanitize_text_field( $validation_messages['gdpr-msg'] ) : sanitize_text_field( $fallback_messages['gdpr-msg'] );
				// Radio Validation Message
				self::$validation_radio_message = isset( $validation_messages['radio-msg'] ) ? sanitize_text_field( $validation_messages['radio-msg'] ) : sanitize_text_field( $fallback_messages['radio-msg'] );
				// Checkbox Validation Message
				self::$validation_checkbox_message = isset( $validation_messages['checkbox-msg'] ) ? sanitize_text_field( $validation_messages['checkbox-msg'] ) : sanitize_text_field( $fallback_messages['checkbox-msg'] );
				// Select Validation Message
				self::$validation_select_message = isset( $validation_messages['select-msg'] ) ? sanitize_text_field( $validation_messages['select-msg'] ) : sanitize_text_field( $fallback_messages['select-msg'] );
				// Email Validation Message
				self::$validation_email_message = isset( $validation_messages['email-msg'] ) ? sanitize_text_field( $validation_messages['email-msg'] ) : sanitize_text_field( $fallback_messages['email-msg'] );
				// Payment Validation Messages
				self::$validation_payment_custom_amount_message = isset( $validation_messages['payment-custom-amount-msg'] ) ? sanitize_text_field( $validation_messages['payment-custom-amount-msg'] ) : sanitize_text_field( $fallback_messages['payment-custom-amount-msg'] );
				self::$validation_payment_quantity_message = isset( $validation_messages['payment-quantity-msg'] ) ? sanitize_text_field( $validation_messages['payment-quantity-msg'] ) : sanitize_text_field( $fallback_messages['payment-quantity-msg'] );
				self::$validation_payment_method_message = isset( $validation_messages['payment-method-msg'] ) ? sanitize_text_field( $validation_messages['payment-method-msg'] ) : sanitize_text_field( $fallback_messages['payment-method-msg'] );
				// Captcha-Empty Validation Message
				self::$validation_captcha_empty_message = isset( $validation_messages['captcha-empty-msg'] ) ? sanitize_text_field( $validation_messages['captcha-empty-msg'] ) : sanitize_text_field( $fallback_messages['captcha-empty-msg'] );
				// Captcha-Wrong Validation Message
				self::$validation_captcha_wrong_message = isset( $validation_messages['captcha-wrong-msg'] ) ? sanitize_text_field( $validation_messages['captcha-wrong-msg'] ) : sanitize_text_field( $fallback_messages['captcha-wrong-msg'] );
				// Captcha-Expire Validation Message
				self::$validation_captcha_expire_message = isset( $validation_messages['captcha-expire-msg'] ) ? sanitize_text_field( $validation_messages['captcha-expire-msg'] ) : sanitize_text_field( $fallback_messages['captcha-expire-msg'] );
				// gCaptcha Validation Error Message
				self::$validation_gcaptcha_error_message = isset( $validation_messages['gcaptcha-error-msg'] ) ? sanitize_text_field( $validation_messages['gcaptcha-error-msg'] ) : sanitize_text_field( $fallback_messages['gcaptcha-error-msg'] );
				self::$validation_hcaptcha_error_message = isset( $validation_messages['hcaptcha-error-msg'] ) ? sanitize_text_field( $validation_messages['hcaptcha-error-msg'] ) : sanitize_text_field( $fallback_messages['hcaptcha-error-msg'] );
				// Upload Validation Message
				self::$validation_upload_required_message = isset( $validation_messages['upload-required-msg'] ) ? sanitize_text_field( $validation_messages['upload-required-msg'] ) : sanitize_text_field( $fallback_messages['upload-required-msg'] );
				self::$validation_upload_allow_message = isset( $validation_messages['upload-allow-msg'] ) ? sanitize_text_field( $validation_messages['upload-allow-msg'] ) : sanitize_text_field( $fallback_messages['upload-allow-msg'] );
				self::$validation_upload_size_message = isset( $validation_messages['upload-size-msg'] ) ? sanitize_text_field( $validation_messages['upload-size-msg'] ) : sanitize_text_field( $fallback_messages['upload-size-msg'] );
				self::$validation_upload_allsize_message = isset( $validation_messages['upload-allsize-msg'] ) ? sanitize_text_field( $validation_messages['upload-allsize-msg'] ) : sanitize_text_field( $fallback_messages['upload-allsize-msg'] );
				self::$validation_upload_maxinput_message = isset( $validation_messages['upload-maxinput-msg'] ) ? sanitize_text_field( $validation_messages['upload-maxinput-msg'] ) : sanitize_text_field( $fallback_messages['upload-maxinput-msg'] );

				// Form Submission Validation Success Message
				self::$validation_form_submission_success_message = isset( $validation_messages['form-submission-success-msg'] ) ? sanitize_text_field( $validation_messages['form-submission-success-msg'] ) : sanitize_text_field( $fallback_messages['form-submission-success-msg'] );
			}
		}
		/**
		 * Text validation
		 */
		public static function text_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Text';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_text_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Text';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Text';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * First Last name validation
		 */
		public static function firstlastname_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'FirstLastname';

					if ( isset( $input_data['values']['first'] )  ) {
						$temp['validationMsgClass'] =  'validation-msg-first-' . $key;
						$temp['labelFirst']         = $input_data['labelFirst']?? '';
					}
					else if ( isset( $input_data['values']['last'] ) ) {
						$temp['validationMsgClass'] = 'validation-msg-last-' . $key;
						$temp['labelLast']          = $input_data['labelLast']?? '';
					}
										
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						if ( isset( $input_data['values']['first'] )  ) {
							$temp['validationMsg']    = ! isset( $input_data['values']['first'] ) || ! array_filter( $input_data['values']['first'] ) ? self::$validation_firstname_message : '';
							$temp['validationStatus'] = ! isset( $input_data['values']['first'] ) || ! array_filter( $input_data['values']['first'] ) ? 'error' : 'success';
						}
						else if ( isset( $input_data['values']['last'] ) ) {
							$temp['validationMsg']    = ! isset( $input_data['values']['last'] ) || ! array_filter( $input_data['values']['last'] ) ? self::$validation_lastname_message : '';
							$temp['validationStatus'] = ! isset( $input_data['values']['last'] ) || ! array_filter( $input_data['values']['last'] ) ? 'error' : 'success';	
						}
					} else {
						$temp['inputType']        = 'FirstLastname';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Firstname';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Number validation
		 */
		public static function number_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Number';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_number_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Number';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Number';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}		

		/**
		 * Textarea validation
		 */
		public static function textarea_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Textarea';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_textarea_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Textarea';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Textarea';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Rich Text Editor validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function richeditor_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'RichEditor';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$temp['required']           = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$field_html                 = isset( $input_data['values'][0] ) ? (string) $input_data['values'][0] : '';
					$field_text                 = trim( wp_strip_all_tags( html_entity_decode( $field_html, ENT_QUOTES, get_bloginfo( 'charset' ) ) ) );

					if ( $temp['required'] && '' === $field_text ) {
						$temp['validationMsg']    = self::$validation_richeditor_message;
						$temp['validationStatus'] = 'error';
					} else {
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			} else {
				$key = array_key_first( $data );
				$temp['inputType']          = 'RichEditor';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Range validation
		 */
		public static function range_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Range';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_number_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Range';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Range';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Url validation
		 */
		public static function url_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Url';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_url_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Url';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Url';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Tel validation
		 */
		public static function tel_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Tel';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_tel_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Tel';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Tel';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Date validation
		 */
		public static function date_validation( $data = array() ) {			
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Date';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					$field_value                = isset( $input_data['values'][0] ) ? sanitize_text_field( $input_data['values'][0] ) : '';
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						if ( ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ) {
							$temp['validationMsg']    = self::$validation_date_message;
							$temp['validationStatus'] = 'error';
						} elseif ( ! self::wordform_date_within_allowed_range( $field_value, $input_data ) ) {
							$temp['validationMsg']    = __( 'Please choose a date within the allowed range.', 'wordform-pro' );
							$temp['validationStatus'] = 'error';
						} else {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';
						}
					} else {
						$temp['inputType']        = 'Date';
						$temp['required']         = false;
						if ( '' !== $field_value && ! self::wordform_date_within_allowed_range( $field_value, $input_data ) ) {
							$temp['validationMsg']    = __( 'Please choose a date within the allowed range.', 'wordform-pro' );
							$temp['validationStatus'] = 'error';
						} else {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';
						}
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Date';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Time validation
		 */
		public static function time_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Time';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_time_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Time';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			} else {
				$key = array_key_first( $data );
				$temp['inputType']          = 'Time';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}


		/**
		 * Radio validation
		 */
		public static function radio_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Radio';
					$is_required       = isset( $input_data['required'] ) && 'true' === $input_data['required'];

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					if ( $is_required ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_radio_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Radio';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Radio';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Checkbox validation
		 */
		public static function checkbox_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Checkbox';
					$is_required       = isset( $input_data['required'] ) && 'true' === $input_data['required'];

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					if ( $is_required ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_checkbox_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Checkbox';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Checkbox';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Select validation
		 */
		public static function select_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Select';
					$is_required       = isset( $input_data['required'] ) && 'true' === $input_data['required'];

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					if ( $is_required ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_select_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Select';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Select';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Email validation
		 */
		public static function email_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Email';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_email_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['inputType']        = 'Email';
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Email';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Address validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function address_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'Address';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$is_required                = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$values                     = isset( $input_data['values'] ) && is_array( $input_data['values'] ) ? $input_data['values'] : array();
					$has_empty_required_part    = false;

					if ( $is_required ) {
						foreach ( array( 'street', 'city', 'state', 'zip', 'country' ) as $address_key ) {
							if ( empty( $values[ $address_key ] ) ) {
								$has_empty_required_part = true;
								break;
							}
						}
					}

					$temp['required']         = $is_required;
					$temp['validationMsg']    = $has_empty_required_part ? self::$validation_address_message : '';
					$temp['validationStatus'] = $has_empty_required_part ? 'error' : 'success';
					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Mask input validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function maskinput_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'MaskInput';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$temp['required']           = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$field_value                = isset( $input_data['values'][0] ) ? sanitize_text_field( $input_data['values'][0] ) : '';
					$pattern                    = isset( $input_data['pattern'] ) ? trim( (string) $input_data['pattern'] ) : '';

					if ( $temp['required'] && '' === trim( $field_value ) ) {
						$temp['validationMsg']    = self::$validation_maskinput_message;
						$temp['validationStatus'] = 'error';
					} elseif ( '' !== $field_value && '' !== $pattern ) {
						$regex_pattern = '/' . str_replace( '/', '\/', $pattern ) . '/';
						if ( false === @preg_match( $regex_pattern, '' ) ) {
							$temp['validationMsg']    = __( 'Invalid mask pattern configured for this field.', 'wordform-pro' );
							$temp['validationStatus'] = 'error';
						} elseif ( 1 !== preg_match( $regex_pattern, $field_value ) ) {
							$temp['validationMsg']    = self::$validation_maskinput_message;
							$temp['validationStatus'] = 'error';
						} else {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';
						}
					} else {
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Rating validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function rating_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'Rating';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$temp['required']           = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$rating_value               = isset( $input_data['values'][0] ) ? absint( $input_data['values'][0] ) : 0;
					$rating_scale               = isset( $input_data['scale'] ) ? max( 3, min( 10, absint( $input_data['scale'] ) ) ) : 5;

					if ( $temp['required'] && ( $rating_value < 1 || $rating_value > $rating_scale ) ) {
						$temp['validationMsg']    = self::$validation_rating_message;
						$temp['validationStatus'] = 'error';
					} else {
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Likert / Matrix validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function likert_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'Likert';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$temp['required']           = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$row_labels                 = isset( $input_data['rowLabels'] ) && is_array( $input_data['rowLabels'] ) ? array_values( array_filter( $input_data['rowLabels'] ) ) : array();
					$column_labels              = isset( $input_data['columnLabels'] ) && is_array( $input_data['columnLabels'] ) ? array_values( array_filter( $input_data['columnLabels'] ) ) : array();
					$selected_values            = isset( $input_data['values'] ) && is_array( $input_data['values'] ) ? $input_data['values'] : array();
					$has_missing_selection      = false;

					if ( $temp['required'] ) {
						foreach ( $row_labels as $row_index => $row_label ) {
							$row_value = isset( $selected_values[ $row_index ] ) ? sanitize_text_field( $selected_values[ $row_index ] ) : '';
							if ( '' === $row_value || ! in_array( $row_value, $column_labels, true ) ) {
								$has_missing_selection = true;
								break;
							}
						}
					}

					$temp['validationMsg']    = $has_missing_selection ? self::$validation_likert_message : '';
					$temp['validationStatus'] = $has_missing_selection ? 'error' : 'success';
					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Signature validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function signature_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'Signature';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$temp['required']           = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$signature_value            = isset( $input_data['values'][0] ) ? trim( (string) $input_data['values'][0] ) : '';

					if ( $temp['required'] && '' === $signature_value ) {
						$temp['validationMsg']    = self::$validation_signature_message;
						$temp['validationStatus'] = 'error';
					} else {
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * GDPR consent validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function gdpr_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'GDPR';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					$temp['required']           = isset( $input_data['required'] ) && 'true' === $input_data['required'];
					$is_checked                 = isset( $input_data['values'][0] ) && 'on' === sanitize_text_field( $input_data['values'][0] );

					if ( $temp['required'] && ! $is_checked ) {
						$temp['validationMsg']    = self::$validation_gdpr_message;
						$temp['validationStatus'] = 'error';
					} else {
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Captcha validation
		 */
		public static function captcha_validation( $data = array() ) {
			if ( array_filter( $data ) ) {				
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'Captcha';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required'] = true;
					}

					// Retrieve server Captcha value
					$captcha_server_value = false;
					if ( isset( $input_data['captcha_session_name'] ) ) {
						$captcha_server_value                = get_transient( $input_data['captcha_session_name'] );
						self::$wordform_captcha_session_name = $input_data['captcha_session_name'];
					}

					// Captcha field empty
					if ( ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ) {
						$temp['validationMsg']    = self::$validation_captcha_empty_message;
						$temp['validationStatus'] = 'error';
					}
					// Captcha expired or not set properly
					elseif ( ! $captcha_server_value ) {
						$temp['validationMsg']    = self::$validation_captcha_expire_message;
						$temp['validationStatus'] = 'error';
					}
					// Captcha entered wrong
					elseif ( isset( $input_data['values'][0] ) && str_replace( ' ', '', $input_data['values'][0] ) !== $captcha_server_value ) {
						$temp['validationMsg']    = self::$validation_captcha_wrong_message;
						$temp['validationStatus'] = 'error';
					}
					// Captcha entered correct
					elseif ( isset( $input_data['values'][0] ) && str_replace( ' ', '', $input_data['values'][0] ) == $captcha_server_value ) {
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}
					// something else happened
					else {
						$temp['validationMsg']    = __( 'Something went wrong with Captcha. Refresh Page.', 'wordform-pro' );
						$temp['validationStatus'] = 'error';
					}

					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$key = array_key_first( $data) ; // get element key number
				$temp['inputType']          = 'Captcha';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

					self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * Google reCaptcha Validation
		 */
		private static function wordform_get_gcaptcha_user_facing_message( $verification_result = array() ) {
			$error_codes = isset( $verification_result['error_codes'] ) && is_array( $verification_result['error_codes'] ) ? $verification_result['error_codes'] : array();
			if ( in_array( 'missing-input-response', $error_codes, true ) ) {
				return __( 'Google reCaptcha could not verify this request. Please try again.', 'wordform-pro' );
			}
			if ( in_array( 'timeout-or-duplicate', $error_codes, true ) ) {
				return __( 'Google reCaptcha expired. Please try again.', 'wordform-pro' );
			}
			if ( in_array( 'invalid-input-response', $error_codes, true ) ) {
				return __( 'Google reCaptcha response was invalid. Please refresh and try again.', 'wordform-pro' );
			}
			if ( in_array( 'missing-input-secret', $error_codes, true ) || in_array( 'invalid-input-secret', $error_codes, true ) ) {
				return __( 'Google reCaptcha is not configured correctly.', 'wordform-pro' );
			}
			if ( in_array( 'bad-request', $error_codes, true ) ) {
				return __( 'Google reCaptcha request was rejected. Please refresh and try again.', 'wordform-pro' );
			}
			if ( in_array( 'http-request-failed', $error_codes, true ) ) {
				return __( 'Google reCaptcha verification request failed. Please try again.', 'wordform-pro' );
			}

			return ! empty( self::$validation_gcaptcha_error_message ) ? self::$validation_gcaptcha_error_message : __( 'Google reCaptcha failed to verify.', 'wordform-pro' );
		}

		/**
		 * Build a clearer user-facing hCaptcha validation message.
		 *
		 * @param array $verification_result
		 * @return string
		 */
		private static function wordform_get_hcaptcha_user_facing_message( $verification_result = array() ) {
			$error_codes = isset( $verification_result['error_codes'] ) && is_array( $verification_result['error_codes'] ) ? $verification_result['error_codes'] : array();
			if ( in_array( 'missing-input-response', $error_codes, true ) ) {
				return __( 'hCaptcha could not verify this request. Please try again.', 'wordform-pro' );
			}
			if ( in_array( 'invalid-input-response', $error_codes, true ) || in_array( 'invalid-or-already-seen-response', $error_codes, true ) ) {
				return __( 'hCaptcha response was invalid or expired. Please try again.', 'wordform-pro' );
			}
			if ( in_array( 'missing-input-secret', $error_codes, true ) || in_array( 'invalid-input-secret', $error_codes, true ) || in_array( 'sitekey-secret-mismatch', $error_codes, true ) ) {
				return __( 'hCaptcha is not configured correctly.', 'wordform-pro' );
			}
			if ( in_array( 'bad-request', $error_codes, true ) ) {
				return __( 'hCaptcha request was rejected. Please refresh and try again.', 'wordform-pro' );
			}
			if ( in_array( 'http-request-failed', $error_codes, true ) ) {
				return __( 'hCaptcha verification request failed. Please try again.', 'wordform-pro' );
			}

			return ! empty( self::$validation_hcaptcha_error_message ) ? self::$validation_hcaptcha_error_message : __( 'hCaptcha verification failed.', 'wordform-pro' );
		}

		public static function gcaptcha_validation( $data = array() ) {
			$gcaptcha_data = SftcyWordformBase::wordform_settings_page_grecaptcha_config();
			if ( empty( $gcaptcha_data['gcaptcha-site-key'] ) || empty( $gcaptcha_data['gcaptcha-secret-key'] ) || empty( $gcaptcha_data['gcaptcha-type'] ) || empty( $gcaptcha_data['gcaptcha-version'] )  ) {
				$temp                     = array();
				$temp['inputType']        = 'gCaptcha';
				$temp['validationStatus'] = 'error';
				$temp['validationMsg']    = __( 'Google reCaptcha integrated but not configured properly.', 'wordform-pro' );
				SftcyWordformSupport::log_event(
					'captcha',
					'error',
					'google_recaptcha_not_configured',
					$temp['validationMsg'],
					array(
						'captcha_type'    => isset( $gcaptcha_data['gcaptcha-type'] ) ? $gcaptcha_data['gcaptcha-type'] : '',
						'captcha_version' => isset( $gcaptcha_data['gcaptcha-version'] ) ? $gcaptcha_data['gcaptcha-version'] : '',
					)
				);
				if ( is_array( $data ) && array_filter( $data ) ) {
					$first_key = array_key_first( $data );
					if ( null !== $first_key ) {
						$temp['validationMsgClass'] = 'validation-msg-' . $first_key;
					}
				}

				self::$sc_wordform_validation_data[] = $temp;
		    }
			elseif ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'gCaptcha';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label'] = isset( $input_data['label'] ) ? $input_data['label'] : 'Google reCaptcha';
					$temp['required'] = true;
					if ( isset( $input_data['token'] ) && ! empty( $input_data['token'] ) ) {
						$data = array( 'response' => $input_data['token'], 'secret' => $gcaptcha_data['gcaptcha-secret-key'] );
						$verification_result = SftcyWordformCaptcha::wordform_verify_gcaptcha_token( $data );
						if ( isset( $verification_result['success'] ) && true === $verification_result['success'] ) {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';	
						}						
						else {
							$temp['validationMsg']    = self::wordform_get_gcaptcha_user_facing_message( $verification_result );
							$temp['validationStatus'] = 'error';	
							SftcyWordformSupport::log_event(
								'captcha',
								'warning',
								'google_recaptcha_verification_failed',
								$temp['validationMsg'],
								array(
									'error_codes' => isset( $verification_result['error_codes'] ) ? $verification_result['error_codes'] : array(),
									'label'       => $temp['label'],
								)
							);
						}
					}
					// When token is empty! reCaptcha challenge not checked | not faced | not filled up
					else {
						$temp['validationStatus'] = 'error';
						$temp['validationMsg'] = __( 'Google reCaptcha could not verify this request. Please try again.', 'wordform-pro' );
						SftcyWordformSupport::log_event(
							'captcha',
							'warning',
							'google_recaptcha_token_missing',
							$temp['validationMsg'],
							array( 'label' => $temp['label'] )
						);
					}
					self::$sc_wordform_validation_data[] = $temp;
				} // foreach
			} else {
				$temp = array();
				$temp['inputType']          = 'gCaptcha';				
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * DateTime validation
		 */
		public static function datetime_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'DateTime';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = $input_data['label'];
					$field_value                = isset( $input_data['values'][0] ) ? sanitize_text_field( $input_data['values'][0] ) : '';
					if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
						$temp['required']         = true;
						if ( ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ) {
							$temp['validationMsg']    = self::$validation_datetime_message;
							$temp['validationStatus'] = 'error';
						} elseif ( ! self::wordform_datetime_within_allowed_range( $field_value, $input_data ) ) {
							$temp['validationMsg']    = __( 'Please choose a datetime within the allowed range.', 'wordform-pro' );
							$temp['validationStatus'] = 'error';
						} else {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';
						}
					} else {
						$temp['inputType']        = 'DateTime';
						$temp['required']         = false;
						if ( '' !== $field_value && ! self::wordform_datetime_within_allowed_range( $field_value, $input_data ) ) {
							$temp['validationMsg']    = __( 'Please choose a datetime within the allowed range.', 'wordform-pro' );
							$temp['validationStatus'] = 'error';
						} else {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';
						}
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			} else {
				$key = array_key_first( $data );
				$temp['inputType']          = 'DateTime';
				$temp['validationMsgClass'] = 'validation-msg-' . $key;
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * hCaptcha validation
		 *
		 * @param array $data
		 * @return void
		 */
		public static function hcaptcha_validation( $data = array() ) {
			$hcaptcha_data = SftcyWordformBase::wordform_settings_page_hcaptcha_config();
			if ( empty( $hcaptcha_data['hcaptcha-site-key'] ) || empty( $hcaptcha_data['hcaptcha-secret-key'] ) ) {
				return;
			}

			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp                       = array();
					$temp['inputType']          = 'hCaptcha';
					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : 'hCaptcha';
					$temp['required']           = true;

					$token = isset( $input_data['token'] ) ? sanitize_text_field( $input_data['token'] ) : '';
					if ( empty( $token ) ) {
						$temp['validationMsg']    = self::$validation_hcaptcha_error_message;
						$temp['validationStatus'] = 'error';
						SftcyWordformSupport::log_event(
							'captcha',
							'warning',
							'hcaptcha_token_missing',
							$temp['validationMsg'],
							array( 'label' => $temp['label'] )
						);
					} else {
						$verify_data = array(
							'response' => $token,
							'secret'   => $hcaptcha_data['hcaptcha-secret-key'],
						);

						$verification_result = SftcyWordformCaptcha::wordform_verify_hcaptcha_token( $verify_data );
						if ( isset( $verification_result['success'] ) && true === $verification_result['success'] ) {
							$temp['validationMsg']    = '';
							$temp['validationStatus'] = 'success';
						} else {
							$temp['validationMsg']    = self::wordform_get_hcaptcha_user_facing_message( $verification_result );
							$temp['validationStatus'] = 'error';
							SftcyWordformSupport::log_event(
								'captcha',
								'warning',
								'hcaptcha_verification_failed',
								$temp['validationMsg'],
								array(
									'error_codes' => isset( $verification_result['error_codes'] ) ? $verification_result['error_codes'] : array(),
									'label'       => $temp['label'],
								)
							);
						}
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Payment custom amount validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function payment_custom_amount_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'PaymentCustomAmount';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					if ( isset( $input_data['required'] ) && 'true' === $input_data['required'] ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_payment_custom_amount_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Payment quantity validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function payment_quantity_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'PaymentQuantity';

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					if ( isset( $input_data['required'] ) && 'true' === $input_data['required'] ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_payment_quantity_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}

		/**
		 * Payment method validation.
		 *
		 * @param array $data
		 * @return void
		 */
		public static function payment_method_validation( $data = array() ) {
			if ( array_filter( $data ) ) {
				foreach ( $data as $key => $input_data ) {
					$temp              = array();
					$temp['inputType'] = 'PaymentMethod';
					$is_required       = isset( $input_data['required'] ) && 'true' === $input_data['required'];

					$temp['validationMsgClass'] = 'validation-msg-' . $key;
					$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';
					if ( $is_required ) {
						$temp['required']         = true;
						$temp['validationMsg']    = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? self::$validation_payment_method_message : '';
						$temp['validationStatus'] = ! isset( $input_data['values'] ) || ! array_filter( $input_data['values'] ) ? 'error' : 'success';
					} else {
						$temp['required']         = false;
						$temp['validationMsg']    = '';
						$temp['validationStatus'] = 'success';
					}

					self::$sc_wordform_validation_data[] = $temp;
				}
			}
		}


		/**
		 * Upload validation
		 */
		public static function upload_validation( $data = array() ) {
			// echo '<pre>';
			// print_r( $data );
			// echo '</pre>';
			// exit();
			if ( array_filter( $data ) ) {		

				// Check all uploaded file size limit
				if ( self::is_all_uploaded_filesize_exceeded_limit( $data ) ) {
					$temp = array();
					$temp['inputType'] = 'Upload';					
					$temp['validationStatus'] = 'error';
					$temp['validationMsg'] = self::$validation_upload_allsize_message;

					self::$sc_wordform_validation_data[] = $temp;
				}
				else {
					// Check Each input file type element - if input file type multiple supported then each input file type may have more than one file uploaded
					foreach ( $data as $key => $input_data ) {
						$temp              = array();
						$temp['inputType'] = 'Upload';

						$temp['validationMsgClass'] = 'validation-msg-' . $key;
						$temp['label']              = isset( $input_data['label'] ) ? $input_data['label'] : '';

						// While file names found | Uploaded data available
						if ( isset( $input_data['name'] ) && array_filter( $input_data['name'] ) ) {
											
							// While uploaded file types not allowed
							if ( ! self::is_wordform_upload_file_types_allowed( $input_data ) ) {						
								$temp['validationMsg']    = self::$validation_upload_allow_message;
								$temp['validationStatus'] = 'error';
							}
							// While uploaded individual file size exceeded limit
							else if ( ! self::is_wordform_upload_each_file_size_allowed( $input_data ) ) {						
								$temp['validationMsg']    = self::$validation_upload_size_message;
								$temp['validationStatus'] = 'error';
							}
							// When uploaded max number of files exceeded limit
							else if ( self::is_all_uploaded_number_of_files_exceeded_limit( $input_data ) ) {
								$temp['validationMsg']    = self::$validation_upload_maxinput_message;
								$temp['validationStatus'] = 'error';	
							}							
					}
					// While file names Not found | Uploaded data Not available
					else if ( ! isset( $input_data['name'] ) || ! array_filter( $input_data['name'] ) ) {
							// If required but not uploaded - error
							if ( isset( $input_data['required'] ) && $input_data['required'] == 'true' ) {
								$temp['required']         = true;
								$temp['validationMsg']    = self::$validation_upload_required_message;
								$temp['validationStatus'] = 'error';
							}
							// Not required 
							else {							
								$temp['required']         = false;
								$temp['validationMsg']    = '';
								$temp['validationStatus'] = 'success';
							}
					}

					self::$sc_wordform_validation_data[] = $temp;
					} // foreach
				}
			} 
			else {
				$temp['inputType']          = 'Upload';				
				$temp['validationMsg']      = __( 'Input element data missing.', 'wordform-pro' );
				$temp['validationStatus']   = 'error';

				self::$sc_wordform_validation_data[] = $temp;
			}
		}

		/**
		 * @param array $data - Individual file uploaded data
		 * Check file types allowed
		 * @return boolean 
		 */
 		public static function is_wordform_upload_file_types_allowed( $input_data ) {
			$error = 0;						
			$uploaded_file_types = [];
			$uploaded_file_extensions = [];
			// Process Allowed File Extensions
			$allowed_file_extensions = isset( $input_data['fileAllowed'] ) ? explode(',', $input_data['fileAllowed'] ) : [];
			// Remove dot (.) from extension
			$allowed_file_extensions = array_map( function( $ext ) { return strtolower( str_replace( '.', '', $ext ) ); }, $allowed_file_extensions );								
			if ( isset( $input_data['name'] ) && is_array( $input_data['name'] ) ) {		
				foreach ( $input_data['name'] as $filename ) {					
					$uploaded_file_types[] = wp_check_filetype( $filename );						
				}
			}
			// Process Uploaded File Extensions
			// $uploaded_file_extensions =  array_unique( array_column( $uploaded_file_types, 'ext' ) );
			$uploaded_file_extensions =  array_unique( array_column( $uploaded_file_types, 'type' ) );
			$uploaded_file_extensions = array_map( 'strtolower', $uploaded_file_extensions );
			// Remove dot (.) from extension
			$uploaded_file_extensions = array_map( function( $ext ) { return str_replace( '.', '', $ext );}, $uploaded_file_extensions );

			// echo '<pre>';
			// print_r( $uploaded_file_extensions );
			// print_r( $allowed_file_extensions );
			// echo '</pre>';

			// Check Image | Word | Pdf Files				
			// Check each uploaded file extension match with allowed file type extensions
			foreach ( $uploaded_file_extensions as $uploaded_ext ) {
				if ( ! in_array( $uploaded_ext, $allowed_file_extensions ) ) {
					$error++;
				}
			}
			return ( $error > 0 ) ? false : true;
		}
               
	/**
	 * Check uploaded individual file size exceeded limit - option data 'upload_each_file_max_size' 
	 * @return boolean
	 */ 
     public static function is_wordform_upload_each_file_size_allowed( $data ) {
		$error = 0;
		$upload_config_data = SftcyWordformBase::wordform_settings_page_upload_config();
		$upload_config_each_file_size_mb  = $upload_config_data['upload_each_file_max_size'];
		// $upload_max_filesize = ini_get('upload_max_filesize');		
		// $limitsize_mb = self::convert_filesize_into_mb( $upload_max_filesize );

		if ( isset( $data['size'] ) ) {
			foreach( $data['size'] as $filesize ) {
				$filesize_mb = number_format( $filesize / ( 1024*1024 ), 2 );									
				// $limitsize_mb = 0 means no limit
				if ( $upload_config_each_file_size_mb > 0 ) {		
					if ( $filesize_mb > $upload_config_each_file_size_mb ) { $error++; }
				}
			}
		}    
		return ( $error > 0 ) ? false : true;
	 }
    /**
	 * Check uploaded all files together with total size of restriction settings exceeded all files size limit - option data 'upload_all_files_max_size'
	 * @return boolean
	 */
    public static function is_all_uploaded_filesize_exceeded_limit( $data ) {
		$upload_config_data = SftcyWordformBase::wordform_settings_page_upload_config();
		//$post_max_size = ini_get('post_max_size');
		//$limitsize_mb = self::convert_filesize_into_mb( $post_max_size );
		$upload_config_all_files_size_mb = $upload_config_data['upload_all_files_max_size'];
		$uploaded_all_file_size_mb = 0;
        foreach( $data as $key => $input_data ) {
             if ( isset( $input_data['size'] ) && $input_data['size'] > 0 ) {
				foreach ( $input_data['size'] as $filesize ) {
					//$filesize_mb = number_format( $filesize / ( 1024*1024 ), 2 );
					$filesize_mb = self::convert_bytes_into_mb( $filesize );
					$uploaded_all_file_size_mb += $filesize_mb;
				}
			 }
		}
		// echo 'Uploaded All Filesize in MB';
		$uploaded_all_file_size_mb = number_format( $uploaded_all_file_size_mb , 2 );
		// var_dump( $uploaded_all_file_size_mb );
		return ( $uploaded_all_file_size_mb > $upload_config_all_files_size_mb ) ? true : false;
	}

    /**
	 * Check number of total uploaded number of files exceeded configured limit - option data 'upload_max_numof_files'
	 *
	 * @param array $data
	 * @return boolean
	 */
    public static function is_all_uploaded_number_of_files_exceeded_limit( $data ) {
		$upload_config_data = SftcyWordformBase::wordform_settings_page_upload_config();
		// $max_file_uploads = ini_get( 'max_file_uploads');
		$upload_config_max_numof_files_allowed = $upload_config_data['upload_max_numof_files'];
		if ( $upload_config_max_numof_files_allowed <= 0 ) { return false; }
		$total_uploaded_files = 0; 
		if ( isset( $data['name'] ) && is_array( $data['name'] )  ) {											
			$total_uploaded_files += count( $data['name'] );
		}
        return ( $total_uploaded_files > $upload_config_max_numof_files_allowed ) ? true : false;
	}

	/**
	 * Check php ini configuration file size
	 * Convert them into MB
	 * @return integer - $limitsize_mb - MB format
	 */
	public static function convert_filesize_into_mb( $size ) {
		$limitsize_mb = 0;
		$filesize_unit = ( $size == 0 || $size == -1 ) ? '' : trim( preg_replace( '/[0-9]/', "", $size ) );
		if ( ! empty( $filesize_unit ) ) {
			// when 'upload_max_filesize' | 'post_max_size' set in MB | GB
             if ( strtolower( $filesize_unit ) == 'm' || strtolower( $filesize_unit ) == 'mb' ) {
                    $limitsize_mb = preg_replace( '/[^0-9]/', '', $size );
			 }
			 // when 'upload_max_filesize' | 'post_max_size' set in GB
             else if ( strtolower( $filesize_unit ) == 'g' || strtolower( $filesize_unit ) == 'gb' ) {
				$limitsize_mb =  preg_replace( '/[^0-9]/', '', $size ) * 1000;
		 	 }
			 // When 'upload_max_filesize' | 'post_max_size' without any size unit appended like 100 - consider value as MB
			 else {
				$limitsize_mb = preg_replace( '/[^0-9]/', '', $size );
			 }
		}
		return $limitsize_mb;		
	}

	/**
	 * Check php ini configuration file size
	 * Convert them ( upload_max_size | post_max_size ) into Bytes
	 * @return integer - Bytes format
	 */
	public static function convert_filesize_into_bytes( $size ) {
		$limitsize_bytes = 0;
		$filesize_unit = ( $size <= 0 ) ? '' : trim( preg_replace( '/[0-9]/', "", $size ) );
		if ( ! empty( $filesize_unit ) ) {
			// when 'upload_max_filesize' | 'post_max_size' set in MB | GB
             if ( strtolower( $filesize_unit ) == 'm' || strtolower( $filesize_unit ) == 'mb' ) {
                    $limitsize_bytes = preg_replace( '/[^0-9]/', '', $size ) * 1024 * 1024;
			 }
			 // when 'upload_max_filesize' | 'post_max_size' set in GB
             else if ( strtolower( $filesize_unit ) == 'g' || strtolower( $filesize_unit ) == 'gb' ) {
				$limitsize_bytes =  preg_replace( '/[^0-9]/', '', $size ) * 1024 * 1024 * 1024;
		 	 }
		}		
		return $limitsize_bytes;		
	}

	/**
	 * @param integer $bytes
	 * Convert file size bytes into MB
	 * @return float MB
	 */
	public static function convert_bytes_into_mb( $bytes = 0 ) {
		if ( $bytes <= 0 ) return 0;
		return  floatval( number_format( $bytes / ( 1024 * 1024 ), 2 ) );
	}


	} // End class
}
