<?php
/**
 * The file that defines the core plugin class
 *
 * @link       https://posimyth.com/
 * @since      6.0.4
 *
 * @package    ThePlus
 */

if ( ! class_exists( 'Tp_Plus_Form' ) ) {

	/**
	 * Handles form submission and email sending functionality.
	 */
	class Tp_Plus_Form {

		/**
		 * Instance of the class.
		 *
		 * @var instance
		 */
		private static $instance;

		/**
		 * Get the singleton instance of the class.
		 * 
		 * @since 6.0.4
		 */
		public static function get_instance() {
			if ( ! isset( self::$instance ) ) {
				self::$instance = new self();
			}
			return self::$instance;
		}

		/**
		 * Constructor to add necessary actions.
		 *
		 * @since 6.0.4
		 */
		public function __construct() {
			add_action( 'wp_ajax_tpaep_form_submission', array( $this, 'tpaep_form_submission' ) );
			add_action( 'wp_ajax_nopriv_tpaep_form_submission', array( $this, 'tpaep_form_submission' ) );
			add_action( 'wp_ajax_tpaep_get_country_code', array( $this, 'tpaep_get_country_code' ) );
			add_action( 'wp_ajax_nopriv_tpaep_get_country_code', array( $this, 'tpaep_get_country_code' ) );
		}
		
		public function tpaep_get_country_code() {
			/**
			 * P-008 fix: Prefer REMOTE_ADDR (set by the web server, not by the
			 * client). HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR are
			 * attacker-controlled request headers and can inject arbitrary
			 * data into the outbound URL. Strictly validate the resulting
			 * value with FILTER_VALIDATE_IP and refuse private / reserved
			 * ranges before using it in wp_remote_get().
			 */
			$ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';

			$valid_ip = filter_var(
				$ip,
				FILTER_VALIDATE_IP,
				array( 'flags' => FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE )
			);

			if ( false === $valid_ip ) {
				// Loopback / private / invalid — fall back to a safe public IP for the lookup.
				$valid_ip = '8.8.8.8';
			}

			$ip       = $valid_ip;
			$response = wp_remote_get( 'https://ipapi.co/' . rawurlencode( $ip ) . '/json/' );
		
			if ( is_wp_error( $response ) ) {
				wp_send_json_error( array(
					'message' => 'Failed to fetch location.'
				) );
			}
		
			$data = json_decode( wp_remote_retrieve_body( $response ), true );
		
			if ( ! empty( $data['country_name'] ) && ! empty( $data['country'] ) ) {
				$country_to_phone_map = array(
					'US' => '+1', 'CA' => '+1', 'UK' => '+44', 'GB' => '+44', 'IN' => '+91', 'CN' => '+86', 
					'JP' => '+81', 'DE' => '+49', 'FR' => '+33', 'IT' => '+39', 'ES' => '+34', 'NL' => '+31',
					'AU' => '+61', 'BR' => '+55', 'RU' => '+7', 'KR' => '+82', 'MX' => '+52', 'ZA' => '+27',
					'AE' => '+971', 'SA' => '+966', 'SG' => '+65', 'HK' => '+852', 'ID' => '+62', 'TH' => '+66',
					'VN' => '+84', 'MY' => '+60', 'PH' => '+63', 'TR' => '+90', 'PL' => '+48', 'SE' => '+46',
					'NO' => '+47', 'DK' => '+45', 'FI' => '+358', 'CH' => '+41', 'AT' => '+43', 'BE' => '+32',
					'IE' => '+353', 'PT' => '+351', 'GR' => '+30', 'CZ' => '+420', 'HU' => '+36', 'RO' => '+40',
					'BG' => '+359', 'HR' => '+385', 'SI' => '+386', 'SK' => '+421', 'LT' => '+370', 'LV' => '+371',
					'EE' => '+372', 'CY' => '+357', 'MT' => '+356', 'LU' => '+352', 'IS' => '+354', 'AD' => '+376',
					'MC' => '+377', 'LI' => '+423', 'SM' => '+378', 'VA' => '+379', 'RS' => '+381', 'ME' => '+382',
					'BA' => '+387', 'MK' => '+389', 'AL' => '+355', 'XK' => '+383', 'IL' => '+972', 'JO' => '+962',
					'LB' => '+961', 'SY' => '+963', 'IQ' => '+964', 'KW' => '+965', 'BH' => '+973', 'QA' => '+974',
					'OM' => '+968', 'YE' => '+967', 'EG' => '+20', 'LY' => '+218', 'TN' => '+216', 'DZ' => '+213',
					'MA' => '+212', 'EH' => '+212', 'SD' => '+249', 'SS' => '+211', 'ET' => '+251', 'ER' => '+291',
					'DJ' => '+253', 'SO' => '+252', 'KE' => '+254', 'TZ' => '+255', 'UG' => '+256', 'BI' => '+257',
					'MZ' => '+258', 'ZW' => '+263', 'ZM' => '+260', 'MW' => '+265', 'LS' => '+266', 'BW' => '+267',
					'NA' => '+264', 'SZ' => '+268', 'MG' => '+261', 'MU' => '+230', 'SC' => '+248', 'KM' => '+269',
					'YT' => '+262', 'RE' => '+262', 'ST' => '+239', 'CV' => '+238', 'GM' => '+220', 'GN' => '+224',
					'GW' => '+245', 'SL' => '+232', 'LR' => '+231', 'CI' => '+225', 'GH' => '+233', 'TG' => '+228',
					'BJ' => '+229', 'NG' => '+234', 'CM' => '+237', 'TD' => '+235', 'CF' => '+236', 'GQ' => '+240',
					'GA' => '+241', 'CG' => '+242', 'CD' => '+243', 'AO' => '+244', 'NE' => '+227', 'BF' => '+226',
					'ML' => '+223', 'SN' => '+221', 'MR' => '+222', 'GM' => '+220', 'GN' => '+224', 'GW' => '+245',
					'SL' => '+232', 'LR' => '+231', 'CI' => '+225', 'GH' => '+233', 'TG' => '+228', 'BJ' => '+229',
					'NG' => '+234', 'CM' => '+237', 'TD' => '+235', 'CF' => '+236', 'GQ' => '+240', 'GA' => '+241',
					'CG' => '+242', 'CD' => '+243', 'AO' => '+244', 'NE' => '+227', 'BF' => '+226', 'ML' => '+223',
					'SN' => '+221', 'MR' => '+222', 'GM' => '+220', 'GN' => '+224', 'GW' => '+245', 'SL' => '+232',
					'LR' => '+231', 'CI' => '+225', 'GH' => '+233', 'TG' => '+228', 'BJ' => '+229', 'NG' => '+234',
					'CM' => '+237', 'TD' => '+235', 'CF' => '+236', 'GQ' => '+240', 'GA' => '+241', 'CG' => '+242',
					'CD' => '+243', 'AO' => '+244', 'NE' => '+227', 'BF' => '+226', 'ML' => '+223', 'SN' => '+221',
					'MR' => '+222', 'GM' => '+220', 'GN' => '+224', 'GW' => '+245', 'SL' => '+232', 'LR' => '+231',
					'CI' => '+225', 'GH' => '+233', 'TG' => '+228', 'BJ' => '+229', 'NG' => '+234', 'CM' => '+237',
					'TD' => '+235', 'CF' => '+236', 'GQ' => '+240', 'GA' => '+241', 'CG' => '+242', 'CD' => '+243',
					'AO' => '+244', 'NE' => '+227', 'BF' => '+226', 'ML' => '+223', 'SN' => '+221', 'MR' => '+222'
				);
				
				$country_code = $data['country'];
				$phone_code = isset( $country_to_phone_map[$country_code] ) ? $country_to_phone_map[$country_code] : '+1';
				
				wp_send_json_success( array(
					'ip'           => $ip,
					'country_code' => $country_code,
					'country_name' => $data['country_name'],
					'phone_code'   => $phone_code,
				) );
			} else {
				wp_send_json_error( array(
					'message' => 'Could not detect country.'
				) );
			}
		
			wp_die();
		}

		/**
		 * Handle form submission and process email sending.
		 *
		 * @since 6.0.4
		 */
		public function tpaep_form_submission() {
			$result = array( 'success' => 0 );

			$integration_data_raw = isset( $_POST['integration'] ) ? sanitize_text_field( wp_unslash( $_POST['integration'] ) ) : '';
			if ( empty( $integration_data_raw ) ) {
				wp_send_json_error( array( 'message' => 'Missing integration data.' ) );
			}

			$integration_data = json_decode( tp_check_decrypt_key( $integration_data_raw ), true );
			if ( ! is_array( $integration_data ) ) {
				wp_send_json_error( array( 'message' => 'Invalid integration data format.' ) );
			}

			$nonce = sanitize_text_field( wp_unslash( $integration_data['nonce']['nonce'] ?? '' ) );
			if ( ! wp_verify_nonce( $nonce, 'tp-form-nonce' ) ) {
				wp_send_json_error( array( 'message' => 'Nonce verification failed.' ) );
			}

			$cf_secret_key     = sanitize_text_field( wp_unslash( $integration_data['nonce']['cf_secret_key'] ?? '' ) );
			$google_secret_key = sanitize_text_field( wp_unslash( $integration_data['nonce']['google_secret_key'] ?? '' ) );

			$form_data_json     = sanitize_text_field( wp_unslash( $_POST['form_data'] ?? '' ) );
			$form_fields_json   = sanitize_text_field( wp_unslash( $_POST['form_fields'] ?? '' ) );
			$form_security_json = sanitize_text_field( wp_unslash( $_POST['form_security'] ?? '' ) );

			$form_data = json_decode( $form_data_json, true );
			if ( ! is_array( $form_data ) ) {
				$form_data = array();
			}

			$form_fields = json_decode( $form_fields_json, true );
			if ( ! is_array( $form_fields ) ) {
				$form_fields = array();
			}

			$form_security = json_decode( $form_security_json, true );
			if ( ! is_array( $form_fields ) ) {
				$form_fields = array();
			}

			$recaptcha_response = sanitize_text_field( wp_unslash( $form_security['g-recaptcha-response'] ?? '' ) );
			$turnstile_response = sanitize_text_field( wp_unslash( $form_security['cf-turnstile-response'] ?? '' ) );

			if ( ! empty( $recaptcha_response ) ) {
				if ( ! empty( $google_secret_key ) ) {
					$response = wp_remote_post(
						'https://www.google.com/recaptcha/api/siteverify',
						array(
							'body' => array(
								'secret'   => $google_secret_key,
								'response' => $recaptcha_response,
							),
						)
					);

					$recaptcha_result = json_decode( wp_remote_retrieve_body( $response ), true );

					if ( empty( $recaptcha_result['success'] ) ) {
						wp_send_json_error( array( 'message' => 'reCAPTCHA failed. Please refresh and try again.' ) );
					}
				}
			}

			if ( ! empty( $cf_secret_key ) && ! empty( $turnstile_response ) ) {
				$response = wp_remote_post(
					'https://challenges.cloudflare.com/turnstile/v0/siteverify',
					array(
						'body' => array(
							'secret'   => $cf_secret_key,
							'response' => $turnstile_response,
							'remoteip' => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '',
						),
						'timeout' => 15,
					)
				);

				$turnstile_result = json_decode( wp_remote_retrieve_body( $response ), true );
			
				if ( empty( $turnstile_result['success'] ) || $turnstile_result['success'] !== true ) {
					wp_send_json_error( array( 'message' => 'Cloudflare Turnstile verification failed. Please try again.' ) );
				}
			}

			// if ( empty( $form_fields ) || ! is_array( $form_fields ) ) {
			// 	wp_send_json_error( array( 'message' => 'Invalid form fields data.' ) );
			// }

			foreach ( $form_data as $key => $value ) {
				$form_fields[ $key ] = is_array( $value ) ? implode( ', ', $value ) : sanitize_text_field( $value );
			}

			foreach ( $form_data as $key => $value ) {
				if ( false !== strpos( $key, 'required' ) && 'yes' === $value ) {
					$field_name = str_replace( '_required', '', $key );
					if ( empty( $form_data[ $field_name ] ) ) {
						wp_send_json_error( array( 'message' => ucfirst( $field_name ) . ' is required.' ) );
					}
				}
			}

			$integration_results = array(
				'email_sent'           => false,
				'redirect_sent'        => null,
				'slack_sent'           => false,
				'webhook_sent'         => false,
				'discord_sent'         => false,
				'active_campaign_sent' => false,
				'convertkit_sent'      => false,
				'getresponse_sent'     => false,
				'mailchimp_sent'       => false,
				'brevo_sent'           => false,
				'mailerlite_sent'      => false,
				'drip_sent'            => false,
			);

			$map = array(
				'email'              => 'tpaep_email_integration',
				'redirect'           => 'tpaep_redirection_integration',
				'slack'              => 'tpaep_slack_integration',
				'webhook'            => 'tpaep_webhook_integration',
				'discord'            => 'tpaep_discord_integration',
				'active_campaign'    => 'tpaep_activecampaign_integration',
				'convertkit'         => 'tpaep_convertkit_integration',
				'get_response'       => 'tpaep_getresponse_integration',
				'mailchimp'          => 'tpaep_mailchimp_integration',
				'brevo'              => 'tpaep_brevo_integration',
				'mailerlite'         => 'tpaep_mailerlite_integration',
				'drip'               => 'tpaep_drip_integration',
				'auto_respond_email' => 'tpaep_autorespond_integration',
				'database_entry'     => 'tpaep_database_entry_integration',
			);

			foreach ( $map as $key => $method ) {
				if ( isset( $integration_data[ $key ] ) && is_array( $integration_data[ $key ] ) && method_exists( $this, $method ) ) {
					if ( in_array( $key, array( 'email', 'auto_respond_email' ), true ) ) {
						$args = array( $integration_data[ $key ], $form_data, $form_fields );
					} else {
						$args = array( $integration_data[ $key ], $form_data );
					}

					$result = call_user_func_array( array( $this, $method ), $args );
					$integration_results[ "{$key}_sent" ] = $result;
				}
			}

			foreach ( $integration_data as $integration_key => $integration_value ) {
				if ( 'nonce' === $integration_key ) {
					continue;
				}
				$sent_key = $integration_key . '_sent';
				if ( empty( $integration_results[ $sent_key ] ) ) {
					wp_send_json_error(
						array(
							'message'            => ucfirst( str_replace( '_', ' ', $integration_key ) ) . ' integration failed.',
							'failed_integration' => $integration_key,
							'status'             => $integration_results,
						)
					);
				}
			}

			wp_send_json_success(
				array(
					'message' => 'Form submitted successfully.',
					'data'    => array(
						'email_sent'  => $integration_results['email_sent'],
						'redirection' => $integration_results['redirect_sent'],
					),
				) + $integration_results
			);
		}

		/**
		 * Handles email integration by preparing and sending the email.
		 *
		 * @param array $email_data  Email data including subject, message, etc.
		 * @param array $form_data   Decoded form data from submission.
		 * @param array $form_fields Form fields from the submitted form.
		 * @return bool True if email was sent, false otherwise.
		 */
		private function tpaep_email_integration( $email_data, $form_data, $form_fields ) {
			$email_subject = ! empty( $email_data['email_subject'] ) ? sanitize_text_field( $email_data['email_subject'] ) : '';
			if ( empty( $email_subject ) ) {
				return false;
			}

			$email_settings = $this->tpaep_prepare_email_settings( $email_data, $form_data, $form_fields );
			return $this->tpaep_send_email( $email_settings );
		}

		/**
		 * Handles autoresponder email integration.
		 *
		 * @param array $email_data  Email data including AR subject, message, etc.
		 * @param array $form_data   Decoded form data from submission.
		 * @param array $form_fields Form fields from the submitted form.
		 * @return bool True if email was sent, false otherwise.
		 */
		private function tpaep_autorespond_integration( $email_data, $form_data, $form_fields ) {
			$email_subject = ! empty( $email_data['ar_email_subject'] ) ? sanitize_text_field( $email_data['ar_email_subject'] ) : '';
			if ( empty( $email_subject ) ) {
				return false;
			}

			$email_settings = $this->tpaep_prepare_are_settings( $email_data, $form_data, $form_fields );
			return $this->tpaep_send_email( $email_settings );
		}

		/**
		 * Prepares redirection settings based on provided data.
		 *
		 * @param array $redirect_data Redirection configuration data.
		 * @return array Redirection settings including URL and external flag.
		 */
		private function tpaep_redirection_integration( $redirect_data ) {
			$redirection = $redirect_data['redirection'] ?? array();
			$url         = isset( $redirection['url'] ) ? esc_url_raw( $redirection['url'] ) : '';
			$is_external = isset( $redirection['is_external'] ) ? (bool) $redirection['is_external'] : false;

			return array(
				'url'         => $url,
				'is_external' => $is_external,
			);
		}

		/**
		 * Saves form submission data to the database.
		 *
		 * @param array $database_data Form meta information.
		 * @param array $form_fields   Submitted form fields.
		 * @return mixed Result of form submission save operation.
		 */
		private function tpaep_database_entry_integration( $database_data, $form_fields ) {
			$form_id         = sanitize_text_field( $database_data['form_id'] ?? '' );
			$form_name       = sanitize_text_field( $database_data['form_name'] ?? '' );
			$post_id         = sanitize_text_field( $database_data['post_id'] ?? '' );
			$element_id      = sanitize_text_field( $database_data['element_id'] ?? '' );
			$current_user_id = get_current_user_id();
			$user_ip         = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
			$user_agent      = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';

			$submission_data = array(
				'form_id'     => $form_id,
				'form_name'   => $form_name,
				'form_fields' => $form_fields,
				'post_id'     => $post_id,
				'element_id'  => $element_id,
				'user_id'     => $current_user_id,
				'user_ip'     => $user_ip,
				'user_agent'  => $user_agent,
			);

			return $this->tpaep_save_form_submission( $submission_data );
		}

		/**
		 * Stores the form submission into the database.
		 *
		 * @param array $data Submission data to be saved.
		 * @return mixed Result of the save operation.
		 */
		private function tpaep_save_form_submission( $data ) {
			require_once ABSPATH . 'wp-admin/includes/upgrade.php';
			global $wpdb;
		
			$submissions_table = $wpdb->prefix . 'tpaep_formsmeta';
			$values_table      = $wpdb->prefix . 'tpaep_forms';
			$charset_collate   = $wpdb->get_charset_collate();
		
			// Create tables if not exist.
			$sql1 = "CREATE TABLE IF NOT EXISTS $submissions_table (
				id BIGINT(20) NOT NULL AUTO_INCREMENT,
				form_id VARCHAR(255) NOT NULL,
				form_name VARCHAR(255) NOT NULL,
				post_id BIGINT(20) DEFAULT 0 NOT NULL,
				element_id VARCHAR(255) DEFAULT '' NOT NULL,
				user_id BIGINT(20) DEFAULT 0 NOT NULL,
				user_ip VARCHAR(100) DEFAULT '' NOT NULL,
				user_agent TEXT DEFAULT '' NOT NULL,
				submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
				PRIMARY KEY (id)
			) $charset_collate;";
		
			$sql2 = "CREATE TABLE IF NOT EXISTS $values_table (
				id BIGINT(20) NOT NULL AUTO_INCREMENT,
				form_id BIGINT(20) NOT NULL,
				`key` VARCHAR(255) NOT NULL,
				`value` LONGTEXT NOT NULL,
				PRIMARY KEY (id),
				FOREIGN KEY (form_id) REFERENCES $submissions_table(id) ON DELETE CASCADE
			) $charset_collate;";
		
			dbDelta( $sql1 );
			dbDelta( $sql2 );
		
			$wpdb->insert(
				$submissions_table,
				array(
					'form_id'    => sanitize_text_field( $data['form_id'] ?? '' ),
					'form_name'  => sanitize_text_field( $data['form_name'] ?? '' ),
					'post_id'    => absint( $data['post_id'] ?? 0 ),
					'element_id' => sanitize_text_field( $data['element_id'] ?? '' ),
					'user_id'    => absint( $data['user_id'] ?? 0 ),
					'user_ip'    => sanitize_text_field( $data['user_ip'] ?? '' ),
					'user_agent' => sanitize_textarea_field( $data['user_agent'] ?? '' ),
				),
				array( '%s', '%s', '%d', '%s', '%d', '%s', '%s' )
			);
		
			$submission_id = $wpdb->insert_id;
		
			if ( ! $submission_id ) {
				return false;
			}
		
			$form_fields = $data['form_fields'] ?? array();
			foreach ( $form_fields as $key => $value ) {
				if ( is_array( $value ) ) {
					$value = maybe_serialize( $value );
				}
				$wpdb->insert(
					$values_table,
					array(
						'form_id' => $submission_id,
						'key'     => sanitize_text_field( $key ),
						'value'   => maybe_serialize( $value ),
					),
					array( '%d', '%s', '%s' )
				);
			}
		
			$post_title = 'Submission #' . $submission_id;

			// Try to get email from form fields.
			if ( ! empty( $form_fields ) ) {
				foreach ( $form_fields as $key => $value ) {
					if ( stripos( $key, 'email' ) !== false && is_string( $value ) && is_email( $value ) ) {
						$post_title = sanitize_text_field( $value );
						break;
					}
				}
			}

			$post_id_created = wp_insert_post(
				array(
					'post_title'  => $post_title,
					'post_type'   => 'tpaep_submission',
					'post_status' => 'publish',
				)
			);
		
			if ( $post_id_created ) {
				update_post_meta( $post_id_created, 'tpaep_submission_id', $submission_id );
			}
		
			return true;
		}
		
		/**
		 * Sends a Slack message using the provided form submission data.
		 *
		 * @param array $slack_data  Slack integration data including webhook URL and message template.
		 * @param array $form_fields Submitted form fields to include in the Slack message.
		 * @return bool
		 */
		public function tpaep_slack_integration( $slack_data, $form_fields ) {
			$slack_token   = sanitize_textarea_field( $slack_data['slack_token'] ?? '' );
			$slack_channel = sanitize_text_field( $slack_data['slack_channel_name'] ?? '' );

			if ( empty( $slack_token ) || empty( $slack_channel ) ) {
				return false;
			}

			$formatted_message = "*Form Submission*\n";
			$formatted_message .= "----------------------\n";
			$formatted_message .= "*Submission Data*\n";
			foreach ( $form_fields as $key => $value ) {
				if ( is_array( $value ) ) {
					$value = implode( ', ', $value );
				}
				$formatted_message .= "*{$key}:* " . ( $value ? $value : 'N/A' ) . "\n";
			}
			
			$formatted_message .= "\n*Meta Data*\n";
			$formatted_message .= $this->tpaep_get_form_metadata_text();

			$slack_message = array(
				'channel' => $slack_channel,
				'text'    => $formatted_message,
			);

			$slack_headers = array(
				'Authorization' => 'Bearer ' . $slack_token,
				'Content-Type'  => 'application/json',
			);

			$response = wp_remote_post(
				'https://slack.com/api/chat.postMessage',
				array(
					'method'  => 'POST',
					'body'    => wp_json_encode( $slack_message ),
					'headers' => $slack_headers,
				)
			);

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$body         = wp_remote_retrieve_body( $response );
			$decoded_body = json_decode( $body, true );

			return ( isset( $decoded_body['ok'] ) && $decoded_body['ok'] );
		}

		/**
		 * Sends form submission data to a custom webhook endpoint.
		 *
		 * @param array $webhook_data Webhook configuration data including the endpoint URL and settings.
		 * @param array $form_fields  Submitted form fields to send to the webhook.
		 * @return bool
		 */
		public function tpaep_webhook_integration( $webhook_data, $form_fields ) {
			$webhook_url = isset( $webhook_data['webhook_url'] ) ? esc_url_raw( $webhook_data['webhook_url'] ) : '';

			if ( empty( $webhook_url ) || ! filter_var( $webhook_url, FILTER_VALIDATE_URL ) ) {
				return false;
			}

			/**
			 * P-009 fix: Block SSRF against private / reserved IP ranges
			 * (loopback, RFC1918, link-local 169.254/16 AWS metadata, etc.).
			 * Without this, a Contributor+ who can configure a form widget can
			 * make the server fetch internal endpoints on every form submission.
			 */
			$parsed_host = wp_parse_url( $webhook_url, PHP_URL_HOST );
			if ( empty( $parsed_host ) ) {
				return false;
			}

			$scheme = strtolower( (string) wp_parse_url( $webhook_url, PHP_URL_SCHEME ) );
			if ( ! in_array( $scheme, array( 'http', 'https' ), true ) ) {
				return false;
			}

			$resolved_ip = gethostbyname( $parsed_host );
			// gethostbyname() returns the original hostname on failure.
			if ( $resolved_ip === $parsed_host && ! filter_var( $parsed_host, FILTER_VALIDATE_IP ) ) {
				return false;
			}

			if ( ! filter_var(
				$resolved_ip,
				FILTER_VALIDATE_IP,
				array( 'flags' => FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE )
			) ) {
				return false;
			}
		
			$http_method = isset( $webhook_data['http_method'] ) ? strtoupper( $webhook_data['http_method'] ) : 'POST';
		
			$formatted_message = "Form Submission\n";
			$formatted_message .= "----------------------\n";
			$formatted_message .= "Submission Data\n";
			foreach ( $form_fields as $key => $value ) {
				if ( is_array( $value ) ) {
					$value = implode( ', ', $value );
				}
				$formatted_message .= ucfirst( $key ) . ': ' . $value . "\n";
			}
			
			$formatted_message .= "\nMeta Data\n";
			$formatted_message .= $this->tpaep_get_form_metadata_text();
	
			if ( strpos( $webhook_url, 'discord.com/api/webhooks' ) !== false || strpos( $webhook_url, 'discordapp.com/api/webhooks' ) !== false ) {
				$discord_message = "**Form Submission**\n";
				$discord_message .= "----------------------\n";
				$discord_message .= "**Submission Data**\n";
				foreach ( $form_fields as $key => $value ) {
					if ( ! empty( $value ) ) {
						$pretty_key = ucwords( str_replace( '_', ' ', $key ) );
						$discord_message .= "**{$pretty_key}:** " . $value . "\n";
					}
				}
				
				if ( trim( $discord_message ) === "**Form Submission**\n----------------------\n**Submission Data**\n" ) {
					$discord_message .= "**Email:** " . ( $form_fields['email'] ?? 'No email provided' ) . "\n";
				}
				
				$discord_message .= "\n**Meta Data**\n";
				$discord_message .= $this->tpaep_get_form_metadata_text();
				
				$payload = array(
					'content'  => $discord_message,
					'username' => 'Form Bot',
				);
			} elseif ( strpos( $webhook_url, 'hooks.slack.com' ) !== false ) {
				$slack_message = "*Form Submission*\n";
				$slack_message .= "----------------------\n";
				$slack_message .= "*Submission Data*\n";
				foreach ( $form_fields as $key => $value ) {
					if ( is_array( $value ) ) {
						$value = implode( ', ', $value );
					}
					$slack_message .= "*{$key}:* " . ( $value ? $value : 'N/A' ) . "\n";
				}
				$slack_message .= "\n*Meta Data*\n";
				$slack_message .= $this->tpaep_get_form_metadata_text();
				
				$payload = array( 'text' => $slack_message );
			} else {
				$payload = array(
					'message' => $formatted_message,
					'fields'  => $form_fields,
				);
			}
		
			$args = array(
				'method'  => $http_method,
				'headers' => array( 'Content-Type' => 'application/json' ),
			);
		
			if ( in_array( $http_method, array( 'POST', 'PUT', 'PATCH' ), true ) ) {
				$args['body'] = wp_json_encode( $payload );
			} elseif ( 'GET' === $http_method ) {
				$webhook_url = add_query_arg( $form_fields, $webhook_url );
			}
			
			$response = wp_remote_request( $webhook_url, $args );
		
			if ( is_wp_error( $response ) ) {
				return false;
			}
		
			$status_code   = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );
			
			if ( ( ( strpos( $webhook_url, 'discord.com/api/webhooks' ) !== false || strpos( $webhook_url, 'discordapp.com/api/webhooks' ) !== false ) && 204 === $status_code )
				|| ( strpos( $webhook_url, 'hooks.slack.com' ) !== false && 200 === $status_code )
				|| ( $status_code >= 200 && $status_code < 300 ) ) {
				return true;
			}

			/**
			 * P-018 fix: Remove production debug logging. On shared hosting
			 * PHP error logs can be world-readable; $response_body may contain
			 * third-party API tokens, channel identifiers, or echoed customer
			 * form fields that must not leak to disk.
			 */
			return false;
		}
		

		/**
		 * Sends a message to a Discord channel using a webhook.
		 *
		 * @param array $discord_data Discord integration data including webhook URL and message template.
		 * @param array $form_fields  Submitted form fields to include in the Discord message.
		 * @return bool
		 */
		public function tpaep_discord_integration( $discord_data, $form_fields ) {
			$webhook_url = isset( $discord_data['discord_url'] ) ? sanitize_textarea_field( $discord_data['discord_url'] ) : '';
			$username    = isset( $discord_data['discord_username'] ) ? sanitize_text_field( $discord_data['discord_username'] ) : 'Form Bot';

			if ( ! filter_var( $webhook_url, FILTER_VALIDATE_URL ) ) {
				return false;
			}

			$message = "**Form Submission**\n";
			$message .= "----------------------\n";
			$message .= "**Submission Data**\n";
			foreach ( $form_fields as $key => $value ) {
				$pretty_key    = ucwords( str_replace( '_', ' ', $key ) );
				$cleaned_value = is_array( $value ) ? implode( ', ', $value ) : $value;
				$message      .= "**{$pretty_key}:** " . ( $cleaned_value ?: 'N/A' ) . "\n";
			}
			
			$message .= "\n**Meta Data**\n";
			$message .= $this->tpaep_get_form_metadata_text();

			$chunks  = strlen( $message ) > 2000 ? str_split( $message, 1900 ) : array( $message );
			$success = true;

			foreach ( $chunks as $chunk ) {
				$data = array(
					'content'  => $chunk,
					'username' => $username,
				);

				$response = wp_remote_post(
					$webhook_url,
					array(
						'method'  => 'POST',
						'body'    => wp_json_encode( $data ),
						'headers' => array(
							'Content-Type' => 'application/json; charset=utf-8',
						),
					)
				);

				if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 204 ) {
					$success = false;
				}
			}

			return $success;
		}

		/**
		 * Integrates form submission data with ActiveCampaign.
		 *
		 * @param array $ac_data     ActiveCampaign integration data including API credentials and list details.
		 * @param array $form_fields Submitted form fields to be synced with ActiveCampaign.
		 * @return bool
		 */
		public function tpaep_activecampaign_integration( $ac_data, $form_fields ) {
			$api_key = isset( $ac_data['ac_custom_key'] ) ? sanitize_text_field( $ac_data['ac_custom_key'] ) : '';
			$api_url = isset( $ac_data['ac_custom_url'] ) ? esc_url_raw( $ac_data['ac_custom_url'] ) : '';

			if ( empty( $api_key ) || empty( $api_url ) ) {
				return false;
			}

			$email = isset( $form_fields['email'] ) ? sanitize_email( $form_fields['email'] ) : '';
			$name  = isset( $form_fields['first_name'] ) ? sanitize_text_field( $form_fields['first_name'] ) : '';
			$phone = isset( $form_fields['phone'] ) ? sanitize_text_field( $form_fields['phone'] ) : '';

			if ( empty( $email ) ) {
				return false;
			}

			$api_endpoint = trailingslashit( $api_url ) . 'api/3/contacts';

			$subscriber_data = array(
				'contact' => array(
					'email'         => $email,
					'firstName'     => $name,
					'phone'         => $phone,
					'updateEnabled' => true,
				),
			);

			$response = wp_remote_post(
				$api_endpoint,
				array(
					'method'  => 'POST',
					'headers' => array(
						'Api-Token'    => $api_key,
						'Content-Type' => 'application/json',
					),
					'body'    => wp_json_encode( $subscriber_data ),
				)
			);

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$body = wp_remote_retrieve_body( $response );
			$data = json_decode( $body, true );

			if ( isset( $data['errors'] ) ) {
				return false;
			}

			return isset( $data['contact']['id'] );
		}

		/**
		 * Sends form submission data to GetResponse.
		 *
		 * @param array $gr_data     GetResponse integration data including API key and campaign ID.
		 * @param array $form_fields Submitted form fields to be sent to GetResponse.
		 * @return bool
		 */
		public function tpaep_getresponse_integration( $gr_data, $form_fields ) {
			$api_key     = isset( $gr_data['getresponse_api_key'] ) ? sanitize_text_field( $gr_data['getresponse_api_key'] ) : '';
			$campaign_id = isset( $gr_data['getresponse_list_token'] ) ? sanitize_text_field( $gr_data['getresponse_list_token'] ) : '';
			$email       = $form_fields['email'] ?? '';
			$name        = $form_fields['first_name'] ?? '';

			if ( empty( $api_key ) || empty( $campaign_id ) || empty( $email ) ) {
				return false;
			}

			$url = 'https://api.getresponse.com/v3/contacts';

			$headers = array(
				'X-Auth-Token' => 'api-key ' . $api_key,
				'Content-Type' => 'application/json',
			);

			$payload = wp_json_encode(
				array(
					'email'    => $email,
					'name'     => $name,
					'campaign' => array(
						'campaignId' => $campaign_id,
					),
				)
			);

			$args = array(
				'method'  => 'POST',
				'headers' => $headers,
				'body'    => $payload,
				'timeout' => 15,
			);

			$response = wp_remote_post( $url, $args );

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$response_code = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );

			if ( in_array( $response_code, array( 202, 409 ), true ) ) {
				return true;
			}

			return false;
		}

		/**
		 * Sends form submission data to Mailchimp.
		 *
		 * @param array $mc_data     Mailchimp integration data including API key and list ID.
		 * @param array $form_fields Submitted form fields to be added to the Mailchimp list.
		 * @return bool
		 */
		public function tpaep_mailchimp_integration( $mc_data, $form_fields ) {
			$api_key = isset( $mc_data['mailchimp_api_key'] ) ? sanitize_text_field( $mc_data['mailchimp_api_key'] ) : '';
			$list_id = isset( $mc_data['mailchimp_audience_id'] ) ? sanitize_text_field( $mc_data['mailchimp_audience_id'] ) : '';

			if ( empty( $api_key ) || empty( $list_id ) ) {
				return false;
			}

			if ( strpos( $api_key, '-' ) === false ) {
				return false;
			}

			$data_center = substr( $api_key, strpos( $api_key, '-' ) + 1 );
			if ( empty( $data_center ) ) {
				return false;
			}

			$email = $form_fields['email'] ?? '';
			$name  = $form_fields['first_name'] ?? '';

			$url = "https://{$data_center}.api.mailchimp.com/3.0/lists/{$list_id}/members";

			$headers = array(
				'Authorization' => 'apikey ' . $api_key,
				'Content-Type'  => 'application/json',
			);

			$payload = wp_json_encode(
				array(
					'email_address' => $email,
					'status'        => 'subscribed',
					'merge_fields'  => array(
						'FNAME' => $name,
					),
				)
			);

			$args = array(
				'method'  => 'POST',
				'headers' => $headers,
				'body'    => $payload,
			);

			$response = wp_remote_post( $url, $args );

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$response_code = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );
			$response_data = json_decode( $response_body, true );

			if ( $response_code >= 200 && $response_code < 300 ) {
				if ( isset( $response_data['status'] ) && 'subscribed' === $response_data['status'] ) {
					return true;
				} else {
					return false;
				}
			}

			return false;
		}

		/**
		 * Sends form submission data to Brevo (formerly Sendinblue).
		 *
		 * @param array $brevo_data  Brevo integration data including API key and list ID.
		 * @param array $form_fields Submitted form fields to be added to Brevo.
		 * @return bool
		 */
		public function tpaep_brevo_integration( $brevo_data, $form_fields ) {
			$api_key = isset( $brevo_data['brevo_api_key'] ) ? sanitize_text_field( $brevo_data['brevo_api_key'] ) : '';
			if ( empty( $api_key ) ) {
				return false;
			}

			$list_id = $brevo_data['brevo_list_id'] ?? null;

			$email = $form_fields['email'] ?? '';
			$name  = $form_fields['first_name'] ?? '';

			if ( empty( $email ) ) {
				return false;
			}

			$contact_data = array(
				'email'      => $email,
				'attributes' => array(
					'FIRSTNAME' => $name,
				),
			);

			if ( $list_id ) {
				$contact_data['listIds'] = array( (int) $list_id );
			}

			$url     = 'https://api.brevo.com/v3/contacts';
			$headers = array(
				'Content-Type' => 'application/json',
				'api-key'      => $api_key,
			);
			$args    = array(
				'method'  => 'POST',
				'headers' => $headers,
				'body'    => wp_json_encode( $contact_data ),
			);

			$response = wp_remote_post( $url, $args );

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$response_code = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );
			$body_data     = json_decode( $response_body, true );

			if ( 201 === $response_code ) {
				return true;
			}

			if ( isset( $body_data['code'] ) && 'duplicate_parameter' === $body_data['code'] ) {
				$update_url  = 'https://api.brevo.com/v3/contacts/' . rawurlencode( $email );
				$update_body = array(
					'attributes' => array( 'FIRSTNAME' => $name ),
				);

				if ( $list_id ) {
					$update_body['listIds'] = array( (int) $list_id );
				}

				$update_args = array(
					'method'  => 'PUT',
					'headers' => $headers,
					'body'    => wp_json_encode( $update_body ),
				);

				$update_response      = wp_remote_request( $update_url, $update_args );
				$update_response_code = wp_remote_retrieve_response_code( $update_response );

				if ( 204 === $update_response_code ) {
					return true;
				}
				return false;
			}
			return false;
		}

		/**
		 * Sends form submission data to ConvertKit.
		 *
		 * @param array $convertkit_data ConvertKit integration data including API key and form ID.
		 * @param array $form_fields     Submitted form fields to be added to ConvertKit.
		 * @return bool
		 */
		public function tpaep_convertkit_integration( $convertkit_data, $form_fields ) {
			$api_key    = sanitize_text_field( $convertkit_data['convertkey_api_key'] ?? '' );
			$form_id    = sanitize_text_field( $convertkit_data['convertkey_form_id'] ?? '' );
			$email      = $form_fields['email'] ?? '';
			$first_name = $form_fields['first_name'] ?? '';
			$phone      = $form_fields['phone'] ?? '';

			if ( empty( $api_key ) || empty( $form_id ) || empty( $email ) ) {
				return false;
			}

			$url = "https://api.convertkit.com/v3/forms/{$form_id}/subscribe?api_key={$api_key}";

			$headers = array(
				'Content-Type' => 'application/json',
			);

			$payload = wp_json_encode(
				array(
					'email'      => $email,
					'first_name' => $first_name,
					'phone'      => $phone,
				)
			);

			$args = array(
				'method'  => 'POST',
				'body'    => $payload,
				'headers' => $headers,
				'timeout' => 45,
			);

			$response = wp_remote_post( $url, $args );

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$status_code   = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );

			if ( 200 === $status_code ) {
				return true;
			}

			return false;
		}

		/**
		 * Sends form submission data to MailerLite.
		 *
		 * @param array $mailerlite_data MailerLite integration data including API key and group ID.
		 * @param array $form_fields     Submitted form fields to be added to MailerLite.
		 * @return bool
		 */
		public function tpaep_mailerlite_integration( $mailerlite_data, $form_fields ) {
			$api_key  = sanitize_text_field( $mailerlite_data['mailerlite_api_key'] ?? '' );
			$group_id = sanitize_text_field( $mailerlite_data['mailerlite_group_id'] ?? '' );
			$email    = sanitize_email( $form_fields['email'] ?? '' );
			$name     = sanitize_text_field( $form_fields['fisrt_name'] ?? '' );

			if ( empty( $api_key ) || empty( $group_id ) || empty( $email ) ) {
				return false;
			}

			$url = 'https://connect.mailerlite.com/api/subscribers';

			$headers = array(
				'Content-Type'  => 'application/json',
				'Authorization' => 'Bearer ' . $api_key,
			);

			$payload = wp_json_encode(
				array(
					'email'  => $email,
					'fields' => array(
						'name' => $name,
					),
					'groups' => array( $group_id ),
				)
			);

			$args = array(
				'method'  => 'POST',
				'headers' => $headers,
				'body'    => $payload,
				'timeout' => 20,
			);

			$response = wp_remote_post( $url, $args );

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$status_code = wp_remote_retrieve_response_code( $response );
			$body        = json_decode( wp_remote_retrieve_body( $response ), true );

			if ( 200 === $status_code || 201 === $status_code ) {
				return true;
			}

			return false;
		}

		/**
		 * Sends form submission data to Drip.
		 *
		 * @param array $drip_data     Drip integration data including API key and campaign details.
		 * @param array $form_fields   Submitted form fields to be added to Drip.
		 * @return bool
		 */
		public function tpaep_drip_integration( $drip_data, $form_fields ) {
			$account_id = sanitize_text_field( $drip_data['drip_account_id'] ?? '' );
			$api_key    = sanitize_text_field( $drip_data['drip_api_key'] ?? '' );
			$email      = sanitize_email( $form_fields['email'] ?? '' );
			$name       = sanitize_text_field( $form_fields['first_name'] ?? '' );
			$phone      = sanitize_text_field( $form_fields['phone'] ?? '' );

			if ( empty( $account_id ) || empty( $api_key ) || empty( $email ) ) {
				return false;
			}

			$url = "https://api.getdrip.com/v2/{$account_id}/subscribers";

			$headers = array(
				'Content-Type'  => 'application/vnd.api+json',
				'Accept'        => 'application/vnd.api+json',
				'Authorization' => 'Basic ' . base64_encode( $api_key . ':' ),
			);

			$payload = wp_json_encode(
				array(
					'subscribers' => array(
						array(
							'email'      => $email,
							'first_name' => $name,
							'phone'      => $phone,
						),
					),
				)
			);

			$args = array(
				'method'  => 'POST',
				'headers' => $headers,
				'body'    => $payload,
				'timeout' => 20,
			);

			$response = wp_remote_post( $url, $args );

			if ( is_wp_error( $response ) ) {
				return false;
			}

			$status_code = wp_remote_retrieve_response_code( $response );
			$body        = json_decode( wp_remote_retrieve_body( $response ), true );

			if ( 200 === $status_code || 201 === $status_code ) {
				return true;
			}
			return false;
		}

		/**
		 * Send email using wp_mail.
		 *
		 * @since 6.0.4
		 *
		 * @param array $email_data Array of email data.
		 * @param array $form_data Array of form data.
		 * @param array $form_fields Array of form fields.
		 * @return bool Whether the email was sent successfully.
		 */
		public function tpaep_prepare_email_settings( $email_data, $form_data, $form_fields ) {
			$email_to        = ! empty( $email_data['email_to'] ) ? sanitize_email( $email_data['email_to'] ) : get_option( 'admin_email' );
			$email_subject   = ! empty( $email_data['email_subject'] ) ? sanitize_text_field( $email_data['email_subject'] ) : 'New Form Submission';
			$email_from      = ! empty( $email_data['email_from'] ) ? sanitize_email( $email_data['email_from'] ) : 'no-reply@example.com';
			$email_from_name = ! empty( $email_data['email_from_name'] ) ? sanitize_text_field( $email_data['email_from_name'] ) : '';
			$email_reply_to  = ! empty( $email_data['email_reply_to'] ) ? sanitize_email( $email_data['email_reply_to'] ) : '';
			$email_cc        = ! empty( $email_data['email_cc'] ) ? sanitize_email( $email_data['email_cc'] ) : '';
			$email_bcc       = ! empty( $email_data['email_bcc'] ) ? sanitize_email( $email_data['email_bcc'] ) : '';
			$email_heading   = ! empty( $email_data['email_heading'] ) ? sanitize_text_field( $email_data['email_heading'] ) : '';

			$email_message = isset( $email_data['email_message'] ) && ! empty( $email_data['email_message'] )
				? sanitize_text_field( $email_data['email_message'] )
				: 'all-fields';

			$email_message_content = $this->tpaep_build_email_message( $form_data, $form_fields, $email_message, $email_heading );

			return array(
				'email_to'        => $email_to,
				'email_subject'   => $email_subject,
				'email_message'   => $email_message_content,
				'email_from'      => $email_from,
				'email_from_name' => $email_from_name,
				'email_reply_to'  => $email_reply_to,
				'email_cc'        => $email_cc,
				'email_bcc'       => $email_bcc,
				'email_heading'   => $email_heading,
			);
		}

		/**
		 * Prepares the settings for the autoresponder email.
		 *
		 * @param array $email_data   The email data including subject, message, and other settings.
		 * @param array $form_data    The data submitted via the form.
		 * @param array $form_fields  The formatted form field values.
		 *
		 * @return array Prepared email settings array.
		 */
		public function tpaep_prepare_are_settings( $email_data, $form_data, $form_fields ) {
			$email_to        = ! empty( $form_data['email'] ) ? sanitize_email( $form_data['email'] ) : get_option( 'admin_email' );
			$email_subject   = ! empty( $email_data['ar_email_subject'] ) ? sanitize_text_field( $email_data['ar_email_subject'] ) : 'New Form Submission';
			$email_from      = ! empty( $email_data['ar_email_from'] ) ? sanitize_email( $email_data['ar_email_from'] ) : 'no-reply@example.com';
			$email_from_name = ! empty( $email_data['ar_email_from_name'] ) ? sanitize_text_field( $email_data['ar_email_from_name'] ) : '';
			$email_reply_to  = ! empty( $email_data['ar_email_reply_to'] ) ? sanitize_email( $email_data['ar_email_reply_to'] ) : '';

			$email_cc        = ! empty( $email_data['ar_email_cc'] ) ? sanitize_email( $email_data['ar_email_cc'] ) : '';
			$email_bcc       = ! empty( $email_data['ar_email_bcc'] ) ? sanitize_email( $email_data['ar_email_bcc'] ) : '';
			$email_heading   = ! empty( $email_data['ar_email_heading'] ) ? sanitize_text_field( $email_data['ar_email_heading'] ) : '';

			$email_message = isset( $email_data['ar_email_message'] ) && ! empty( $email_data['ar_email_message'] )
				? sanitize_text_field( $email_data['ar_email_message'] )
				: 'all-fields';

			$email_message_content = $this->tpaep_build_email_message( $form_data, $form_fields, $email_message, $email_heading );

			return array(
				'email_to'        => $email_to,
				'email_subject'   => $email_subject,
				'email_message'   => $email_message_content,
				'email_from'      => $email_from,
				'email_from_name' => $email_from_name,
				'email_reply_to'  => $email_reply_to,
				'email_cc'        => $email_cc,
				'email_bcc'       => $email_bcc,
				'email_heading'   => $email_heading,
			);
		}

		/**
		 * Process Email Message: creates email message text
		 *
		 * @since 6.0.4
		 *
		 * @param array $form_data The form fields array.
		 * @param array $form_fields The form data array.
		 * @param array $email_message The form data array.
		 * @param array $email_heading The form data array.
		 */
		public function tpaep_build_email_message( $form_data, $form_fields, $email_message, $email_heading ) {
			$email_message = trim( $email_message );

			if ( '[all-values]' === $email_message ) {
				// $email_message = ! empty( $email_heading ) ? '<h2>' . esc_html( $email_heading ) . '</h2>' : '';
				
				// Add form submission header
				$email_message = '<h3>Form Submission</h3>';
				$email_message .= '<hr style="border: 1px solid #ddd; margin: 20px 0;">';
				
				// Add submission data section
				$email_message .= '<h4>Submission Data</h4>';
				foreach ( $form_fields as $key => $field ) {
					if ( ! is_numeric( $key ) ) {
						$display_value = is_array( $field ) ? implode( ', ', $field ) : $field;
						if ( ! empty( $display_value ) ) {
							$clean_label = str_replace('[]', '', $key);
							$email_message .= '<p><strong>' . esc_html( $clean_label ) . ':</strong> ' . wp_kses_post( $display_value ) . '</p>';
						}
					}
				}
				
				// Add metadata section
				$email_message .= '<h4>Meta Data</h4>';
				$email_message .= $this->tpaep_get_form_metadata();
			}

			$email_message = preg_replace_callback(
				"/\[value_id=(\"|')([^\"']+)(\"|')\]/",
				function ( $matches ) use ( $form_fields ) {
					$field_id_from_shortcode = $matches[2];

					foreach ( $form_fields as $field ) {
						if ( ( isset( $field['field_id'] ) && $field['field_id'] === $field_id_from_shortcode ) ||
							( isset( $field['field_name'] ) && strpos( $field['field_name'], $field_id_from_shortcode ) !== false ) ) {
							return wp_kses_post( $field['field_value'] );
						}
					}

					return "[form_id=\"$field_id_from_shortcode\"]";
				},
				$email_message
			);

			return $email_message;
		}

		/**
		 * Get form submission metadata including date, time, page URL, user agent, and remote IP.
		 *
		 * @since 6.0.4
		 *
		 * @return string HTML formatted metadata.
		 */
		private function tpaep_get_form_metadata() {
			$current_datetime = current_time( 'Y-m-d H:i:s' );
			$date = date( 'Y-m-d', strtotime( $current_datetime ) );
			$time = date( 'H:i:s', strtotime( $current_datetime ) );
			
			$page_url = '';
			if ( isset( $_POST['page_url'] ) ) {
				$page_url = sanitize_url( $_POST['page_url'] );
			} elseif ( isset( $_SERVER['HTTP_REFERER'] ) ) {
				$page_url = sanitize_url( $_SERVER['HTTP_REFERER'] );
			}
			
			$user_agent = '';
			if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
				$user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );
			}
			
			$remote_ip = '';
			if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
				$remote_ip = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
			} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
				$remote_ip = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
			} elseif ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
				$remote_ip = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
			}
			
			$metadata_html = '';
			$metadata_html .= '<p><strong>Date:</strong> ' . esc_html( $date ) . '</p>';
			$metadata_html .= '<p><strong>Time:</strong> ' . esc_html( $time ) . '</p>';
			$metadata_html .= '<p><strong>Page URL:</strong> ' . esc_html( $page_url ) . '</p>';
			$metadata_html .= '<p><strong>User Agent:</strong> ' . esc_html( $user_agent ) . '</p>';
			$metadata_html .= '<p><strong>Remote IP:</strong> ' . esc_html( $remote_ip ) . '</p>';
			
			return $metadata_html;
		}

		/**
		 * Get form submission metadata in plain text format for integrations like Slack, Discord, etc.
		 *
		 * @since 6.0.4
		 *
		 * @return string Plain text formatted metadata.
		 */
		private function tpaep_get_form_metadata_text() {
			$current_datetime = current_time( 'Y-m-d H:i:s' );
			$date = date( 'Y-m-d', strtotime( $current_datetime ) );
			$time = date( 'H:i:s', strtotime( $current_datetime ) );
			
			$page_url = '';
			if ( isset( $_POST['page_url'] ) ) {
				$page_url = sanitize_url( $_POST['page_url'] );
			} elseif ( isset( $_SERVER['HTTP_REFERER'] ) ) {
				$page_url = sanitize_url( $_SERVER['HTTP_REFERER'] );
			}
			
			$user_agent = '';
			if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
				$user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );
			}
			
			$remote_ip = '';
			if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
				$remote_ip = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
			} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
				$remote_ip = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
			} elseif ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
				$remote_ip = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
			}
			
			$metadata_text = '';
			$metadata_text .= "Date: " . $date . "\n";
			$metadata_text .= "Time: " . $time . "\n";
			$metadata_text .= "Page URL: " . $page_url . "\n";
			$metadata_text .= "User Agent: " . $user_agent . "\n";
			$metadata_text .= "Remote IP: " . $remote_ip . "\n";
			$metadata_text .= "Powered By: The Plus Addons for Elmentor\n";
			
			return $metadata_text;
		}

		/**
		 * Send Email Message : Includes Email Configurations
		 *
		 * @since 6.0.4
		 *
		 * @param array $mail_conf The tpaep_send_email array.
		 */
		public function tpaep_send_email( $mail_conf ) {
			$to      = $mail_conf['email_to'];
			$subject = $mail_conf['email_subject'];
			$message = $mail_conf['email_message'];

			$headers = array(
				'From: ' . $mail_conf['email_from_name'] . ' <' . $mail_conf['email_from'] . '>',
				'Reply-To: ' . $mail_conf['email_reply_to'],
				'Content-Type: text/html; charset=UTF-8',
			);

			if ( ! empty( $mail_conf['email_cc'] ) ) {
				$headers[] = 'Cc: ' . $mail_conf['email_cc'];
			}
			if ( ! empty( $mail_conf['email_bcc'] ) ) {
				$headers[] = 'Bcc: ' . $mail_conf['email_bcc'];
			}

			return wp_mail( $to, $subject, $message, $headers );
		}
	}

	Tp_Plus_Form::get_instance();
}