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

require_once SFTCY_WORDFORM_PLUGIN_INC . 'class-sftcy-wordform-support.php';

if ( ! class_exists( 'SftcyWordformBase' ) ) {
	class SftcyWordformBase {
		private static $initiated                          		= false;
		public static $sc_wordform_tbl                     		= 'scwordform_created_forms';
		public static $sc_wordform_submission_tbl          		= 'scwordform_submisson_forms_data';
		public static $sc_wordform_validation_messages_tbl 		= 'scwordform_validation_messages_data';
		public static $sc_wordform_connects_tbl            	  	= 'scwordform_connects_data';
		public static $sc_wordform_configured_application_tbl 	= 'scwordform_configured_applications';
		public static $sc_wordform_coupons_tbl             		= 'scwordform_coupons';
		public static $sc_wordform_coupon_usage_tbl        		= 'scwordform_coupon_usage';
		public static $sc_wordform_support_requests_tbl   		= 'scwordform_support_requests';
		public static $sc_wordform_support_logs_tbl       		= 'scwordform_support_logs';
		public static $wordform_custom_block_name          		= 'wordform-block/wordform';
		public static $preview_form_data                   		= null;
		public static $output 							   		= [];
		const WORDFORM_DB_SCHEMA_VERSION                         = '20260508';

		public function __construct() {
			if ( ! self::$initiated ) {
				self::initiate_hooks();
			}
		}

		/**
		 * Init Hooks
		 */
		private static function initiate_hooks() {
			add_action( 'admin_init', [ __CLASS__, 'sftcy_wordform_deactivate_free_plugin' ] );
			add_action( 'init', array( __CLASS__, 'sc_wordform_create_block_init' ) );
			add_action( 'admin_menu', array( __CLASS__, 'add_scwordform_submenus' ) );
			add_action( 'admin_post_sc_wordform_export_form_submissions', array( __CLASS__, 'sc_wordform_export_form_submissions' ) );
			// add_action( 'current_screen', [ __CLASS__, 'wordform_current_screen_actions' ] );
			add_filter( 'the_content', array( __CLASS__, 'wordform_post_page_rendering_with_form_data' ) );

			add_action( 'admin_notices', array( __CLASS__, 'scwordform_admin_notices' ) );
			add_action( 'admin_enqueue_scripts', array( __CLASS__, 'scwordform_empty_state_notice_styles' ) );
			add_action( 'plugins_loaded', array( __CLASS__, 'scwordform_load_textdomain' ) );
			add_action( 'plugins_loaded', array( __CLASS__, 'maybe_upgrade_database_schema' ), 20 );
			// add_filter( 'plugin_row_meta',     array( __CLASS__, 'scwordform_row_link'), 10, 2 );
			add_filter( 'template_include', array( __CLASS__, 'sc_wordform_check_preview_page' ), 10, 1 );

			self::$initiated = true;
		}

		/**
		 * Activate required dependency
		 */
		public static function activate() {
			self::check_preactivation_requirements();
			self::sc_wordform_create_block_init();
			self::sc_wordform_db_tables_install();
			flush_rewrite_rules( true );
		}

		public static function maybe_upgrade_database_schema() {
			$installed_schema_version = get_option( 'sftcy_wordform_db_schema_version', '' );

			if ( self::WORDFORM_DB_SCHEMA_VERSION !== (string) $installed_schema_version ) {
				self::sc_wordform_db_tables_install();
			}
		}

		/**
		 * Check pre-activate requirements
		 */
		public static function check_preactivation_requirements() {
			if ( version_compare( PHP_VERSION, SFTCY_WORDFORM_MINIMUM_PHP_VERSION, '<' ) ) {
				wp_die( esc_html( 'Minimum PHP Version required: ' ) . SFTCY_WORDFORM_MINIMUM_PHP_VERSION );
			}
			global $wp_version;
			if ( version_compare( $wp_version, SFTCY_WORDFORM_MINIMUM_WP_VERSION, '<' ) ) {
				wp_die( esc_html( 'Minimum WordPress Version required: ' ) . SFTCY_WORDFORM_MINIMUM_WP_VERSION );
			}
		}

		/**
		 * 'admin_init' hook call back method
		 * If free version activated then deactivate to install PRO plugin 
		 * @return void
		 */
		public static function sftcy_wordform_deactivate_free_plugin() {
			// Include dependent file		
			if ( ! function_exists( 'is_plugin_active' ) || ! function_exists( 'is_plugin_inactive' || ! function_exists( 'deactivate_plugins' ) ) ) {
				include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
			}

			if ( is_plugin_active( 'wordform-pro/wordform-pro.php' ) ) {
				deactivate_plugins( 'wordform/wordform.php' );
				$linktext = '<a href="' . esc_attr( admin_url( 'plugins.php' ) ) . '" rel="nofollow"> Return to Plugins page</a>';
				wp_die( 'WordForm free plugin has been deactivated because WordForm Pro is active on this site. Please keep only one WordForm variant active at a time.' . $linktext );
			}
		}

		public static function scwordform_load_textdomain() {
			load_plugin_textdomain( 'wordform', false, SFTCY_WORDFORM_PLUGIN_DIR . 'languages/' );
		}

		public static function sc_wordform_create_block_init() {
			register_block_type( SFTCY_WORDFORM_PLUGIN_DIR . 'admin/block/build', array() );
		}

		/**
		 * Get alll created from list
		 * display as select dropdown
		 * Block editor select form name dropdown
		 * return - array - [ ID, formID, formName ]
		 */
		public static function sc_wordform_get_all_forms_for_block_dynamic_callback() {
			global $wpdb;
			$table         = $wpdb->prefix . self::$sc_wordform_tbl;
			$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT id,form_id,form_name FROM %i ORDER BY id DESC', $table ), ARRAY_A );

			$options = array();
			foreach ( $query_results as $data ) {
				$temp             = array();
				$temp['formName'] = sanitize_text_field( $data['form_name'] );
				$temp['formID']   = sanitize_text_field( $data['form_id'] );
				$temp['ID']       = sanitize_text_field( $data['id'] );
				$options[]        = $temp;
			}
			return $options;
		}

		/**
		 * Create Tables
		 *
		 * @since 1.0.0
		 */
		public static function sc_wordform_db_tables_install() {
			global $wpdb;
			$wordform_created_form_table_name        	= $wpdb->prefix . self::$sc_wordform_tbl;
			$wordform_submission_form_table_name     	= $wpdb->prefix . self::$sc_wordform_submission_tbl;
			$wordform_validation_messages_table_name 	= $wpdb->prefix . self::$sc_wordform_validation_messages_tbl;
			$wordform_connects_data_table_name       	= $wpdb->prefix . self::$sc_wordform_connects_tbl;			
			$wordform_configured_application_table_name = $wpdb->prefix . self::$sc_wordform_configured_application_tbl;			
			$wordform_coupons_table_name            	= $wpdb->prefix . self::$sc_wordform_coupons_tbl;
			$wordform_coupon_usage_table_name       	= $wpdb->prefix . self::$sc_wordform_coupon_usage_tbl;
			$wordform_support_requests_table_name   	= $wpdb->prefix . self::$sc_wordform_support_requests_tbl;
			$wordform_support_logs_table_name       	= $wpdb->prefix . self::$sc_wordform_support_logs_tbl;
			$charset_collate                         	= $wpdb->get_charset_collate();

			// Keep dbDelta SQL simple: one column per line and no blank lines inside definitions.
			$wordform_created_forms_tbl_sql = "CREATE TABLE $wordform_created_form_table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
form_name CHAR(100) DEFAULT '' NOT NULL,
form_id CHAR(100) DEFAULT '' NOT NULL,
form TEXT DEFAULT NULL,
builtform_html_data LONGTEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_submission_forms_tbl_sql = "CREATE TABLE $wordform_submission_form_table_name (
id BIGINT NOT NULL AUTO_INCREMENT,
form_id CHAR(100) DEFAULT '' NOT NULL,
submission_data TEXT DEFAULT NULL,
submission_user_data TEXT DEFAULT NULL,
data_send_info TEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_validation_messages_tbl_sql = "CREATE TABLE $wordform_validation_messages_table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
form_id CHAR(100) DEFAULT '' NOT NULL,
validation_messages TEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_connects_data_tbl_sql = "CREATE TABLE $wordform_connects_data_table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
configured_application_tbl_id INT(11) DEFAULT 0 NOT NULL,
wordform_id CHAR(50) DEFAULT '' NOT NULL,
wordform_status CHAR(50) DEFAULT 'active' NOT NULL,
connection_status CHAR(50) DEFAULT 'active' NOT NULL,
connection_info LONGTEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_configured_application_tbl_sql = "CREATE TABLE $wordform_configured_application_table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
application_slug CHAR(50) DEFAULT '' NOT NULL,
application_name CHAR(50) DEFAULT '' NOT NULL,
configured_status CHAR(50) DEFAULT 'active' NOT NULL,
configured_info LONGTEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_coupons_tbl_sql = "CREATE TABLE $wordform_coupons_table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
coupon_code CHAR(100) DEFAULT '' NOT NULL,
discount_type CHAR(20) DEFAULT 'fixed' NOT NULL,
discount_value DECIMAL(10,2) DEFAULT 0.00 NOT NULL,
coupon_status CHAR(20) DEFAULT 'active' NOT NULL,
start_date DATE DEFAULT NULL,
expiry_date DATE DEFAULT NULL,
usage_limit INT(11) DEFAULT 0 NOT NULL,
minimum_amount DECIMAL(10,2) DEFAULT 0.00 NOT NULL,
apply_to_custom_amount CHAR(10) DEFAULT 'no' NOT NULL,
allowed_forms LONGTEXT DEFAULT NULL,
coupon_note LONGTEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_coupon_usage_tbl_sql = "CREATE TABLE $wordform_coupon_usage_table_name (
id BIGINT NOT NULL AUTO_INCREMENT,
coupon_id INT(11) DEFAULT 0 NOT NULL,
coupon_code CHAR(100) DEFAULT '' NOT NULL,
form_id CHAR(100) DEFAULT '' NOT NULL,
submission_id BIGINT DEFAULT 0 NOT NULL,
payment_gateway CHAR(50) DEFAULT '' NOT NULL,
discount_amount DECIMAL(10,2) DEFAULT 0.00 NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_support_requests_tbl_sql = "CREATE TABLE $wordform_support_requests_table_name (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_uuid CHAR(36) DEFAULT '' NOT NULL,
site_url TEXT DEFAULT NULL,
site_domain CHAR(190) DEFAULT '' NOT NULL,
sender_email CHAR(190) DEFAULT '' NOT NULL,
plugin_variant CHAR(20) DEFAULT 'free' NOT NULL,
plugin_version CHAR(50) DEFAULT '' NOT NULL,
issue_type CHAR(50) DEFAULT 'general' NOT NULL,
include_diagnostics CHAR(3) DEFAULT 'yes' NOT NULL,
delivery_channels LONGTEXT DEFAULT NULL,
delivery_results LONGTEXT DEFAULT NULL,
overall_status CHAR(30) DEFAULT 'received' NOT NULL,
office_ticket_id CHAR(100) DEFAULT '' NOT NULL,
office_status CHAR(30) DEFAULT '' NOT NULL,
office_last_synced_at DATETIME DEFAULT NULL,
request_payload LONGTEXT DEFAULT NULL,
delivery_channel CHAR(50) DEFAULT 'email' NOT NULL,
delivery_status CHAR(20) DEFAULT 'pending' NOT NULL,
delivery_message TEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY  (id)
) $charset_collate;";

			$wordform_support_logs_tbl_sql = "CREATE TABLE $wordform_support_logs_table_name (
id BIGINT NOT NULL AUTO_INCREMENT,
severity CHAR(20) DEFAULT 'info' NOT NULL,
subsystem CHAR(50) DEFAULT 'general' NOT NULL,
event_code CHAR(100) DEFAULT '' NOT NULL,
message TEXT DEFAULT NULL,
context_json LONGTEXT DEFAULT NULL,
form_id CHAR(100) DEFAULT '' NOT NULL,
submission_id BIGINT DEFAULT 0 NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
expires_at DATETIME DEFAULT NULL,
PRIMARY KEY  (id)
) $charset_collate;";

		
			// Create Tables
			require_once ABSPATH . 'wp-admin/includes/upgrade.php';
			dbDelta( $wordform_created_forms_tbl_sql );
			dbDelta( $wordform_submission_forms_tbl_sql );
			dbDelta( $wordform_validation_messages_tbl_sql );
			dbDelta( $wordform_connects_data_tbl_sql );
			dbDelta( $wordform_configured_application_tbl_sql );
			dbDelta( $wordform_coupons_tbl_sql );
			dbDelta( $wordform_coupon_usage_tbl_sql );
			dbDelta( $wordform_support_requests_tbl_sql );
			dbDelta( $wordform_support_logs_tbl_sql );

			// Add Columns 'data_send_info' - new column added later after creation of Table
			$column_data_send_info = 'data_send_info';
			$column_data_send_info_sql = 'ALTER TABLE '. $wordform_submission_form_table_name .' ADD COLUMN ' . $column_data_send_info . ' TEXT DEFAULT NULL AFTER submission_user_data';
			maybe_add_column( $wordform_submission_form_table_name, $column_data_send_info, $column_data_send_info_sql );

			update_option( 'sftcy_wordform_db_schema_version', self::WORDFORM_DB_SCHEMA_VERSION );
		}

		/**
		 * filter hook
		 * Created form display - preview & test
		 * return - template path
		 */
		public static function sc_wordform_check_preview_page( $template ) {
			if ( isset( $_GET['sc-wordform-id'] ) && ! empty( $_GET['sc-wordform-id'] ) ) {
				// global $created_form_escaped;
				// global $sc_wordform_id;
				$form_id = sanitize_text_field( $_GET['sc-wordform-id'] );
				// $sc_wordform_id = $form_id;
				// $created_form_escaped = SftcyWordformBuildForm::wordform_built_to_display( $form_id );
				self::$preview_form_data = SftcyWordformBuildForm::wordform_built_to_display( $form_id );
				$template = SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/sc-wordform-preview-page.php';
			}
			return $template;
		}
		
		/**
		 * Check built form preview page template data
		 * Built form data with proper sanitization & escaping
		 * @return - string
		 */
		public static function wordform_check_preview_template_data() {						
			return self::$preview_form_data;
		}

		/**
		 * Get created form  data by form_id
		 * param - $form_id
		 * return - array
		 */
		public static function sc_wordform_db_query( $form_id = null ) {
			global $wpdb;
			$table         = $wpdb->prefix . self::$sc_wordform_tbl;
			$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE form_id = %s LIMIT 1', array( $table, $form_id ) ), ARRAY_A );
			return $query_results;
		}

		/**
		 * Add admin menus
		 */
		public static function add_scwordform_submenus() {

			// Top Menu|Parent Menu - WordForm
			//add_menu_page( __( 'WordForm', 'wordform-pro' ), 'WordForm', 'manage_options', 'word-form-topmenu', '', 'dashicons-forms', 6 );
			// add_menu_page( __( 'WordForm Pro', 'wordform-pro' ), 'WordForm Pro', 'manage_options', 'word-form-topmenu', '', plugin_dir_url( __FILE__ ) . '../admin/views/images/wordform-icon-box-shape-16x16.png', 6 );
			add_menu_page( __( 'WordForm', 'wordform' ), 'WordForm', 'manage_options', 'word-form-topmenu', '', plugin_dir_url( __FILE__ ) . '../admin/views/images/wordform-icon-gradient.svg', 6 );

			// Submenu - All Forms - sc-wordform-all-forms page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm - Forms', 'wordform' ),
				__( 'Forms', 'wordform' ),
				'manage_options',
				'word-form-topmenu',
				array( __CLASS__, 'add_scwordform_submenus_allforms_callback' )
			);

			// Submenu - Create Forms - sc-wordform-create-forms page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm - Add New', 'wordform' ),
				__( 'Add New', 'wordform' ),
				'manage_options',
				'sc-wordform-create-forms',
				array( __CLASS__, 'add_scwordform_submenus_create_forms_callback' )
			);

			// Submenu - Forms Submission Report - sc-wordform-user-submission-data page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm - Submissions', 'wordform' ),
				__( 'Submissions', 'wordform' ),
				'manage_options',
				'sc-wordform-user-submission-data',
				array( __CLASS__, 'add_scwordform_submenus_user_submission_report_callback' )
			);

			// Submenu [ Hidden ] - Forms Submission data information - sc-wordform-user-form-submission-data page slug - Parent slug ( 'options.php' for hidden, not visible in menu )
			add_submenu_page(
				'options.php', 
				__( 'WordForm - Submission Details', 'wordform-pro' ),
				__( 'Submission Details', 'wordform-pro' ),
				'manage_options',
				'sc-wordform-user-form-submission-data',
				array( __CLASS__, 'add_scwordform_submenus_user_form_submission_data_callback' )
			);

			// Submenu [ Hidden ] - Connection send log data by form.
			if ( SftcyWordformFeatures::wordform_is_feature_available( 'connection_send_logs' ) ) {
				add_submenu_page(
					'options.php',
					__( 'WordForm - Integration Send Log', 'wordform' ),
					__( 'Integration Send Log', 'wordform' ),
					'manage_options',
					'sc-wordform-connection-status-send-log',
					array( __CLASS__, 'add_scwordform_submenus_connection_status_send_log_callback' )
				);
			}

			// Submenu - Settings - sc-wordform-settings page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm -Settings', 'wordform' ),
				__( 'Settings', 'wordform' ),
				'manage_options',
				'sc-wordform-settings',
				array( __CLASS__, 'add_scwordform_submenus_settings_callback' )
			);

			// Submenu - Integrations - wordform-connects page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm - Integrations', 'wordform' ),
				__( 'Integrations', 'wordform' ),
				'manage_options',
				'wordform-connects',
				array( __CLASS__, 'add_scwordform_submenus_connects_callback' )
			);

			// Submenu - Support - wordform-support page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm - Support', 'wordform' ),
				__( 'Support', 'wordform' ),
				'manage_options',
				'wordform-support',
				array( __CLASS__, 'add_scwordform_submenus_support_callback' )
			);

			// Submenu - License - wordform-license page slug
			add_submenu_page(
				'word-form-topmenu',
				__( 'WordForm - Go Pro', 'wordform' ),
				__( 'Go Pro', 'wordform' ),
				'manage_options',
				'wordform-license',
				array( __CLASS__, 'add_scwordform_submenus_license_callback' )
			);

		}

		/**
		 * All Forms: Callback function of all forms
		 * Display all created forms
		 */
		public static function add_scwordform_submenus_allforms_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			$query_results = self::sc_wordform_get_all_created_forms_data();
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/allforms_callback_page.php';
		}

		/**
		 * Create Form: Create form page menu callback function
		 * Check if edit page - if not then create form page
		 */
		public static function add_scwordform_submenus_create_forms_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			if ( isset( $_GET['wordform-edit-id'] ) && ! empty( $_GET['wordform-edit-id'] ) ) {
				$wordform_id = isset( $_GET['wordform-edit-id'] ) && ! empty( $_GET['wordform-edit-id'] ) ? sanitize_text_field( $_GET['wordform-edit-id'] ) : '';
				global $wpdb;
				$table         = $wpdb->prefix . self::$sc_wordform_tbl;
				$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE form_id=%s ORDER BY id DESC', array( $table, $wordform_id ) ), ARRAY_A );
			}
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/create_forms_callback_page.php';
		}

		/**
		 * FormsSubmission Report
		 * Submission Data: users submission Report menu callback function
		 * Table data loaded by ajax request - Datatable
		 * Ajax action name 'sc_wordform_users_submission_data_load' loaded dynamically when Table ID generated
		 */
		public static function add_scwordform_submenus_user_submission_report_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/user-submission-report-callback-page.php';
		}

		/**
		 * Forms Submission Data Detail		 
		 * Submission Data: users submission data detail hidden menu callback function
		 * Table data loaded by ajax request - Datatable
		 * Ajax action name 'sc_wordform_users_form_submission_data_load' loaded dynamically when Table ID generated
		 */
		public static function add_scwordform_submenus_user_form_submission_data_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/user-form-submission-data-callback-page.php';
		}

		/**
		 * Connection Status send log detail hidden page callback.
		 *
		 * @return void
		 */
		public static function add_scwordform_submenus_connection_status_send_log_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/connection-status-send-log-callback-page.php';
		}


		/**
		 * Callback Function
		 * Settings : validation Tab
		 * Get default validation messages for all forms initially
		 * Default 'all_form' validation messages display
		 */
		public static function add_scwordform_submenus_settings_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			$all_created_forms   = self::sc_wordform_get_all_created_forms_data();
			$validation_messages = self::sc_wordform_get_validation_messages_data_by_formid( 'all_form' );
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/settings_callback_page.php';
		}

		/**
		 * Callback Function
		 * Connects Page		 		 
		 */
		public static function add_scwordform_submenus_connects_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/connects-callback-page.php';
		}


		/**
		 * Callback Function
		 * License Page		 		 
		 */
		public static function add_scwordform_submenus_license_callback() {
			// check user capabilities
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/license-callback-page.php';
		}
		
		/**
		 * Get all created forms data
		 *
		 * @since 1.0.0
		 * return - array - All created forms data
		 */
		public static function sc_wordform_get_all_created_forms_data() {
			global $wpdb;
			$table         = $wpdb->prefix . self::$sc_wordform_tbl;
			$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id DESC', $table ), ARRAY_A );
			return $query_results;
		}


		/**
		 * Table: wp_scwordform_configured_applications 
		 * Check & change applications 'configured_status' into 'inactive' based on re-authentication requires
		 * @param string $application_slug
		 * @since 1.0.0
		 * @return - boolean 0 | 1
		 */
		public static function wordform_check_n_change_configured_status_applications( $application_slug = null ) {
			global $wpdb;
			$update_result = 0;
			$table         = $wpdb->prefix . self::$sc_wordform_configured_application_tbl;			
			$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE application_slug = %s AND configured_status = %s ORDER BY id DESC', [ $table, $application_slug, 'active' ] ), ARRAY_A );						
			if ( $query_results && array_filter( $query_results ) ) {
				$id = isset( $query_results[0]['id'] )? $query_results[0]['id'] : 0;
				$update_result = $wpdb->update( $table, [ 'configured_status' => 'inactive'], [ 'id' => $id ], [ '%s' ], [ '%d' ] );	
			}
			return $update_result;
		}

		/**
		 * Get all application names which are configured successfully
		 *
		 * @since 1.0.0
		 * return - array - All active configured application names
		 */
		public static function wordform_get_all_configured_application_names() {
			global $wpdb;
			$table         = $wpdb->prefix . self::$sc_wordform_configured_application_tbl;
			// $query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id DESC', $table ), ARRAY_A );
			$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE configured_status = %s ORDER BY id DESC', [ $table, 'active' ] ), ARRAY_A );
			return $query_results;
		}


		/**
		 * Menu - Settings - Validation Tab
		 * Settings validation messages Tab dropdown forms list
		 * Inner join validation messages table with created forms table
		 * Skipping deleted forms display to validation messages setting dropdown forms list by inner join
		 *
		 * @since 1.0.0
		 * return - array - [ id, form_name, form_id ]
		 */
		/*
		public static function wordform_validation_messages_table_inner_join_with_created_forms_table() {
		global $wpdb;
		$wordform_table = $wpdb->prefix . self::$sc_wordform_tbl;
		$wordform_validation_table = $wpdb->prefix . self::$sc_wordform_validation_messages_tbl;
		$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT wcf.id, form_name, wcf.form_id FROM %i as wvm INNER JOIN %i as wcf ON wvm.form_id = wcf.form_id WHERE form_name IS NOT NULL ORDER BY wvm.id DESC', [ $wordform_validation_table, $wordform_table ] ), ARRAY_A );
		return $query_results;
		}*/

		/**
		 * Submisson Report Against each From - Group by form_id
		 * Menu - Submission Report
		 * Inner join users submission data table with created forms table
		 * Skipping deleted forms users submission data table by inner join
		 *
		 * @since 1.0.0
		 * return - JSON 
		 */
		private static function wordform_get_submission_report_page_summary() {
			global $wpdb;

			$wordform_table            = $wpdb->prefix . self::$sc_wordform_tbl;
			$wordform_submission_table = $wpdb->prefix . self::$sc_wordform_submission_tbl;

			$total_forms_with_submission = (int) $wpdb->get_var(
				"SELECT COUNT(DISTINCT form_id) FROM $wordform_submission_table"
			);

			$total_submissions = (int) $wpdb->get_var(
				"SELECT COUNT(*) FROM $wordform_submission_table"
			);

			$latest_submission = $wpdb->get_row(
				"SELECT wcf.form_name, wst.created_at
				FROM $wordform_submission_table AS wst
				INNER JOIN $wordform_table AS wcf ON wcf.form_id = wst.form_id
				ORDER BY wst.created_at DESC
				LIMIT 1",
				ARRAY_A
			);

			$average_submissions = $total_forms_with_submission > 0 ? round( $total_submissions / $total_forms_with_submission, 1 ) : 0;
			$latest_submission_label = __( 'No submissions yet', 'wordform-pro' );

			if ( ! empty( $latest_submission['created_at'] ) ) {
				$latest_submission_label = sprintf(
					'%1$s, %2$s',
					sanitize_text_field( $latest_submission['form_name'] ?? __( 'Unknown form', 'wordform-pro' ) ),
					wp_date( 'd M Y, g:i a', strtotime( $latest_submission['created_at'] ) )
				);
			}

			return array(
				'forms'   => $total_forms_with_submission,
				'total'   => $total_submissions,
				'average' => $average_submissions,
				'latest'  => $latest_submission_label,
			);
		}

		/**
		 * Support page callback.
		 *
		 * @return void
		 */
		public static function add_scwordform_submenus_support_callback() {
			if ( ! current_user_can( 'manage_options' ) ) {
				return;
			}

			$support_prefill_data = SftcyWordformSupport::get_support_prefill_data();
			include_once SFTCY_WORDFORM_PLUGIN_DIR . 'admin/views/support-callback-page.php';
		}

		public static function wordform_submission_report_table_inner_join_with_created_forms_table($postData = []) {
			global $wpdb;
			$wordform_table            = $wpdb->prefix . self::$sc_wordform_tbl;
			$wordform_submission_table = $wpdb->prefix . self::$sc_wordform_submission_tbl;

			// DataTables params
			$draw   = isset($postData['draw']) ? intval($postData['draw']) : 1;
			$start  = isset($postData['start']) ? intval($postData['start']) : 0;
			$length = isset($postData['length']) ? intval($postData['length']) : 10;

			$order_col_index = isset($postData['order'][0]['column']) ? intval($postData['order'][0]['column']) : 2;
			$order_dir       = (isset($postData['order'][0]['dir']) && strtolower($postData['order'][0]['dir']) === 'asc') ? 'ASC' : 'DESC';			

			// Map columns
			$columns = [
				0 => 'wcf.form_name',
				1 => 'total_submission',
				2 => 'last_submission_date'
			];
			$order_column = $columns[$order_col_index] ?? 'last_submission_date';

			// Search
			$search_value = isset($postData['search']['value']) ? $postData['search']['value'] : '';
			$where = '';
			$where_params = [];
			if (!empty($search_value)) {
				$like = '%' . $wpdb->esc_like($search_value) . '%';
				$where = "WHERE (wcf.form_name LIKE %s OR DATE_FORMAT(wst.created_at, '%%M %%e, %%Y') LIKE %s)";
				$where_params[] = $like; // form_name
				$where_params[] = $like; // formatted date like "October 2, 2025"
			}

			// Total records
			$recordsTotal = (int) $wpdb->get_var("SELECT COUNT(DISTINCT form_id) FROM $wordform_submission_table");

			// Filtered count
			$recordsFiltered = $recordsTotal;
			if (!empty($where)) {
				$sql_count = "SELECT COUNT(*) FROM (
								SELECT wcf.form_id
								FROM $wordform_table AS wcf
								INNER JOIN $wordform_submission_table AS wst ON wcf.form_id = wst.form_id
								$where
								GROUP BY wcf.form_id
							) AS sub";
				$recordsFiltered = (int) $wpdb->get_var($wpdb->prepare($sql_count, $where_params));
			}

			// Main query (group by form_id)
			$sql = "SELECT wcf.form_id, wcf.form_name,
							COUNT(wst.id) AS total_submission,
							MAX(wst.created_at) AS last_submission_date
					FROM $wordform_table AS wcf
					INNER JOIN $wordform_submission_table AS wst ON wcf.form_id = wst.form_id
					$where
					GROUP BY wcf.form_id
					ORDER BY $order_column $order_dir
					LIMIT %d OFFSET %d";

			$query_params = array_merge($where_params, [$length, $start]);
			$results = $wpdb->get_results($wpdb->prepare($sql, $query_params), ARRAY_A);
				
			// Format safely
			$data = [];
			foreach ($results as $row) {
				$temp = [];

				$form_id = isset($row['form_id']) ?  $row['form_id'] : '';
				$form_name = isset($row['form_name']) ? $row['form_name'] : '';
				$last_submission_date = isset($row['last_submission_date']) ? $row['last_submission_date'] : '';
								
				$form_url = admin_url('admin.php?page=sc-wordform-user-form-submission-data');
				$form_url = add_query_arg( 'form_id', $form_id, $form_url );
				$temp['formName'] = sprintf('<a href="%s">%s</a>', esc_url($form_url), esc_html($form_name));										

				$totalSubmission = isset($row['total_submission']) ? intval($row['total_submission']) : 0;
				$temp['totalSubmission'] = sprintf('<a href="%s">%s</a>', esc_url($form_url), $totalSubmission );
				$temp['lastSubmissionDate'] = $last_submission_date ? wp_date( 'd M Y, g:i a', strtotime( $last_submission_date ) ) : '';

				$data[] = $temp;
			}

			return [
				"draw"            => $draw,
				"recordsTotal"    => $recordsTotal,
				"recordsFiltered" => $recordsFiltered,
				"summary"         => self::wordform_get_submission_report_page_summary(),
				"data"            => $data
			];
		}


		/**
		 * Submission data Detail by Form-Wise
		 * Menu - Submission Data Detail
		 * Inner join users submission data table with created forms table
		 * Skipping deleted forms users submission data table by inner join
		 *
		 * @since 1.0.0
		 * return - JSON 
		 */
		private static function wordform_get_processed_submission_rows( $submission_data = '' ) {
			$decoded_submission = json_decode( (string) $submission_data, true );
			$decoded_submission = is_array( $decoded_submission ) ? $decoded_submission : array();

			SftcyWordformFormSubmission::$sc_wordform_submission_array_data     = $decoded_submission;
			SftcyWordformFormSubmission::$sc_wordform_processed_forms_raw_data  = array();
			SftcyWordformFormSubmission::$sc_wordform_return_processed_raw_data = true;

			$processed_rows = SftcyWordformFormSubmission::sc_wordform_process_submission_data();

			SftcyWordformFormSubmission::$sc_wordform_submission_array_data     = array();
			SftcyWordformFormSubmission::$sc_wordform_processed_forms_raw_data  = array();
			SftcyWordformFormSubmission::$sc_wordform_return_processed_raw_data = false;

			return is_array( $processed_rows ) ? $processed_rows : array();
		}

		/**
		 * Flatten a submission field value into a single readable string.
		 *
		 * @param mixed $value Field value.
		 * @return string
		 */
		private static function wordform_format_submission_field_value( $value ) {
			if ( is_array( $value ) ) {
				$flattened = array();

				array_walk_recursive(
					$value,
					function( $item ) use ( &$flattened ) {
						if ( is_scalar( $item ) ) {
							$item = trim( (string) $item );
							if ( '' !== $item ) {
								$flattened[] = $item;
							}
						}
					}
				);

				return implode( ', ', array_unique( $flattened ) );
			}

			return is_scalar( $value ) ? trim( (string) $value ) : '';
		}

		/**
		 * Check whether a submission value represents uploaded file URLs.
		 *
		 * @param string $label Field label.
		 * @param string $value Flattened field value.
		 * @return bool
		 */
		private static function wordform_is_upload_submission_value( $label = '', $value = '' ) {
			$label = strtolower( sanitize_text_field( $label ) );
			$value = trim( (string) $value );

			if ( '' === $value ) {
				return false;
			}

			if ( false !== strpos( $label, 'upload' ) || false !== strpos( $label, 'file' ) ) {
				return true;
			}

			return false !== strpos( $value, '/uploads/wordform/' ) || false !== strpos( $value, 'http://' ) || false !== strpos( $value, 'https://' );
		}

		/**
		 * Extract uploaded file URLs from a flattened submission value.
		 *
		 * @param string $value Flattened field value.
		 * @return array
		 */
		private static function wordform_get_submission_file_urls( $value = '' ) {
			$value = trim( (string) $value );
			if ( '' === $value ) {
				return array();
			}

			$parts = preg_split( '/[\r\n,]+/', $value );
			$urls  = array();

			foreach ( $parts as $part ) {
				$part = trim( (string) $part );
				if ( '' === $part ) {
					continue;
				}

				if ( filter_var( $part, FILTER_VALIDATE_URL ) ) {
					$urls[] = esc_url_raw( $part );
				}
			}

			return array_values( array_unique( array_filter( $urls ) ) );
		}

		/**
		 * Build submission detail HTML for a field value.
		 *
		 * @param string $label Field label.
		 * @param string $value Flattened field value.
		 * @return string
		 */
		private static function wordform_get_submission_field_value_html( $label = '', $value = '', $processed_row = array() ) {
			$field_type = isset( $processed_row['formFieldType'] ) ? sanitize_key( $processed_row['formFieldType'] ) : '';
			$raw_value  = isset( $processed_row['formRawValue'] ) ? trim( (string) $processed_row['formRawValue'] ) : '';

			if ( 'signature' === $field_type && '' !== $raw_value && 0 === strpos( $raw_value, 'data:image/png;base64,' ) ) {
				return sprintf(
					'<div class="wordform-submission-signature-preview"><img src="%1$s" alt="%2$s" loading="lazy" /></div>',
					esc_attr( $raw_value ),
					esc_attr__( 'Submitted signature', 'wordform-pro' )
				);
			}

			if ( 'richeditor' === $field_type && '' !== $raw_value ) {
				return '<div class="wordform-submission-richtext-preview">' . wp_kses_post( $raw_value ) . '</div>';
			}

			if ( self::wordform_is_upload_submission_value( $label, $value ) ) {
				$file_urls = self::wordform_get_submission_file_urls( $value );

				if ( ! empty( $file_urls ) ) {
					$list_items = array();

					foreach ( $file_urls as $file_url ) {
						$file_name = wp_basename( wp_parse_url( $file_url, PHP_URL_PATH ) );
						$list_items[] = sprintf(
							'<li><a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a></li>',
							esc_url( $file_url ),
							esc_html( urldecode( $file_name ) )
						);
					}

					return '<ul class="wordform-submission-upload-file-list">' . implode( '', $list_items ) . '</ul>';
				}
			}

			return nl2br( esc_html( $value ) );
		}

		/**
		 * Extract a compact submitter string from processed submission rows.
		 *
		 * @param array $processed_rows Processed submission rows.
		 * @return string
		 */
		private static function wordform_is_submission_identity_skip_label( $label = '' ) {
			$label = strtolower( sanitize_text_field( $label ) );

			if ( '' === $label ) {
				return true;
			}

			$blocked_keywords = array(
				'payment',
				'amount',
				'quantity',
				'summary',
				'total',
				'stripe',
				'paypal',
				'square',
				'authorize',
				'captcha',
				'card',
				'cvv',
				'expiry',
				'zip',
				'postal',
				'terms',
			);

			foreach ( $blocked_keywords as $keyword ) {
				if ( false !== strpos( $label, $keyword ) ) {
					return true;
				}
			}

			return false;
		}

		private static function wordform_get_submission_submitter_label( $processed_rows = array(), $submission_id = 0 ) {
			$email_value = '';
			$name_parts  = array();
			$phone_value = '';
			$fallback    = '';

			foreach ( $processed_rows as $row ) {
				$label = isset( $row['formLabelName'] ) ? sanitize_text_field( $row['formLabelName'] ) : '';
				$value = self::wordform_format_submission_field_value( $row['formFieldValues'] ?? '' );

				if ( '' === $label || '' === $value ) {
					continue;
				}

				$label_key = strtolower( $label );

				if ( '' === $email_value && ( false !== strpos( $label_key, 'email' ) || is_email( $value ) ) ) {
					$email_value = sanitize_email( $value );
					continue;
				}

				if ( false !== strpos( $label_key, 'name' ) ) {
					$name_parts[] = $value;
					continue;
				}

				if ( '' === $phone_value && false !== strpos( $label_key, 'phone' ) ) {
					$phone_value = $value;
					continue;
				}

				if ( self::wordform_is_submission_identity_skip_label( $label_key ) ) {
					continue;
				}

				if ( '' === $fallback ) {
					$fallback = $value;
				}
			}

			if ( ! empty( $name_parts ) ) {
				$name_parts = array_unique( array_filter( array_map( 'trim', $name_parts ) ) );
				if ( ! empty( $name_parts ) ) {
					return implode( ' ', $name_parts );
				}
			}

			if ( ! empty( $email_value ) ) {
				return $email_value;
			}

			if ( ! empty( $phone_value ) ) {
				return $phone_value;
			}

			if ( '' !== $fallback ) {
				return $fallback;
			}

			return $submission_id > 0 ? sprintf( __( 'Submission #%d', 'wordform-pro' ), $submission_id ) : __( 'Unknown submitter', 'wordform-pro' );
		}

		/**
		 * Build compact preview HTML for submission rows.
		 *
		 * @param array $processed_rows Processed submission rows.
		 * @return string
		 */
		private static function wordform_get_submission_preview_html( $processed_rows = array() ) {
			$preview_items = array();
			$skip_labels   = array(
				'stripe',
				'paypal',
				'square',
				'authorize.net',
				'payment summary',
			);

			foreach ( $processed_rows as $row ) {
				$label = isset( $row['formLabelName'] ) ? sanitize_text_field( $row['formLabelName'] ) : '';
				$value = self::wordform_format_submission_field_value( $row['formFieldValues'] ?? '' );

				if ( '' === $label || '' === $value ) {
					continue;
				}

				if ( in_array( strtolower( $label ), $skip_labels, true ) ) {
					continue;
				}

				if ( self::wordform_is_upload_submission_value( $label, $value ) ) {
					$file_urls = self::wordform_get_submission_file_urls( $value );
					$preview_value = ! empty( $file_urls ) ? sprintf(
						_n( '%d file attached', '%d files attached', count( $file_urls ), 'wordform-pro' ),
						count( $file_urls )
					) : esc_html__( 'Uploaded file attached', 'wordform-pro' );

					$preview_items[] = sprintf(
						'<li><strong>%1$s:</strong> %2$s</li>',
						esc_html( $label ),
						esc_html( $preview_value )
					);

					if ( count( $preview_items ) >= 3 ) {
						break;
					}

					continue;
				}

				$preview_items[] = sprintf(
					'<li><strong>%1$s:</strong> %2$s</li>',
					esc_html( $label ),
					esc_html( wp_html_excerpt( $value, 80, '...' ) )
				);

				if ( count( $preview_items ) >= 3 ) {
					break;
				}
			}

			if ( empty( $preview_items ) ) {
				return '<span class="wordform-submission-preview-empty">' . esc_html__( 'No preview available.', 'wordform-pro' ) . '</span>';
			}

			return '<ul class="wordform-submission-preview-list">' . implode( '', $preview_items ) . '</ul>';
		}

		/**
		 * Build modal table HTML for a submission record.
		 *
		 * @param array $processed_rows Processed submission rows.
		 * @return string
		 */
		private static function wordform_get_submission_detail_table_html( $processed_rows = array() ) {
			$table_rows = array();

			foreach ( $processed_rows as $row ) {
				$label = isset( $row['formLabelName'] ) ? sanitize_text_field( $row['formLabelName'] ) : '';
				$value = self::wordform_format_submission_field_value( $row['formFieldValues'] ?? '' );

				if ( '' === $label && '' === $value ) {
					continue;
				}

				$table_rows[] = sprintf(
					'<tr><th>%1$s</th><td>%2$s</td></tr>',
					esc_html( $label ),
					self::wordform_get_submission_field_value_html( $label, $value, $row )
				);
			}

			if ( empty( $table_rows ) ) {
				return '<p>' . esc_html__( 'No submission data found.', 'wordform-pro' ) . '</p>';
			}

			return '<table class="widefat striped wordform-submission-detail-table"><tbody>' . implode( '', $table_rows ) . '</tbody></table>';
		}

		/**
		 * Build summary counts for a form-specific submission detail page.
		 *
		 * @param string $form_id WordForm ID.
		 * @return array
		 */
		private static function wordform_get_submission_data_page_summary( $form_id = '' ) {
			global $wpdb;

			$form_id = sanitize_text_field( $form_id );
			if ( '' === $form_id ) {
				return array(
					'total'  => 0,
					'today'  => 0,
					'week'   => 0,
					'latest' => __( 'No submissions yet', 'wordform-pro' ),
				);
			}

			$table       = $wpdb->prefix . self::$sc_wordform_submission_tbl;
			$timezone    = wp_timezone();
			$now         = new DateTimeImmutable( 'now', $timezone );
			$today_start = $now->setTime( 0, 0, 0 );
			$week_start  = $today_start->modify( 'monday this week' );

			$total_submissions = (int) $wpdb->get_var(
				$wpdb->prepare(
					"SELECT COUNT(*) FROM $table WHERE form_id = %s",
					$form_id
				)
			);

			$today_submissions = (int) $wpdb->get_var(
				$wpdb->prepare(
					"SELECT COUNT(*) FROM $table WHERE form_id = %s AND created_at >= %s",
					$form_id,
					$today_start->format( 'Y-m-d H:i:s' )
				)
			);

			$week_submissions = (int) $wpdb->get_var(
				$wpdb->prepare(
					"SELECT COUNT(*) FROM $table WHERE form_id = %s AND created_at >= %s",
					$form_id,
					$week_start->format( 'Y-m-d H:i:s' )
				)
			);

			$latest_submission = $wpdb->get_var(
				$wpdb->prepare(
					"SELECT created_at FROM $table WHERE form_id = %s ORDER BY created_at DESC LIMIT 1",
					$form_id
				)
			);

			return array(
				'total'  => $total_submissions,
				'today'  => $today_submissions,
				'week'   => $week_submissions,
				'latest' => ! empty( $latest_submission ) ? wp_date( 'd M Y, g:i a', strtotime( $latest_submission ) ) : __( 'No submissions yet', 'wordform-pro' ),
			);
		}

		public static function wordform_submission_data_table_inner_join_with_created_forms_table($postData = []) {
			global $wpdb;
			$wordform_table            = $wpdb->prefix . self::$sc_wordform_tbl;
			$wordform_submission_table = $wpdb->prefix . self::$sc_wordform_submission_tbl;

			// Get form_id safely
			$form_id = isset($postData['form_id']) ? (string) $postData['form_id'] : '';
			if (empty($form_id)) {
				return [
					"draw" => intval($postData['draw'] ?? 1),
					"recordsTotal" => 0,
					"recordsFiltered" => 0,
					"summary" => self::wordform_get_submission_data_page_summary( '' ),
					"data" => []
				];
			}

			// DataTables params
			$draw   = intval($postData['draw'] ?? 1);
			$start  = intval($postData['start'] ?? 0);
			$length = intval($postData['length'] ?? 10);

			$order_col_index = intval($postData['order'][0]['column'] ?? 2);
			$order_dir       = (isset($postData['order'][0]['dir']) && strtolower($postData['order'][0]['dir']) === 'asc') ? 'ASC' : 'DESC';

			$columns = [
				0 => 'wst.submission_data',
				1 => 'wst.submission_data',
				2 => 'wst.created_at',
				3 => 'wst.created_at'
			];
			$order_column = $columns[$order_col_index] ?? 'wst.created_at';

			// Search filter
			// $search_value = isset($postData['search']['value']) ? (string) $postData['search']['value'] : '';
			// $where = "WHERE wcf.form_id = %s";
			// $where_params = [$form_id];

			// if (!empty($search_value)) {
			// 	$like = '%' . $wpdb->esc_like($search_value) . '%';
			// 	$where .= " AND (wst.submission_data LIKE %s)";
			// 	$where_params[] = $like;
			// }

			// Search filter
			$search_value = isset($postData['search']['value']) ? (string) $postData['search']['value'] : '';
			$where = "WHERE wcf.form_id = %s";
			$where_params = [$form_id];

			if (!empty($search_value)) {
				$like = '%' . $wpdb->esc_like($search_value) . '%';
				$where .= " AND (wst.submission_data LIKE %s OR wcf.form_name LIKE %s OR DATE_FORMAT(wst.created_at, '%%M %%e, %%Y') LIKE %s)";
				$where_params[] = $like; // submission_data
				$where_params[] = $like; // form_name
				$where_params[] = $like; // formatted date (e.g. "September 15, 2025")
			}


			// Total records for this form
			$recordsTotal = (int) $wpdb->get_var($wpdb->prepare(
				"SELECT COUNT(*) FROM $wordform_submission_table WHERE form_id = %s",
				$form_id
			));

			// Total filtered
			$recordsFiltered = $recordsTotal;
			if (!empty($search_value)) {
				$recordsFiltered = (int) $wpdb->get_var($wpdb->prepare(
					"SELECT COUNT(*) 
					FROM $wordform_table AS wcf 
					INNER JOIN $wordform_submission_table AS wst ON wcf.form_id = wst.form_id
					$where",
					$where_params
				));
			}

			// Main query
			$sql = "SELECT wcf.form_name, wst.id, wst.submission_data, wst.created_at
					FROM $wordform_table AS wcf
					INNER JOIN $wordform_submission_table AS wst ON wcf.form_id = wst.form_id
					$where
					ORDER BY $order_column $order_dir
					LIMIT %d OFFSET %d";

			$query_params = array_merge($where_params, [$length, $start]);
			$results = $wpdb->get_results($wpdb->prepare($sql, $query_params), ARRAY_A);

			// Format safely
			$data = [];
			foreach ($results as $row) {
				$temp = [];

				$form_name       = isset($row['form_name']) ? (string) $row['form_name'] : '';
				$submission_id   = isset($row['id']) ? (int) $row['id'] : 0;
				$submission_data = isset($row['submission_data']) ? (string) $row['submission_data'] : '';
				$created_at      = isset($row['created_at']) ? (string) $row['created_at'] : '';
				$processed_rows  = self::wordform_get_processed_submission_rows( $submission_data );
				$detail_payload  = array(
					'formName'           => sanitize_text_field( $form_name ),
					'formId'             => sanitize_text_field( $form_id ),
					'submissionId'       => $submission_id,
					'submitter'          => self::wordform_get_submission_submitter_label( $processed_rows, $submission_id ),
					'submissionDate'     => $created_at ? wp_date( 'd M Y, g:i a', strtotime( $created_at ) ) : '',
					'submissionDataHtml' => self::wordform_get_submission_detail_table_html( $processed_rows ),
				);

				$temp['submitter'] = '<span class="wordform-submission-submitter-name">' . esc_html( $detail_payload['submitter'] ) . '</span>';
				$temp['preview']   = self::wordform_get_submission_preview_html( $processed_rows );
				$temp['date']      = $detail_payload['submissionDate'];
				$temp['details']   = '<button type="button" class="button button-secondary wordform-open-submission-detail-modal" data-submission-detail="' . esc_attr( wp_json_encode( $detail_payload ) ) . '">' . esc_html__( 'View Data', 'wordform-pro' ) . '</button>';

				$data[] = $temp;
			}

			return [
				"draw"            => $draw,
				"recordsTotal"    => $recordsTotal,
				"recordsFiltered" => $recordsFiltered,
				"summary"         => self::wordform_get_submission_data_page_summary( $form_id ),
				"data"            => $data
			];
		}

		/**
		 * Export all submissions of a specific form as an Excel workbook.
		 *
		 * @return void
		 */
		public static function sc_wordform_export_form_submissions() {
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_die( esc_html__( 'You do not have permission to export submission data.', 'wordform-pro' ) );
			}

			$form_id = isset( $_REQUEST['form_id'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['form_id'] ) ) : '';
			if ( '' === $form_id ) {
				wp_die( esc_html__( 'Invalid form export request.', 'wordform-pro' ) );
			}

			check_admin_referer( 'sc_wordform_export_form_submissions_' . $form_id );

			$selected_sheets = isset( $_REQUEST['export_sheets'] ) ? (array) wp_unslash( $_REQUEST['export_sheets'] ) : array( 'submissions', 'field_map', 'form_architecture' );
			$selected_sheets = array_values(
				array_intersect(
					array_map( 'sanitize_key', $selected_sheets ),
					array( 'submissions', 'field_map', 'form_architecture' )
				)
			);
			$submission_export_available = ! class_exists( 'SftcyWordformFeatures' ) || SftcyWordformFeatures::wordform_is_feature_available( 'form_submission_export' );
			if ( ! $submission_export_available && in_array( 'submissions', $selected_sheets, true ) ) {
				$selected_sheets = array_values( array_diff( $selected_sheets, array( 'submissions' ) ) );
			}

			if ( empty( $selected_sheets ) ) {
				if ( ! $submission_export_available ) {
					$upgrade_url = defined( 'SFTCY_WORDFORM_PRODUCT_URL' ) ? SFTCY_WORDFORM_PRODUCT_URL : 'https://softcoy.com/products/wordform-pro';
					wp_die(
						wp_kses_post(
							sprintf(
								/* translators: %s: WordForm Pro product URL. */
								__( 'Submission data export is a WordForm Pro feature. <a href="%s">Upgrade to WordForm Pro</a> to export submissions.', 'wordform-pro' ),
								esc_url( $upgrade_url )
							)
						)
					);
				}
				wp_die( esc_html__( 'Select at least one sheet to export.', 'wordform-pro' ) );
			}

			$form_data = self::sc_wordform_db_query( $form_id );
			if ( empty( $form_data ) || empty( $form_data[0]['form_id'] ) ) {
				wp_die( esc_html__( 'The requested form could not be found.', 'wordform-pro' ) );
			}

			$composer_autoload = SFTCY_WORDFORM_PLUGIN_DIR . 'vendor/autoload.php';
			if ( ! file_exists( $composer_autoload ) ) {
				wp_die( esc_html__( 'PhpSpreadsheet is not installed. Please install plugin dependencies first.', 'wordform-pro' ) );
			}

			require_once $composer_autoload;

			$form_name        = sanitize_text_field( $form_data[0]['form_name'] );
			$form_definition  = json_decode( (string) $form_data[0]['form'], true );
			$form_definition  = is_array( $form_definition ) ? $form_definition : array();
			$submission_rows  = self::wordform_get_submission_export_records( $form_id );
			$export_dataset   = self::wordform_build_submission_export_dataset( $form_id, $form_name, $form_definition, $submission_rows );
			$spreadsheet      = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
			$spreadsheet->getProperties()
				->setCreator( 'WordForm' )
				->setTitle( $form_name . ' - Submissions Export' )
				->setSubject( 'WordForm submissions export' )
				->setDescription( 'Submission export generated by WordForm.' );
			$spreadsheet->getDefaultStyle()->getFont()->setName( 'Calibri' )->setSize( 11 );
			$dynamic_headers = self::wordform_get_submission_export_dynamic_headers( $export_dataset['schema']['fields'] );
			$created_sheet_count = 0;

			if ( in_array( 'submissions', $selected_sheets, true ) ) {
				$submission_sheet = 0 === $created_sheet_count ? $spreadsheet->getActiveSheet() : $spreadsheet->createSheet();
				$submission_sheet->setTitle( 'Submissions' );
				self::wordform_populate_submission_export_sheet( $submission_sheet, $export_dataset, $dynamic_headers );
				$created_sheet_count++;
			}

			if ( in_array( 'field_map', $selected_sheets, true ) ) {
				$field_map_sheet = 0 === $created_sheet_count ? $spreadsheet->getActiveSheet() : $spreadsheet->createSheet();
				$field_map_sheet->setTitle( 'Field Map' );
				self::wordform_populate_submission_export_field_map_sheet( $field_map_sheet, $export_dataset['schema']['fields'], $dynamic_headers );
				$created_sheet_count++;
			}

			if ( in_array( 'form_architecture', $selected_sheets, true ) ) {
				$architecture_sheet = 0 === $created_sheet_count ? $spreadsheet->getActiveSheet() : $spreadsheet->createSheet();
				$architecture_sheet->setTitle( 'Form Architecture' );
				self::wordform_populate_submission_export_architecture_sheet( $architecture_sheet, $form_id, $form_name, $form_definition, count( $export_dataset['rows'] ) );
				$created_sheet_count++;
			}

			if ( in_array( 'submissions', $selected_sheets, true ) ) {
				$spreadsheet->setActiveSheetIndexByName( 'Submissions' );
			} else {
				$spreadsheet->setActiveSheetIndex( 0 );
			}

			$file_name = sanitize_title( $form_name ? $form_name : $form_id );
			$file_name = $file_name ? $file_name : 'wordform-submissions';
			$file_name .= '-' . wp_date( 'Y-m-d-His' ) . '.xlsx';

			while ( ob_get_level() > 0 ) {
				ob_end_clean();
			}

			nocache_headers();
			header( 'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' );
			header( 'Content-Disposition: attachment; filename="' . $file_name . '"' );
			header( 'Cache-Control: max-age=0' );
			header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
			header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
			header( 'Cache-Control: cache, must-revalidate' );
			header( 'Pragma: public' );

			$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx( $spreadsheet );
			$writer->save( 'php://output' );
			exit;
		}

		/**
		 * Fetch all saved submissions for a specific form export.
		 *
		 * @param string $form_id WordForm ID.
		 * @return array
		 */
		private static function wordform_get_submission_export_records( $form_id = '' ) {
			global $wpdb;

			$form_id = sanitize_text_field( $form_id );
			if ( '' === $form_id ) {
				return array();
			}

			$table = $wpdb->prefix . self::$sc_wordform_submission_tbl;

			return $wpdb->get_results(
				$wpdb->prepare(
					"SELECT id, submission_data, created_at
					FROM $table
					WHERE form_id = %s
					ORDER BY created_at DESC, id DESC",
					$form_id
				),
				ARRAY_A
			);
		}

		/**
		 * Build an export dataset from stored submissions and form architecture.
		 *
		 * @param string $form_id          WordForm ID.
		 * @param string $form_name        Human readable form name.
		 * @param array  $form_definition  Stored form JSON.
		 * @param array  $submission_rows  Saved submission rows.
		 * @return array
		 */
		private static function wordform_build_submission_export_dataset( $form_id = '', $form_name = '', $form_definition = array(), $submission_rows = array() ) {
			$schema        = self::wordform_build_submission_export_schema( $form_definition );
			$schema['include_submitter_column'] = ! self::wordform_submission_export_schema_has_identity_fields( $schema['fields'] );
			$exported_rows = array();

			foreach ( $submission_rows as $submission_row ) {
				$submission_id  = isset( $submission_row['id'] ) ? (int) $submission_row['id'] : 0;
				$processed_rows = self::wordform_get_processed_submission_rows( isset( $submission_row['submission_data'] ) ? $submission_row['submission_data'] : '' );
				$row_fields     = array();
				$row_label_hits = array();

				foreach ( $processed_rows as $processed_row ) {
					$value = self::wordform_format_submission_field_value( $processed_row['formFieldValues'] ?? '' );
					if ( '' === $value ) {
						continue;
					}

					$export_key = self::wordform_get_submission_export_processed_row_key( $processed_row, $schema, $row_label_hits );
					if ( '' === $export_key ) {
						continue;
					}

					$row_fields[ $export_key ] = self::wordform_append_submission_export_value(
						isset( $row_fields[ $export_key ] ) ? $row_fields[ $export_key ] : '',
						$value
					);
				}

				$exported_rows[] = array(
					'submission_id'   => $submission_id,
					'submission_date' => ! empty( $submission_row['created_at'] ) ? wp_date( 'd M Y, g:i a', strtotime( $submission_row['created_at'] ) ) : '',
					'submitter'       => self::wordform_get_submission_submitter_label( $processed_rows, $submission_id ),
					'fields'          => $row_fields,
				);
			}

			return array(
				'form_id'         => $form_id,
				'form_name'       => $form_name,
				'schema'          => $schema,
				'rows'            => $exported_rows,
				'form_definition' => $form_definition,
			);
		}

		/**
		 * Determine whether the schema already contains identity columns.
		 *
		 * @param array $fields Export schema fields.
		 * @return bool
		 */
		private static function wordform_submission_export_schema_has_identity_fields( $fields = array() ) {
			foreach ( $fields as $field ) {
				$visible_label = isset( $field['visible_label'] ) ? strtolower( sanitize_text_field( $field['visible_label'] ) ) : '';
				$admin_label   = isset( $field['admin_label'] ) ? strtolower( sanitize_key( $field['admin_label'] ) ) : '';
				$haystack      = trim( $visible_label . ' ' . str_replace( '_', ' ', $admin_label ) );

				if ( '' === $haystack ) {
					continue;
				}

				if (
					false !== strpos( $haystack, 'name' ) ||
					false !== strpos( $haystack, 'email' ) ||
					false !== strpos( $haystack, 'phone' ) ||
					false !== strpos( $haystack, 'mobile' )
				) {
					return true;
				}
			}

			return false;
		}

		/**
		 * Create stable header labels for dynamic submission fields.
		 *
		 * @param array $fields Export schema fields.
		 * @return array
		 */
		private static function wordform_get_submission_export_dynamic_headers( $fields = array() ) {
			$dynamic_headers = array();
			$used_headers    = array();

			foreach ( $fields as $field ) {
				$header_label = ! empty( $field['visible_label'] ) ? $field['visible_label'] : $field['export_key'];
				$header_base  = $header_label;
				$header_index = 2;

				while ( isset( $used_headers[ strtolower( $header_label ) ] ) ) {
					$header_label = $header_base . ' (' . $header_index . ')';
					$header_index++;
				}

				$used_headers[ strtolower( $header_label ) ] = true;
				$dynamic_headers[ $field['export_key'] ]     = $header_label;
			}

			return $dynamic_headers;
		}

		/**
		 * Populate the Submissions export sheet.
		 *
		 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $submission_sheet Target sheet.
		 * @param array                                         $export_dataset   Dataset.
		 * @param array                                         $dynamic_headers  Header map.
		 * @return void
		 */
		private static function wordform_populate_submission_export_sheet( $submission_sheet, $export_dataset = array(), $dynamic_headers = array() ) {
			$include_submitter = ! empty( $export_dataset['schema']['include_submitter_column'] );
			$submission_headers = array(
				'Submission ID',
				'Submission Date',
			);

			if ( $include_submitter ) {
				$submission_headers[] = 'Submitter';
			}

			$submission_headers = array_merge( $submission_headers, array_values( $dynamic_headers ) );
			$submission_sheet->fromArray( $submission_headers, null, 'A1', true );

			$submission_row_number = 2;
			foreach ( $export_dataset['rows'] as $submission_row ) {
				$sheet_row = array(
					$submission_row['submission_id'],
					$submission_row['submission_date'],
				);

				if ( $include_submitter ) {
					$sheet_row[] = $submission_row['submitter'];
				}

				foreach ( array_keys( $dynamic_headers ) as $export_key ) {
					$sheet_row[] = isset( $submission_row['fields'][ $export_key ] ) ? $submission_row['fields'][ $export_key ] : '';
				}

				$submission_sheet->fromArray( $sheet_row, null, 'A' . $submission_row_number, true );
				$submission_row_number++;
			}

			$submission_highest_column = $submission_sheet->getHighestColumn();
			$submission_sheet->freezePane( 'A2' );
			$submission_sheet->setAutoFilter( 'A1:' . $submission_highest_column . '1' );
			self::wordform_style_submission_export_sheet( $submission_sheet, $submission_highest_column );
		}

		/**
		 * Populate the Field Map export sheet.
		 *
		 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $field_map_sheet Target sheet.
		 * @param array                                         $fields          Schema fields.
		 * @param array                                         $dynamic_headers Header map.
		 * @return void
		 */
		private static function wordform_populate_submission_export_field_map_sheet( $field_map_sheet, $fields = array(), $dynamic_headers = array() ) {
			$field_map_sheet->fromArray(
				array(
					'Export Key',
					'Header',
					'Visible Label',
					'Admin Label',
					'Field Type',
					'Source',
					'Notes',
				),
				null,
				'A1',
				true
			);

			$field_map_row = 2;
			foreach ( $fields as $field ) {
				$field_map_sheet->fromArray(
					array(
						$field['export_key'],
						isset( $dynamic_headers[ $field['export_key'] ] ) ? $dynamic_headers[ $field['export_key'] ] : $field['visible_label'],
						$field['visible_label'],
						$field['admin_label'],
						$field['field_type'],
						$field['source'],
						$field['notes'],
					),
					null,
					'A' . $field_map_row,
					true
				);
				$field_map_row++;
			}

			$field_map_highest_column = $field_map_sheet->getHighestColumn();
			$field_map_sheet->freezePane( 'A2' );
			$field_map_sheet->setAutoFilter( 'A1:' . $field_map_highest_column . '1' );
			self::wordform_style_submission_export_sheet( $field_map_sheet, $field_map_highest_column );
		}

		/**
		 * Populate the Form Architecture export sheet.
		 *
		 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $architecture_sheet Target sheet.
		 * @param string                                        $form_id             Form ID.
		 * @param string                                        $form_name           Form name.
		 * @param array                                         $form_definition     Stored form JSON.
		 * @param int                                           $submission_count    Total submissions.
		 * @return void
		 */
		private static function wordform_populate_submission_export_architecture_sheet( $architecture_sheet, $form_id = '', $form_name = '', $form_definition = array(), $submission_count = 0 ) {
			$architecture_sheet->setCellValue( 'A1', 'Form ID' );
			$architecture_sheet->setCellValue( 'B1', $form_id );
			$architecture_sheet->setCellValue( 'A2', 'Form Name' );
			$architecture_sheet->setCellValue( 'B2', $form_name );
			$architecture_sheet->setCellValue( 'A3', 'Exported At' );
			$architecture_sheet->setCellValue( 'B3', wp_date( 'Y-m-d H:i:s' ) );
			$architecture_sheet->setCellValue( 'A4', 'Total Submissions' );
			$architecture_sheet->setCellValue( 'B4', $submission_count );
			$architecture_sheet->setCellValue( 'A6', 'Raw Form JSON' );
			$architecture_sheet->setCellValue( 'B6', wp_json_encode( $form_definition, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) );
			$architecture_sheet->getStyle( 'A1:A6' )->getFont()->setBold( true );
			$architecture_sheet->getStyle( 'B6' )->getAlignment()->setWrapText( true )->setVertical( \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP );
			$architecture_sheet->getColumnDimension( 'A' )->setWidth( 22 );
			$architecture_sheet->getColumnDimension( 'B' )->setWidth( 120 );
			$architecture_sheet->getRowDimension( 6 )->setRowHeight( 260 );
		}

		/**
		 * Build the export field schema from the stored form JSON.
		 *
		 * @param array $form_definition Stored builder data.
		 * @return array
		 */
		private static function wordform_build_submission_export_schema( $form_definition = array() ) {
			$schema = array(
				'fields'          => array(),
				'lookup_by_admin' => array(),
				'lookup_by_label' => array(),
			);

			foreach ( $form_definition as $element ) {
				if ( ! is_array( $element ) ) {
					continue;
				}

				$type = isset( $element['type'] ) ? sanitize_key( $element['type'] ) : '';
				if ( in_array( $type, array( 'form-name', 'submit-button', 'sectionhtml', 'pagebreak', 'captcha', 'gcaptcha', 'hcaptcha' ), true ) ) {
					continue;
				}

				if ( 'firstlastname' === $type ) {
					self::wordform_register_submission_export_field(
						$schema,
						array(
							'field_type'    => $type,
							'visible_label' => isset( $element['labelFirst'] ) ? sanitize_text_field( $element['labelFirst'] ) : __( 'First Name', 'wordform-pro' ),
							'admin_label'   => isset( $element['adminLabelFirst'] ) ? sanitize_key( $element['adminLabelFirst'] ) : '',
							'element_index' => isset( $element['elementIndex'] ) ? sanitize_text_field( $element['elementIndex'] ) : '',
							'source'        => 'form_architecture',
							'notes'         => '',
						)
					);
					self::wordform_register_submission_export_field(
						$schema,
						array(
							'field_type'    => $type,
							'visible_label' => isset( $element['labelLast'] ) ? sanitize_text_field( $element['labelLast'] ) : __( 'Last Name', 'wordform-pro' ),
							'admin_label'   => isset( $element['adminLabelLast'] ) ? sanitize_key( $element['adminLabelLast'] ) : '',
							'element_index' => isset( $element['elementIndex'] ) ? sanitize_text_field( $element['elementIndex'] ) : '',
							'source'        => 'form_architecture',
							'notes'         => '',
						)
					);
					continue;
				}

				self::wordform_register_submission_export_field(
					$schema,
					array(
						'field_type'    => $type,
						'visible_label' => isset( $element['label'] ) ? sanitize_text_field( $element['label'] ) : ucwords( str_replace( array( '_', '-' ), ' ', $type ) ),
						'admin_label'   => isset( $element['adminLabel'] ) ? sanitize_key( $element['adminLabel'] ) : '',
						'element_index' => isset( $element['elementIndex'] ) ? sanitize_text_field( $element['elementIndex'] ) : '',
						'source'        => 'form_architecture',
						'notes'         => '',
					)
				);
			}

			return $schema;
		}

		/**
		 * Register a field in the export schema and keep lookups in sync.
		 *
		 * @param array $schema Schema array passed by reference.
		 * @param array $field  Field metadata.
		 * @return string
		 */
		private static function wordform_register_submission_export_field( &$schema, $field = array() ) {
			$field_type    = isset( $field['field_type'] ) ? sanitize_key( $field['field_type'] ) : 'field';
			$visible_label = isset( $field['visible_label'] ) ? sanitize_text_field( $field['visible_label'] ) : '';
			$admin_label   = isset( $field['admin_label'] ) ? sanitize_key( $field['admin_label'] ) : '';
			$element_index = isset( $field['element_index'] ) ? sanitize_text_field( $field['element_index'] ) : '';
			$source        = isset( $field['source'] ) ? sanitize_key( $field['source'] ) : 'form_architecture';
			$notes         = isset( $field['notes'] ) ? sanitize_text_field( $field['notes'] ) : '';
			$base_key      = $admin_label;

			if ( '' === $base_key ) {
				$base_key = sanitize_key( sanitize_title( $visible_label ? $visible_label : $field_type ) );
				if ( '' !== $element_index ) {
					$base_key .= '_' . sanitize_key( $element_index );
				}
			}

			if ( '' === $base_key ) {
				$base_key = 'field';
			}

			$export_key = $base_key;
			$counter    = 2;
			while ( isset( $schema['fields'][ $export_key ] ) ) {
				$export_key = $base_key . '_' . $counter;
				$counter++;
			}

			$schema['fields'][ $export_key ] = array(
				'export_key'    => $export_key,
				'visible_label' => $visible_label ? $visible_label : $export_key,
				'admin_label'   => $admin_label,
				'field_type'    => $field_type,
				'source'        => $source,
				'notes'         => $notes,
			);

			if ( '' !== $admin_label ) {
				$schema['lookup_by_admin'][ $admin_label ] = $export_key;
			}

			if ( '' !== $visible_label ) {
				$label_lookup_key = strtolower( $visible_label );
				if ( ! isset( $schema['lookup_by_label'][ $label_lookup_key ] ) ) {
					$schema['lookup_by_label'][ $label_lookup_key ] = array();
				}
				$schema['lookup_by_label'][ $label_lookup_key ][] = $export_key;
			}

			return $export_key;
		}

		/**
		 * Resolve or create an export column key for a processed submission row.
		 *
		 * @param array $processed_row   Normalized processed submission row.
		 * @param array $schema          Export schema passed by reference.
		 * @param array $row_label_hits  Per-row label hit counters passed by reference.
		 * @return string
		 */
		private static function wordform_get_submission_export_processed_row_key( $processed_row = array(), &$schema = array(), &$row_label_hits = array() ) {
			$admin_label = isset( $processed_row['formAdminLabel'] ) ? sanitize_key( $processed_row['formAdminLabel'] ) : '';
			$label       = isset( $processed_row['formLabelName'] ) ? sanitize_text_field( $processed_row['formLabelName'] ) : '';

			if ( '' !== $admin_label && isset( $schema['lookup_by_admin'][ $admin_label ] ) ) {
				return $schema['lookup_by_admin'][ $admin_label ];
			}

			$label_lookup_key = strtolower( $label );
			if ( '' !== $label_lookup_key && ! empty( $schema['lookup_by_label'][ $label_lookup_key ] ) ) {
				$matches  = $schema['lookup_by_label'][ $label_lookup_key ];
				$hit_index = isset( $row_label_hits[ $label_lookup_key ] ) ? (int) $row_label_hits[ $label_lookup_key ] : 0;
				$row_label_hits[ $label_lookup_key ] = $hit_index + 1;

				if ( isset( $matches[ $hit_index ] ) ) {
					return $matches[ $hit_index ];
				}

				return $matches[0];
			}

			return self::wordform_register_submission_export_field(
				$schema,
				array(
					'field_type'    => 'submission_data',
					'visible_label' => $label ? $label : __( 'Field', 'wordform-pro' ),
					'admin_label'   => $admin_label,
					'element_index' => '',
					'source'        => 'submission_data',
					'notes'         => __( 'Column was discovered from saved submission data and was not matched to current form architecture.', 'wordform-pro' ),
				)
			);
		}

		/**
		 * Append a field value into an export cell without losing earlier data.
		 *
		 * @param string $existing Existing cell value.
		 * @param string $incoming Incoming field value.
		 * @return string
		 */
		private static function wordform_append_submission_export_value( $existing = '', $incoming = '' ) {
			$existing = trim( (string) $existing );
			$incoming = trim( (string) $incoming );

			if ( '' === $incoming ) {
				return $existing;
			}

			if ( '' === $existing || $existing === $incoming ) {
				return $incoming;
			}

			return $existing . PHP_EOL . $incoming;
		}

		/**
		 * Apply shared workbook styles to an export sheet.
		 *
		 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet          Target worksheet.
		 * @param string                                        $highest_column Highest used column.
		 * @return void
		 */
		private static function wordform_style_submission_export_sheet( $sheet, $highest_column = 'A' ) {
			$highest_row = $sheet->getHighestRow();
			$sheet->getStyle( 'A1:' . $highest_column . '1' )->getFont()->setBold( true );
			$sheet->getStyle( 'A1:' . $highest_column . '1' )->getFill()->setFillType( \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID )->getStartColor()->setARGB( 'FFEFF6FF' );
			$sheet->getStyle( 'A1:' . $highest_column . $highest_row )->getAlignment()->setVertical( \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP );
			if ( $highest_row >= 2 ) {
				$sheet->getStyle( 'A2:' . $highest_column . $highest_row )->getAlignment()->setWrapText( true );
			}

			$highest_column_index = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString( $highest_column );
			for ( $column_index = 1; $column_index <= $highest_column_index; $column_index++ ) {
				$column_id = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex( $column_index );
				$sheet->getColumnDimension( $column_id )->setAutoSize( true );
			}
		}

		/**
		 * Payment report filter options for the Payment Reports settings tab.
		 *
		 * @return array
		 */
		public static function wordform_get_payment_report_filter_options() {
			return array(
				'gateways' => array(
					'stripe' => __( 'Stripe', 'wordform-pro' ),
					'paypal' => __( 'PayPal', 'wordform-pro' ),
					'square' => __( 'Square', 'wordform-pro' ),
					'authorizenet' => __( 'Authorize.Net', 'wordform-pro' ),
				),
				'statuses' => array(
					'success'    => __( 'Success', 'wordform-pro' ),
					'processing' => __( 'Processing', 'wordform-pro' ),
					'failed'     => __( 'Failed', 'wordform-pro' ),
					'unknown'    => __( 'Unknown', 'wordform-pro' ),
				),
			);
		}

		/**
		 * Normalize payment gateway statuses for reporting UI and filtering.
		 *
		 * @param string $gateway_slug Payment gateway slug.
		 * @param string $raw_status   Raw gateway status from saved submission data.
		 * @return array
		 */
		public static function wordform_get_payment_report_status_meta( $gateway_slug = '', $raw_status = '' ) {
			$gateway_slug = sanitize_key( $gateway_slug );
			$raw_status   = strtoupper( sanitize_text_field( $raw_status ) );
			$normalized_status = preg_replace( '/[^A-Z_]/', '', str_replace( array( ' ', '-' ), '_', $raw_status ) );

			if ( in_array( $normalized_status, array( 'SUCCEEDED', 'SUCCESS', 'COMPLETED', 'PAID' ), true ) ) {
				return array(
					'key'   => 'success',
					'label' => __( 'Success', 'wordform-pro' ),
				);
			}

			if ( in_array( $normalized_status, array( 'PROCESSING', 'PENDING', 'REQUIRES_CAPTURE', 'CREATED', 'APPROVED', 'AUTHORIZED_PENDING_CAPTURE' ), true ) ) {
				return array(
					'key'   => 'processing',
					'label' => __( 'Processing', 'wordform-pro' ),
				);
			}

			if ( in_array( $normalized_status, array( 'FAILED', 'CANCELED', 'VOIDED', 'DENIED', 'DECLINED', 'ERROR', 'SETTLEMENT_ERROR' ), true ) ) {
				return array(
					'key'   => 'failed',
					'label' => __( 'Failed', 'wordform-pro' ),
				);
			}

			return array(
				'key'   => 'unknown',
				'label' => $raw_status ? $raw_status : __( 'Unknown', 'wordform-pro' ),
			);
		}

		/**
		 * Build payment report DataTable rows from saved submission data.
		 *
		 * Current report is submission-backed, so only payment attempts that reached
		 * saved submission state can appear here.
		 *
		 * @param array $post_data DataTable request payload.
		 * @return array
		 */
		public static function wordform_get_payment_reports_table_data( $post_data = array() ) {
			global $wpdb;

			$wordform_table            = $wpdb->prefix . self::$sc_wordform_tbl;
			$wordform_submission_table = $wpdb->prefix . self::$sc_wordform_submission_tbl;
			$selected_form_id          = isset( $post_data['payment_report_form_id'] ) ? sanitize_text_field( $post_data['payment_report_form_id'] ) : '';
			$selected_gateway          = isset( $post_data['payment_report_gateway'] ) ? sanitize_key( $post_data['payment_report_gateway'] ) : '';
			$selected_status           = isset( $post_data['payment_report_status'] ) ? sanitize_key( $post_data['payment_report_status'] ) : '';
			$search_value              = isset( $post_data['search']['value'] ) ? sanitize_text_field( $post_data['search']['value'] ) : '';
			$draw                      = isset( $post_data['draw'] ) ? intval( $post_data['draw'] ) : 1;
			$start                     = isset( $post_data['start'] ) ? intval( $post_data['start'] ) : 0;
			$length                    = isset( $post_data['length'] ) ? intval( $post_data['length'] ) : 10;
			$order_col_index           = isset( $post_data['order'][0]['column'] ) ? intval( $post_data['order'][0]['column'] ) : 6;
			$order_dir                 = ( isset( $post_data['order'][0]['dir'] ) && strtolower( $post_data['order'][0]['dir'] ) === 'asc' ) ? 'asc' : 'desc';

			$where_clause = '';
			$where_params = array();
			if ( ! empty( $selected_form_id ) ) {
				$where_clause   = 'WHERE wcf.form_id = %s';
				$where_params[] = $selected_form_id;
			}

			$query = "SELECT wcf.form_id, wcf.form_name, wst.id AS submission_id, wst.submission_data, wst.created_at
				FROM $wordform_table AS wcf
				INNER JOIN $wordform_submission_table AS wst ON wcf.form_id = wst.form_id
				$where_clause
				ORDER BY wst.created_at DESC";

			$results = ! empty( $where_params ) ? $wpdb->get_results( $wpdb->prepare( $query, $where_params ), ARRAY_A ) : $wpdb->get_results( $query, ARRAY_A );
			$all_rows = array();

			foreach ( $results as $row ) {
				$submission_data = isset( $row['submission_data'] ) ? json_decode( $row['submission_data'], true ) : array();
				if ( empty( $submission_data ) || ! is_array( $submission_data ) ) {
					continue;
				}

				$gateway_rows = self::wordform_extract_payment_report_rows_from_submission(
					$submission_data,
					isset( $row['form_id'] ) ? $row['form_id'] : '',
					isset( $row['form_name'] ) ? $row['form_name'] : '',
					isset( $row['submission_id'] ) ? absint( $row['submission_id'] ) : 0,
					isset( $row['created_at'] ) ? $row['created_at'] : ''
				);

				if ( ! empty( $gateway_rows ) ) {
					$all_rows = array_merge( $all_rows, $gateway_rows );
				}
			}

			$records_total = count( $all_rows );

			if ( ! empty( $selected_gateway ) ) {
				$all_rows = array_values(
					array_filter(
						$all_rows,
						function( $row ) use ( $selected_gateway ) {
							return isset( $row['gatewaySlug'] ) && $row['gatewaySlug'] === $selected_gateway;
						}
					)
				);
			}

			if ( ! empty( $selected_status ) ) {
				$all_rows = array_values(
					array_filter(
						$all_rows,
						function( $row ) use ( $selected_status ) {
							return isset( $row['paymentStatusKey'] ) && $row['paymentStatusKey'] === $selected_status;
						}
					)
				);
			}

			if ( ! empty( $search_value ) ) {
				$all_rows = array_values(
					array_filter(
						$all_rows,
						function( $row ) use ( $search_value ) {
							$haystack = implode(
								' ',
								array(
									$row['formName'] ?? '',
									$row['gatewayName'] ?? '',
									$row['paymentStatusLabel'] ?? '',
									$row['paymentStatusRaw'] ?? '',
									$row['amount'] ?? '',
									$row['couponCode'] ?? '',
									$row['couponDiscount'] ?? '',
									$row['couponDisplayText'] ?? '',
									$row['currency'] ?? '',
									$row['transactionRef'] ?? '',
									$row['submissionDateRaw'] ?? '',
								)
							);
							return false !== stripos( $haystack, $search_value );
						}
					)
				);
			}

			$records_filtered = count( $all_rows );
			$order_map        = array(
				0 => 'formName',
				1 => 'gatewayName',
				2 => 'paymentStatusLabel',
				3 => 'amountNumeric',
				4 => 'couponDisplayText',
				5 => 'currency',
				6 => 'transactionRef',
				7 => 'submissionTimestamp',
			);
			$order_key        = isset( $order_map[ $order_col_index ] ) ? $order_map[ $order_col_index ] : 'submissionTimestamp';

			usort(
				$all_rows,
				function( $a, $b ) use ( $order_key, $order_dir ) {
					$value_a = isset( $a[ $order_key ] ) ? $a[ $order_key ] : '';
					$value_b = isset( $b[ $order_key ] ) ? $b[ $order_key ] : '';
					if ( $value_a === $value_b ) {
						return 0;
					}
					$comparison = ( $value_a < $value_b ) ? -1 : 1;
					return ( 'asc' === $order_dir ) ? $comparison : -$comparison;
				}
			);

			$paged_rows = array_slice( $all_rows, $start, $length > 0 ? $length : null );
			$data       = array();
			foreach ( $paged_rows as $row ) {
				$data[] = array(
					'formName'      => '<a href="' . esc_url( admin_url( 'admin.php?page=sc-wordform-create-forms&wordform-edit-id=' . $row['formId'] ) ) . '">' . esc_html( $row['formName'] ) . '</a>',
					'gateway'       => esc_html( $row['gatewayName'] ),
					'paymentStatus' => '<span class="wordform-payment-status-pill wordform-payment-status-pill-' . esc_attr( $row['paymentStatusKey'] ) . '">' . esc_html( $row['paymentStatusLabel'] ) . '</span>',
					'amount'        => esc_html( number_format( (float) $row['amountNumeric'], 2, '.', '' ) ),
					'coupon'        => $row['couponDisplayHtml'],
					'currency'      => esc_html( $row['currency'] ),
					'transactionRef'=> '<code>' . esc_html( $row['transactionRef'] ) . '</code>',
					'submissionDate'=> esc_html( $row['submissionDateDisplay'] ),
					'details'       => '<button type="button" class="button button-link wordform-open-payment-report-detail-modal" data-payment-detail="' . esc_attr( wp_json_encode( $row['detailPayload'] ) ) . '"><span class="dashicons dashicons-visibility" aria-hidden="true"></span> ' . esc_html__( 'View', 'wordform-pro' ) . '</button>',
				);
			}

			return array(
				'draw'            => $draw,
				'recordsTotal'    => $records_total,
				'recordsFiltered' => $records_filtered,
				'data'            => $data,
			);
		}

		/**
		 * Extract payment report rows from a single saved submission payload.
		 *
		 * @param array  $submission_data Submission JSON decoded into array.
		 * @param string $form_id         WordForm ID.
		 * @param string $form_name       WordForm name.
		 * @param int    $submission_id   Submission row ID.
		 * @param string $created_at      Submission datetime.
		 * @return array
		 */
		private static function wordform_extract_payment_report_rows_from_submission( $submission_data = array(), $form_id = '', $form_name = '', $submission_id = 0, $created_at = '' ) {
			$rows = array();
			$gateway_map = array(
				'stripe' => __( 'Stripe', 'wordform-pro' ),
				'paypal' => __( 'PayPal', 'wordform-pro' ),
				'square' => __( 'Square', 'wordform-pro' ),
				'authorizenet' => __( 'Authorize.Net', 'wordform-pro' ),
			);

			SftcyWordformFormSubmission::$sc_wordform_submission_array_data = $submission_data;
			SftcyWordformFormSubmission::$sc_wordform_return_processed_raw_data = false;
			$submission_data_html = SftcyWordformFormSubmission::sc_wordform_process_submission_data();
			$coupon_code          = '';
			$coupon_discount      = '';
			$coupon_display_text  = '';
			$coupon_display_html  = '<span class="wordform-payment-report-empty-value">-</span>';

			if ( ! empty( $submission_data['payment_coupon'] ) && is_array( $submission_data['payment_coupon'] ) ) {
				foreach ( $submission_data['payment_coupon'] as $coupon_data ) {
					$maybe_coupon_code = isset( $coupon_data['values'] ) && is_array( $coupon_data['values'] ) ? strtoupper( sanitize_text_field( implode( ',', $coupon_data['values'] ) ) ) : '';
					$maybe_discount    = isset( $coupon_data['discountAmount'] ) ? sanitize_text_field( $coupon_data['discountAmount'] ) : '';

					if ( '' === $maybe_coupon_code && '' === $maybe_discount ) {
						continue;
					}

					$coupon_code         = $maybe_coupon_code;
					$coupon_discount     = $maybe_discount;
					$coupon_display_text = $coupon_code;

					if ( '' !== $coupon_discount && '0.00' !== $coupon_discount ) {
						$coupon_display_text .= ( '' !== $coupon_display_text ? ' | ' : '' ) . sprintf(
							/* translators: %s discount amount. */
							__( 'Discount: %s', 'wordform-pro' ),
							$coupon_discount
						);
					}

					if ( '' !== $coupon_code ) {
						$coupon_display_html = '<div class="wordform-payment-report-coupon-cell"><span class="wordform-payment-report-coupon-code">' . esc_html( $coupon_code ) . '</span>';
						if ( '' !== $coupon_discount && '0.00' !== $coupon_discount ) {
							$coupon_display_html .= '<span class="wordform-payment-report-coupon-discount">' . esc_html__( 'Discount:', 'wordform-pro' ) . ' ' . esc_html( $coupon_discount ) . '</span>';
						}
						$coupon_display_html .= '</div>';
					}

					break;
				}
			}

			foreach ( $gateway_map as $gateway_slug => $gateway_name ) {
				if ( empty( $submission_data[ $gateway_slug ] ) || ! is_array( $submission_data[ $gateway_slug ] ) ) {
					continue;
				}

				foreach ( $submission_data[ $gateway_slug ] as $payment_data ) {
					$payment_status = isset( $payment_data['paymentStatus'] ) ? sanitize_text_field( $payment_data['paymentStatus'] ) : '';
					$amount         = isset( $payment_data['values'] ) && is_array( $payment_data['values'] ) ? implode( ',', array_map( 'sanitize_text_field', $payment_data['values'] ) ) : '';
					$amount_numeric = (float) $amount;
					$currency       = isset( $payment_data['paymentCurrency'] ) ? sanitize_text_field( $payment_data['paymentCurrency'] ) : '';
					$transaction_ref = '';

					if ( 'stripe' === $gateway_slug ) {
						$transaction_ref = isset( $payment_data['paymentIntentId'] ) ? sanitize_text_field( $payment_data['paymentIntentId'] ) : '';
					} elseif ( 'paypal' === $gateway_slug ) {
						$transaction_ref = ! empty( $payment_data['captureId'] ) ? sanitize_text_field( $payment_data['captureId'] ) : ( isset( $payment_data['orderId'] ) ? sanitize_text_field( $payment_data['orderId'] ) : '' );
					} elseif ( 'square' === $gateway_slug ) {
						$transaction_ref = isset( $payment_data['paymentId'] ) ? sanitize_text_field( $payment_data['paymentId'] ) : '';
					} elseif ( 'authorizenet' === $gateway_slug ) {
						$transaction_ref = isset( $payment_data['transactionId'] ) ? sanitize_text_field( $payment_data['transactionId'] ) : '';
					}

					if ( '' === $payment_status && '' === $transaction_ref && $amount_numeric <= 0 ) {
						continue;
					}

					$status_meta = self::wordform_get_payment_report_status_meta( $gateway_slug, $payment_status );
					$timestamp   = ! empty( $created_at ) ? strtotime( $created_at ) : 0;
					$detail_payload = array(
						'formName'             => sanitize_text_field( $form_name ),
						'formId'               => sanitize_text_field( $form_id ),
						'gatewayName'          => $gateway_name,
						'gatewaySlug'          => $gateway_slug,
						'paymentStatusLabel'   => $status_meta['label'],
						'paymentStatusRaw'     => $payment_status,
						'amount'               => $amount,
						'couponCode'           => $coupon_code,
						'couponDiscount'       => $coupon_discount,
						'couponDisplayText'    => $coupon_display_text,
						'currency'             => $currency,
						'transactionRef'       => $transaction_ref,
						'submissionId'         => $submission_id,
						'submissionDateDisplay'=> $timestamp ? wp_date( 'd M Y, g:i a', $timestamp ) : '',
						'submissionDataHtml'   => wp_kses_post( $submission_data_html ),
					);

					if ( 'stripe' === $gateway_slug ) {
						$detail_payload['paymentMethodId'] = isset( $payment_data['paymentMethodId'] ) ? sanitize_text_field( $payment_data['paymentMethodId'] ) : '';
					} elseif ( 'paypal' === $gateway_slug ) {
						$detail_payload['orderId']   = isset( $payment_data['orderId'] ) ? sanitize_text_field( $payment_data['orderId'] ) : '';
						$detail_payload['captureId'] = isset( $payment_data['captureId'] ) ? sanitize_text_field( $payment_data['captureId'] ) : '';
						$detail_payload['payerId']   = isset( $payment_data['payerId'] ) ? sanitize_text_field( $payment_data['payerId'] ) : '';
					} elseif ( 'square' === $gateway_slug ) {
						$detail_payload['sourceId']       = isset( $payment_data['sourceId'] ) ? sanitize_text_field( $payment_data['sourceId'] ) : '';
						$detail_payload['cardBrand']      = isset( $payment_data['cardBrand'] ) ? sanitize_text_field( $payment_data['cardBrand'] ) : '';
						$detail_payload['last4']          = isset( $payment_data['last4'] ) ? sanitize_text_field( $payment_data['last4'] ) : '';
						$detail_payload['receiptUrl']     = isset( $payment_data['receiptUrl'] ) ? esc_url_raw( $payment_data['receiptUrl'] ) : '';
					} elseif ( 'authorizenet' === $gateway_slug ) {
						$detail_payload['responseCode']   = isset( $payment_data['responseCode'] ) ? sanitize_text_field( $payment_data['responseCode'] ) : '';
						$detail_payload['authCode']       = isset( $payment_data['authCode'] ) ? sanitize_text_field( $payment_data['authCode'] ) : '';
						$detail_payload['accountNumber']  = isset( $payment_data['accountNumber'] ) ? sanitize_text_field( $payment_data['accountNumber'] ) : '';
						$detail_payload['accountType']    = isset( $payment_data['accountType'] ) ? sanitize_text_field( $payment_data['accountType'] ) : '';
					}

					$rows[] = array(
						'formId'               => sanitize_text_field( $form_id ),
						'formName'             => sanitize_text_field( $form_name ),
						'gatewaySlug'          => $gateway_slug,
						'gatewayName'          => $gateway_name,
						'paymentStatusKey'     => $status_meta['key'],
						'paymentStatusLabel'   => $status_meta['label'],
						'paymentStatusRaw'     => $payment_status,
						'amount'               => $amount,
						'amountNumeric'        => $amount_numeric,
						'couponCode'           => $coupon_code,
						'couponDiscount'       => $coupon_discount,
						'couponDisplayText'    => $coupon_display_text,
						'couponDisplayHtml'    => $coupon_display_html,
						'currency'             => $currency ? strtoupper( $currency ) : '',
						'transactionRef'       => $transaction_ref,
						'submissionDateRaw'    => $created_at,
						'submissionTimestamp'  => $timestamp,
						'submissionDateDisplay'=> $timestamp ? wp_date( 'd M Y, g:i a', $timestamp ) : '',
						'detailPayload'        => $detail_payload,
					);
				}
			}

			return $rows;
		}




		/**
		 * Default Validation messages
		 * Wordform default validation messages
		 * Fallback validation messages
		 */
		public static function wordform_default_validation_messages() {
			$validation_messages                                = array();
			$validation_messages['validation-summary-show']     = 'yes';
			$validation_messages['validation-summary-msg']      = esc_html__( 'Please review the highlighted fields and try again.', 'wordform-pro' );
			$validation_messages['text-msg']                    = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['firstname-msg']               = esc_html__( 'First name required.', 'wordform-pro' );
			$validation_messages['lastname-msg']                = esc_html__( 'Last name required.', 'wordform-pro' );
			$validation_messages['number-msg']                  = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['textarea-msg']                = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['richeditor-msg']              = esc_html__( 'Rich text content is required.', 'wordform-pro' );
			$validation_messages['range-msg']                   = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['url-msg']                     = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['tel-msg']                     = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['date-msg']                    = esc_html__( 'Date field value required.', 'wordform-pro' );
			$validation_messages['time-msg']                    = esc_html__( 'Time field value required.', 'wordform-pro' );
			$validation_messages['datetime-msg']                = esc_html__( 'Date time field value required.', 'wordform-pro' );
			$validation_messages['address-msg']                 = esc_html__( 'Address field value required.', 'wordform-pro' );
			$validation_messages['maskinput-msg']               = esc_html__( 'Enter the value in the required format.', 'wordform-pro' );
			$validation_messages['rating-msg']                  = esc_html__( 'Please select a rating.', 'wordform-pro' );
			$validation_messages['likert-msg']                  = esc_html__( 'Please complete each matrix row.', 'wordform-pro' );
			$validation_messages['signature-msg']               = esc_html__( 'Signature is required.', 'wordform-pro' );
			$validation_messages['radio-msg']                   = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['checkbox-msg']                = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['gdpr-msg']                    = esc_html__( 'Privacy consent is required.', 'wordform-pro' );
			$validation_messages['select-msg']                  = esc_html__( 'This field value required.', 'wordform-pro' );
			$validation_messages['email-msg']                   = esc_html__( 'Valid email address required.', 'wordform-pro' );
			$validation_messages['payment-custom-amount-msg']   = esc_html__( 'Payment amount required.', 'wordform-pro' );
			$validation_messages['payment-quantity-msg']        = esc_html__( 'Payment quantity required.', 'wordform-pro' );
			$validation_messages['payment-method-msg']          = esc_html__( 'Select a payment method.', 'wordform-pro' );
			$validation_messages['captcha-empty-msg']           = esc_html__( 'Please fill the captcha field.', 'wordform-pro' );
			$validation_messages['captcha-wrong-msg']           = esc_html__( 'Wrong captcha value entered.', 'wordform-pro' );
			$validation_messages['captcha-expire-msg']          = esc_html__( 'Captcha value expired.', 'wordform-pro' );
			$validation_messages['gcaptcha-error-msg']          = esc_html__( 'Google captcha error.', 'wordform-pro' );
			$validation_messages['hcaptcha-error-msg']          = esc_html__( 'hCaptcha verification failed.', 'wordform-pro' );
			$validation_messages['upload-required-msg']         = esc_html__( 'Upload file required.', 'wordform-pro' );
			$validation_messages['upload-allow-msg']            = esc_html__( 'Upload file type not allowed.', 'wordform-pro' );
			$validation_messages['upload-size-msg']             = esc_html__( 'Upload file size exceeded limit.', 'wordform-pro' );
			$validation_messages['upload-allsize-msg']          = esc_html__( 'Upload all files size exceeded limit.', 'wordform-pro' );
			$validation_messages['upload-maxinput-msg']         = esc_html__( 'Upload max number of files exceeded limit.', 'wordform-pro' );
			$validation_messages['upload-filealready-added-msg']= esc_html__( 'File already added.', 'wordform-pro' );
			$validation_messages['form-submission-success-msg'] = esc_html__( 'We have received your message.', 'wordform-pro' );
			
			return $validation_messages;
		}

		/**
		 * Get validation messages data for the selected form id
		 *
		 * @since 1.0.0
		 * return - array - query results
		 */
		public static function sc_wordform_get_validation_messages_data_by_formid( $form_id = null ) {
			$validation_messages = self::wordform_default_validation_messages();
			if ( ! is_null( $form_id ) || ! empty( $form_id ) ) {
				global $wpdb;
				$table         = $wpdb->prefix . self::$sc_wordform_validation_messages_tbl;
				$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE form_id = %s LIMIT 1', array( $table, $form_id ) ), ARRAY_A );
				if ( $query_results && isset( $query_results[0] ) && isset( $query_results[0]['validation_messages'] ) ) {
					$stored_messages = wp_unslash( json_decode( $query_results[0]['validation_messages'], true ) );
					if ( is_array( $stored_messages ) ) {
						return wp_parse_args( $stored_messages, $validation_messages );
					}
				}
			}
			// Return default validation messages if not set yet
			return $validation_messages;
		}

		/**
		 * Check validation messages data already set or Not for the selected form ID
		 *
		 * @since 1.0.0
		 * return - array - query results
		 */
		public static function sc_wordform_check_validation_messages_data_set_or_not( $form_id = null ) {
			if ( ! is_null( $form_id ) || ! empty( $form_id ) ) {
				global $wpdb;
				$table         = $wpdb->prefix . self::$sc_wordform_validation_messages_tbl;
				$query_results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE form_id = %s LIMIT 1', array( $table, $form_id ) ), ARRAY_A );
				if ( $query_results ) {
					return $query_results;
				}
			}
			return array();
		}

		/**
		 * Settings : General Tab Info - Default Setting data
		 * return - array
		 */
		public static function wordform_get_settings_general_tab_default_data() {
			$general_tab_options                                   		= array();
			$general_tab_options['submit_button_background_color'] 		= '#2271b1';
			$general_tab_options['submit_button_background_hover_color'] = '#006ba1';
			$general_tab_options['submit_button_font_color']             = '#ffffff';
			$general_tab_options['submit_button_font_size']              = 16;
			$general_tab_options['submit_button_padding_top_bottom']     = 12;
			$general_tab_options['submit_button_padding_left_right']     = 25;
			$general_tab_options['submit_button_font_weight']            = 'normal';
			$general_tab_options['send_email_on_form_submission']        = 'no';
			$general_tab_options['hide_form_on_form_submission']         = 'yes';
			$general_tab_options['wordform_form_width']                  = 100;
			$general_tab_options['form_submission_success_message']      = esc_html__( 'We have received your message.', 'wordform-pro' );
			$general_tab_options['submit_button_loading_text']           = esc_html__( 'Submitting...', 'wordform-pro' );
			$general_tab_options['show_submit_button_spinner']           = 'yes';
			$general_tab_options['show_submit_progress_text']            = 'no';
			$general_tab_options['show_success_message_as_card']         = 'yes';
			$general_tab_options['redirect_on_form_submission']          = 'no';
			$general_tab_options['redirect_url_on_form_submission']      = '';
			$general_tab_options['form_field_gap']                       = 22;
			$general_tab_options['form_container_padding']               = 0;
			$general_tab_options['form_container_border_radius']         = 0;
			return $general_tab_options;
		}

		/**
		 * Get frontend success message for a specific form.
		 * Falls back to legacy validation storage for backward compatibility.
		 *
		 * @param string $form_id
		 * @return string
		 */
		public static function wordform_get_form_submission_success_message( $form_id = 'all_form' ) {
			$general_options = self::sc_wordform_get_settings_general_tab_info( $form_id );
			if ( ! empty( $general_options['form_submission_success_message'] ) ) {
				return sanitize_text_field( $general_options['form_submission_success_message'] );
			}

			$validation_messages = self::sc_wordform_get_validation_messages_data_by_formid( $form_id );
			if ( ! empty( $validation_messages['form-submission-success-msg'] ) ) {
				return sanitize_text_field( $validation_messages['form-submission-success-msg'] );
			}

			$defaults = self::wordform_get_settings_general_tab_default_data();
			return sanitize_text_field( $defaults['form_submission_success_message'] );
		}

		/**
		 * Settings : General Tab Info
		 * get options data
		 * return - array
		 */
		// public static function sc_wordform_get_settings_general_tab_info() {
		// 	$general_tab_options = self::wordform_get_settings_general_tab_default_data();
		// 	if ( $options = get_option( 'sftcy_wordform_settings_menu_general_tab_info' ) ) {
		// 		// Form Width
		// 		$general_tab_options['wordform_form_width'] = isset( $options['wordform_form_width'] ) ? sanitize_text_field( $options['wordform_form_width'] ) : $general_tab_options['wordform_form_width'];

		// 		// Background Color
		// 		$general_tab_options['submit_button_background_color'] = isset( $options['submit_button_background_color'] ) ? sanitize_hex_color( $options['submit_button_background_color'] ) : $general_tab_options['submit_button_background_color'];

		// 		// Background Color (Hover)
		// 		$general_tab_options['submit_button_background_hover_color'] = isset( $options['submit_button_background_hover_color'] ) ? sanitize_hex_color( $options['submit_button_background_hover_color'] ) : $general_tab_options['submit_button_background_hover_color'];

		// 		// Font Size
		// 		$general_tab_options['submit_button_font_size'] = isset( $options['submit_button_font_size'] ) ? sanitize_text_field( $options['submit_button_font_size'] ) : $general_tab_options['submit_button_font_size'];

		// 		// Padding ( Top-Bottom)
		// 		$general_tab_options['submit_button_padding_top_bottom'] = isset( $options['submit_button_padding_top_bottom'] ) ? sanitize_text_field( $options['submit_button_padding_top_bottom'] ) : $general_tab_options['submit_button_padding_top_bottom'];

		// 		// Padding ( Left-Right)
		// 		$general_tab_options['submit_button_padding_left_right'] = isset( $options['submit_button_padding_left_right'] ) ? sanitize_text_field( $options['submit_button_padding_left_right'] ) : $general_tab_options['submit_button_padding_left_right'];

		// 		// Font Color
		// 		$general_tab_options['submit_button_font_color'] = isset( $options['submit_button_font_color'] ) ? sanitize_hex_color( $options['submit_button_font_color'] ) : $general_tab_options['submit_button_font_color'];

		// 		// Font Weight
		// 		$general_tab_options['submit_button_font_weight'] = isset( $options['submit_button_font_weight'] ) ? sanitize_text_field( $options['submit_button_font_weight'] ) : $general_tab_options['submit_button_font_weight'];

		// 		// Send Email On Form Submission
		// 		$general_tab_options['send_email_on_form_submission'] = isset( $options['send_email_on_form_submission'] ) ? sanitize_text_field( $options['send_email_on_form_submission'] ) : $general_tab_options['send_email_on_form_submission'];

		// 		// Hide On Form Submission
		// 		$general_tab_options['hide_form_on_form_submission'] = isset( $options['hide_form_on_form_submission'] ) ? sanitize_text_field( $options['hide_form_on_form_submission'] ) : $general_tab_options['hide_form_on_form_submission'];
		// 	}
		// 	return $general_tab_options;
		// }


		public static function sc_wordform_get_settings_general_tab_info( $form_id = 'all_form' ) {
			$defaults = self::wordform_get_settings_general_tab_default_data();

			$all_forms_options = get_option( 'sftcy_wordform_settings_menu_general_tab_info', array() );
			if ( ! is_array( $all_forms_options ) ) {
				$all_forms_options = array();
			}

			// Shared "All Forms" settings should act as the inheritance base for specific forms.
			$inherited_settings = wp_parse_args( $all_forms_options, $defaults );

			if ( $form_id === 'all_form' ) {
				return $inherited_settings;
			}

			$form_specific_option_key = 'sftcy_wordform_settings_menu_general_tab_info_' . sanitize_text_field( $form_id );
			$form_specific_options    = get_option( $form_specific_option_key, array() );

			if ( ! is_array( $form_specific_options ) || empty( $form_specific_options ) ) {
				return $inherited_settings;
			}

			return wp_parse_args( $form_specific_options, $inherited_settings );
		}


		/**
		 * Default Wordform Width
		 *
		 * @return - integer - width value
		 */
		public static function wordform_current_form_width() {
			$general_tab_options = self::sc_wordform_get_settings_general_tab_info();
			return $general_tab_options['wordform_form_width'];
		}

		/**
		 * Settings Page -> Upload Configuration Tab
		 *
		 * 
		 * @return array  upload settings data
		 */
		// public static function wordform_settings_page_upload_config() {
		// 	$upload_config_data = [];
		// 	// If ini_get( 'max_file_uploads') set to no restriction ( 0 | -1 ) then no limit - but put a limit 1000 number of files
		// 	$upload_config_data[ 'max_num_files_allowed' ] = sanitize_text_field( get_option( 'wordform_upload_max_numof_files', ini_get( 'max_file_uploads') <= 0 ? 1000 : ini_get( 'max_file_uploads') ) );
		// 	$upload_config_data[ 'server_max_num_files_allowed' ] = sanitize_text_field( ini_get( 'max_file_uploads') <= 0 ? 1000 : ini_get( 'max_file_uploads') );

		// 	// Convert into MB - If ini_get('upload_max_filesize') set to no restriction ( 0 | -1 ) then no limit - but put a limit 2000 MB
		// 	$upload_config_data[ 'each_file_max_size_allowed' ] = sanitize_text_field( get_option( 'wordform_upload_each_file_max_size', ini_get('upload_max_filesize') <= 0 ? 2000 : SftcyWordformFormValidation::convert_filesize_into_mb( ini_get('upload_max_filesize') ) ) );
		// 	$upload_config_data[ 'server_each_file_max_size_allowed' ] = sanitize_text_field( ini_get('upload_max_filesize') <= 0 ? 2000 : SftcyWordformFormValidation::convert_filesize_into_mb( ini_get('upload_max_filesize') ) );

		// 	// Convert into MB - If ini_get('post_max_size') set to no restriction ( 0 | -1 ) then no limit - but put a limit 5000 MB
		// 	$upload_config_data[ 'all_files_max_size_allowed' ] = sanitize_text_field( get_option( 'wordform_upload_all_files_max_size', ini_get('post_max_size') <= 0 ? 5000 : SftcyWordformFormValidation::convert_filesize_into_mb( ini_get('post_max_size') ) ) );
		// 	$upload_config_data[ 'server_all_files_max_size_allowed' ] = sanitize_text_field( ini_get('post_max_size') <= 0 ? 5000 : SftcyWordformFormValidation::convert_filesize_into_mb( ini_get('post_max_size') ) );			

		// 	// Show Hide Uploading Progress Bar
		// 	$upload_config_data['wordform_upload_show_hide_progress_bar'] = get_option( 'wordform_upload_show_hide_progress_bar', 'yes' );

		// 	// Uploading Progress bar color
		// 	$upload_config_data['wordform_upload_progress_bar_color'] = get_option( 'wordform_upload_progress_bar_color', '#2271b1' );
		// 	return $upload_config_data;
		// }


		/**
		 * Settings Page -> Upload Configuration Tab
		 *
		 * Fetches all upload configuration settings
		 * from the single stored option: 'wordform_upload_tab_options_data'
		 *
		 * @return array Upload settings data
		 */
		public static function wordform_settings_page_upload_config() {

			// Server-level defaults
			$server_defaults = array(
				'server_max_num_files_allowed'       => ( ini_get( 'max_file_uploads' ) <= 0 ? 100 : ini_get( 'max_file_uploads' ) ),
				'server_each_file_max_size_allowed'  => ( ini_get( 'upload_max_filesize' ) <= 0 ? 5000 : SftcyWordformFormValidation::convert_filesize_into_mb( ini_get( 'upload_max_filesize' ) ) ),
				'server_all_files_max_size_allowed'  => ( ini_get( 'post_max_size' ) <= 0 ? 5000 : SftcyWordformFormValidation::convert_filesize_into_mb( ini_get( 'post_max_size' ) ) ),
			);

			// Get saved settings
			$saved = get_option( 'wordform_upload_tab_options_data', array() );

			// Merge with defaults
			$upload_config_data = wp_parse_args( $saved, array(
				'upload_max_numof_files'         => sanitize_text_field( $server_defaults['server_max_num_files_allowed'] ),
				'upload_each_file_max_size'      => sanitize_text_field( $server_defaults['server_each_file_max_size_allowed'] ),
				'upload_all_files_max_size'      => sanitize_text_field( $server_defaults['server_all_files_max_size_allowed'] ),
				'upload_show_hide_progress_bar'  => 'yes',
				'upload_progress_bar_color'      => '#2271b1',
				'version'                        => 1,
				'last_updated'                   => current_time( 'mysql' ),
			) );

			// Include reference values for display
			$upload_config_data = array_merge( $upload_config_data, $server_defaults );

			if ( class_exists( 'SftcyWordformFeatures' ) && 'basic' === SftcyWordformFeatures::wordform_get_product_tier() ) {
				$upload_limits = SftcyWordformFeatures::wordform_get_feature_limits( 'upload' );
				$upload_config_data['upload_max_numof_files'] = ! empty( $upload_limits['maxFiles'] ) ? absint( $upload_limits['maxFiles'] ) : 1;
			}

			return $upload_config_data;
		}


		/**
		 * Settings Page -> Google reCaptcha Tab
		 *		 
		 * @return array  reCaptcha settings data
		 */
		public static function wordform_settings_page_grecaptcha_config() {
			$data = [];
			// reCaptcha Type
			$data[ 'gcaptcha-type' ] = trim( sanitize_text_field( get_option( 'wordform_gcaptcha_type', '' ) ) );
			// reCaptcha Version
			$data[ 'gcaptcha-version' ] = trim( sanitize_text_field( get_option( 'wordform_gcaptcha_version', '' ) ) );

			// reCaptcha Site Key
			$data[ 'gcaptcha-site-key' ] = trim( sanitize_text_field( get_option( 'wordform_gcaptcha_site_key', '' ) ) );
			// reCaptcha Secret Key
			$data[ 'gcaptcha-secret-key' ] = trim( sanitize_text_field( get_option( 'wordform_gcaptcha_secret_key', '' ) ) );

			// reCaptcha Theme
			$data[ 'gcaptcha-theme' ] = trim( sanitize_text_field( get_option( 'wordform_gcaptcha_theme', 'light' ) ) );

			return $data;
		}

		/**
		 * Settings Page -> hCaptcha Tab
		 *
		 * @return array
		 */
		public static function wordform_settings_page_hcaptcha_config() {
			$data = [];
			$data['hcaptcha-site-key']   = trim( sanitize_text_field( get_option( 'wordform_hcaptcha_site_key', '' ) ) );
			$data['hcaptcha-secret-key'] = trim( sanitize_text_field( get_option( 'wordform_hcaptcha_secret_key', '' ) ) );
			$data['hcaptcha-theme']      = trim( sanitize_text_field( get_option( 'wordform_hcaptcha_theme', 'light' ) ) );
			return $data;
		}

		/**
		 * Settings Page -> Payment Tab
		 *
		 * Global payment gateway defaults for the premium payment foundation.
		 * Stored separately so Stripe / PayPal settings stay isolated from
		 * general form-design options and can be gated later by plan/license.
		 *
		 * @return array
		 */
		public static function wordform_get_settings_payment_tab_default_data() {
			return array(
				'payment_currency'                => 'USD',
				'payment_currency_symbol_position'=> 'before',
				'stripe_enabled'                 => 'no',
				'stripe_mode'                    => 'test',
				'stripe_publishable_key'         => '',
				'stripe_secret_key'              => '',
				'stripe_webhook_secret'          => '',
				'paypal_enabled'                 => 'no',
				'paypal_mode'                    => 'sandbox',
				'paypal_client_id'               => '',
				'paypal_client_secret'           => '',
				'paypal_webhook_id'              => '',
				'square_enabled'                 => 'no',
				'square_mode'                    => 'sandbox',
				'square_application_id'          => '',
				'square_access_token'            => '',
				'square_location_id'             => '',
				'authorizenet_enabled'           => 'no',
				'authorizenet_mode'              => 'sandbox',
				'authorizenet_api_login_id'      => '',
				'authorizenet_client_key'        => '',
				'authorizenet_transaction_key'   => '',
				'version'                        => 1,
				'last_updated'                   => '',
			);
		}

		/**
		 * Supported payment currencies for v1 payment settings.
		 * Kept intentionally small until all gateways share the same tested list.
		 *
		 * @return array
		 */
		public static function wordform_get_supported_payment_currencies() {
			return array(
				'USD' => __( 'US Dollar (USD)', 'wordform-pro' ),
				'EUR' => __( 'Euro (EUR)', 'wordform-pro' ),
				'GBP' => __( 'British Pound (GBP)', 'wordform-pro' ),
				'AUD' => __( 'Australian Dollar (AUD)', 'wordform-pro' ),
				'CAD' => __( 'Canadian Dollar (CAD)', 'wordform-pro' ),
			);
		}

		/**
		 * Settings Page -> Payment Tab
		 *
		 * @return array
		 */
		public static function wordform_settings_page_payment_config() {
			$defaults = self::wordform_get_settings_payment_tab_default_data();
			$saved    = get_option( 'wordform_payment_tab_options_data', array() );
			$saved    = is_array( $saved ) ? $saved : array();
			$options  = wp_parse_args( $saved, $defaults );

			if ( class_exists( 'SftcyWordformFeatures' ) && 'basic' === SftcyWordformFeatures::wordform_get_product_tier() ) {
				$options['square_enabled']               = 'no';
				$options['square_mode']                  = 'sandbox';
				$options['square_application_id']        = '';
				$options['square_access_token']          = '';
				$options['square_location_id']           = '';
				$options['authorizenet_enabled']         = 'no';
				$options['authorizenet_mode']            = 'sandbox';
				$options['authorizenet_api_login_id']    = '';
				$options['authorizenet_client_key']      = '';
				$options['authorizenet_transaction_key'] = '';
			}

			return $options;
		}

		/**
		 * Supported coupon discount types.
		 *
		 * @return array
		 */
		public static function wordform_get_supported_coupon_discount_types() {
			return array(
				'fixed'      => __( 'Fixed amount', 'wordform-pro' ),
				'percentage' => __( 'Percentage', 'wordform-pro' ),
			);
		}

		/**
		 * Default coupon data.
		 *
		 * @return array
		 */
		public static function wordform_get_default_coupon_data() {
			return array(
				'id'                     => 0,
				'coupon_code'            => '',
				'discount_type'          => 'fixed',
				'discount_value'         => '0.00',
				'coupon_status'          => 'active',
				'start_date'             => '',
				'expiry_date'            => '',
				'usage_limit'            => 0,
				'minimum_amount'         => '0.00',
				'apply_to_custom_amount' => 'no',
				'allowed_forms'          => array(),
				'coupon_note'            => '',
				'usage_count'            => 0,
			);
		}

		/**
		 * Fetch all coupons with usage counts.
		 *
		 * @return array
		 */
		public static function wordform_get_all_coupons() {
			global $wpdb;
			self::sc_wordform_db_tables_install();

			$table       = $wpdb->prefix . self::$sc_wordform_coupons_tbl;
			$usage_table = $wpdb->prefix . self::$sc_wordform_coupon_usage_tbl;
			$query       = "SELECT c.*, COUNT(u.id) AS usage_count
				FROM {$table} c
				LEFT JOIN {$usage_table} u ON c.id = u.coupon_id
				GROUP BY c.id
				ORDER BY c.updated_at DESC, c.id DESC";
			$results     = $wpdb->get_results( $query, ARRAY_A );

			if ( ! is_array( $results ) ) {
				return array();
			}

			$coupons = array();
			foreach ( $results as $row ) {
				$defaults = self::wordform_get_default_coupon_data();
				$temp     = wp_parse_args( $row, $defaults );
				$temp['id'] = absint( $temp['id'] );
				$temp['coupon_code'] = strtoupper( sanitize_text_field( $temp['coupon_code'] ) );
				$temp['discount_type'] = sanitize_key( $temp['discount_type'] );
				$temp['discount_value'] = number_format( (float) $temp['discount_value'], 2, '.', '' );
				$temp['coupon_status'] = ( 'inactive' === $temp['coupon_status'] ) ? 'inactive' : 'active';
				$temp['start_date'] = ! empty( $temp['start_date'] ) ? sanitize_text_field( $temp['start_date'] ) : '';
				$temp['expiry_date'] = ! empty( $temp['expiry_date'] ) ? sanitize_text_field( $temp['expiry_date'] ) : '';
				$temp['usage_limit'] = absint( $temp['usage_limit'] );
				$temp['minimum_amount'] = number_format( (float) $temp['minimum_amount'], 2, '.', '' );
				$temp['apply_to_custom_amount'] = ( 'yes' === $temp['apply_to_custom_amount'] ) ? 'yes' : 'no';
				$temp['allowed_forms'] = json_decode( (string) $temp['allowed_forms'], true );
				$temp['allowed_forms'] = is_array( $temp['allowed_forms'] ) ? array_values( array_filter( array_map( 'sanitize_text_field', $temp['allowed_forms'] ) ) ) : array();
				$temp['coupon_note'] = sanitize_textarea_field( $temp['coupon_note'] );
				$temp['usage_count'] = absint( $temp['usage_count'] );
				$coupons[] = $temp;
			}

			return $coupons;
		}

		/**
		 * Get a single coupon by ID.
		 *
		 * @param int $coupon_id
		 * @return array
		 */
		public static function wordform_get_coupon_by_id( $coupon_id = 0 ) {
			$coupon_id = absint( $coupon_id );
			if ( $coupon_id <= 0 ) {
				return self::wordform_get_default_coupon_data();
			}

			foreach ( self::wordform_get_all_coupons() as $coupon ) {
				if ( absint( $coupon['id'] ) === $coupon_id ) {
					return $coupon;
				}
			}

			return self::wordform_get_default_coupon_data();
		}

		/**
		 * Get a single coupon by coupon code.
		 *
		 * @param string $coupon_code
		 * @return array
		 */
		public static function wordform_get_coupon_by_code( $coupon_code = '' ) {
			$normalized_coupon_code = strtoupper( sanitize_text_field( $coupon_code ) );
			if ( '' === $normalized_coupon_code ) {
				return self::wordform_get_default_coupon_data();
			}

			foreach ( self::wordform_get_all_coupons() as $coupon ) {
				if ( $normalized_coupon_code === strtoupper( sanitize_text_field( $coupon['coupon_code'] ) ) ) {
					return $coupon;
				}
			}

			return self::wordform_get_default_coupon_data();
		}

		/**
		 * Validate a coupon for the current form/payment totals.
		 *
		 * @param string $coupon_code
		 * @param string $form_id
		 * @param array  $payment_totals
		 * @return array
		 */
		public static function wordform_validate_coupon_for_form( $coupon_code = '', $form_id = '', $payment_totals = array() ) {
			$coupon_code = strtoupper( sanitize_text_field( $coupon_code ) );
			$form_id     = sanitize_text_field( $form_id );
			$defaults    = array(
				'subtotal'             => 0,
				'discountable_subtotal'=> 0,
				'custom_amount_total'  => 0,
			);
			$payment_totals = wp_parse_args( is_array( $payment_totals ) ? $payment_totals : array(), $defaults );
			$subtotal = (float) $payment_totals['subtotal'];
			$discountable_subtotal = max( 0, (float) $payment_totals['discountable_subtotal'] );

			if ( '' === $coupon_code ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'Enter a coupon code.', 'wordform-pro' ),
				);
			}

			$coupon = self::wordform_get_coupon_by_code( $coupon_code );
			if ( empty( $coupon['id'] ) ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'Coupon code was not found.', 'wordform-pro' ),
				);
			}

			if ( 'inactive' === $coupon['coupon_status'] ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'This coupon is inactive.', 'wordform-pro' ),
				);
			}

			$today = gmdate( 'Y-m-d' );
			if ( ! empty( $coupon['start_date'] ) && $today < $coupon['start_date'] ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'This coupon is not active yet.', 'wordform-pro' ),
				);
			}

			if ( ! empty( $coupon['expiry_date'] ) && $today > $coupon['expiry_date'] ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'This coupon has expired.', 'wordform-pro' ),
				);
			}

			if ( ! empty( $coupon['allowed_forms'] ) && ! in_array( $form_id, (array) $coupon['allowed_forms'], true ) ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'This coupon is not available for the selected form.', 'wordform-pro' ),
				);
			}

			if ( $subtotal <= 0 ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'Add a payable amount before applying a coupon.', 'wordform-pro' ),
				);
			}

			if ( $subtotal < (float) $coupon['minimum_amount'] ) {
				return array(
					'status'  => 'fail',
					'message' => sprintf(
						/* translators: %s: minimum order amount */
						__( 'This coupon requires a minimum order of %s.', 'wordform-pro' ),
						number_format_i18n( (float) $coupon['minimum_amount'], 2 )
					),
				);
			}

			if ( $discountable_subtotal <= 0 ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'This coupon cannot be applied to the current payment amount.', 'wordform-pro' ),
				);
			}

			if ( ! empty( $coupon['usage_limit'] ) && absint( $coupon['usage_count'] ) >= absint( $coupon['usage_limit'] ) ) {
				return array(
					'status'  => 'fail',
					'message' => __( 'This coupon has reached its usage limit.', 'wordform-pro' ),
				);
			}

			$discount_amount = 0;
			if ( 'percentage' === $coupon['discount_type'] ) {
				$discount_amount = ( $discountable_subtotal * (float) $coupon['discount_value'] ) / 100;
			} else {
				$discount_amount = (float) $coupon['discount_value'];
			}

			$discount_amount = min( $discountable_subtotal, max( 0, $discount_amount ) );
			$final_total     = max( 0, $subtotal - $discount_amount );

			return array(
				'status'                => 'success',
				'coupon'                => $coupon,
				'coupon_code'           => $coupon['coupon_code'],
				'discount_type'         => $coupon['discount_type'],
				'discount_value'        => number_format( (float) $coupon['discount_value'], 2, '.', '' ),
				'discount_amount'       => number_format( $discount_amount, 2, '.', '' ),
				'subtotal'              => number_format( $subtotal, 2, '.', '' ),
				'discountable_subtotal' => number_format( $discountable_subtotal, 2, '.', '' ),
				'total'                 => number_format( $final_total, 2, '.', '' ),
				'apply_to_custom_amount'=> $coupon['apply_to_custom_amount'],
				'message'               => __( 'Coupon applied successfully.', 'wordform-pro' ),
			);
		}

		/**
		 * Record coupon usage after a successful payment submission.
		 *
		 * @param array  $coupon
		 * @param string $form_id
		 * @param int    $submission_id
		 * @param string $payment_gateway
		 * @param float  $discount_amount
		 * @return bool
		 */
		public static function wordform_record_coupon_usage( $coupon = array(), $form_id = '', $submission_id = 0, $payment_gateway = '', $discount_amount = 0 ) {
			global $wpdb;

			$coupon_id = isset( $coupon['id'] ) ? absint( $coupon['id'] ) : 0;
			if ( $coupon_id <= 0 || $submission_id <= 0 ) {
				return false;
			}

			$table = $wpdb->prefix . self::$sc_wordform_coupon_usage_tbl;
			$existing_usage = $wpdb->get_var(
				$wpdb->prepare(
					"SELECT COUNT(id) FROM {$table} WHERE coupon_id = %d AND submission_id = %d",
					$coupon_id,
					absint( $submission_id )
				)
			);

			if ( ! empty( $existing_usage ) ) {
				return true;
			}

			return (bool) $wpdb->insert(
				$table,
				array(
					'coupon_id'       => $coupon_id,
					'coupon_code'     => isset( $coupon['coupon_code'] ) ? strtoupper( sanitize_text_field( $coupon['coupon_code'] ) ) : '',
					'form_id'         => sanitize_text_field( $form_id ),
					'submission_id'   => absint( $submission_id ),
					'payment_gateway' => sanitize_key( $payment_gateway ),
					'discount_amount' => number_format( (float) $discount_amount, 2, '.', '' ),
				),
				array( '%d', '%s', '%s', '%d', '%s', '%f' )
			);
		}

		/**
		 * Format coupon validity text.
		 *
		 * @param array $coupon
		 * @return string
		 */
		public static function wordform_get_coupon_validity_text( $coupon = array() ) {
			$start_date  = ! empty( $coupon['start_date'] ) ? sanitize_text_field( $coupon['start_date'] ) : '';
			$expiry_date = ! empty( $coupon['expiry_date'] ) ? sanitize_text_field( $coupon['expiry_date'] ) : '';

			if ( empty( $start_date ) && empty( $expiry_date ) ) {
				return __( 'No date restriction', 'wordform-pro' );
			}

			if ( ! empty( $start_date ) && empty( $expiry_date ) ) {
				return sprintf( __( 'From %s', 'wordform-pro' ), date_i18n( 'd M Y', strtotime( $start_date ) ) );
			}

			if ( empty( $start_date ) && ! empty( $expiry_date ) ) {
				return sprintf( __( 'Until %s', 'wordform-pro' ), date_i18n( 'd M Y', strtotime( $expiry_date ) ) );
			}

			return sprintf(
				__( '%1$s to %2$s', 'wordform-pro' ),
				date_i18n( 'd M Y', strtotime( $start_date ) ),
				date_i18n( 'd M Y', strtotime( $expiry_date ) )
			);
		}

		/**
		 * Format coupon allowed forms text.
		 *
		 * @param array $allowed_forms
		 * @return string
		 */
		public static function wordform_get_coupon_allowed_forms_text( $allowed_forms = array() ) {
			$allowed_forms = is_array( $allowed_forms ) ? array_values( array_filter( array_map( 'sanitize_text_field', $allowed_forms ) ) ) : array();

			if ( empty( $allowed_forms ) ) {
				return __( 'All forms', 'wordform-pro' );
			}

			$all_forms = self::sc_wordform_get_all_forms_for_block_dynamic_callback();
			$labels    = array();

			foreach ( $all_forms as $form ) {
				if ( isset( $form['formID'], $form['formName'] ) && in_array( $form['formID'], $allowed_forms, true ) ) {
					$labels[] = sanitize_text_field( $form['formName'] );
				}
			}

			if ( empty( $labels ) ) {
				return __( 'Selected forms', 'wordform-pro' );
			}

			return implode( ', ', $labels );
		}


		/**
		 * Check if send email setting is true
		 * Send Email on Each Form Submission by users at front-end
		 */
		public static function sc_wordform_send_email_on_form_submission_by_users( $data = array() ) {
			$options      = self::sc_wordform_get_settings_general_tab_info();
			$email_option = isset( $options['send_email_on_form_submission'] ) ? sanitize_text_field( $options['send_email_on_form_submission'] ) : 'no';
			$recipient    = sanitize_email( get_option( 'admin_email' ) );
			if ( isset( $email_option ) && $email_option == 'yes' && array_filter( $data ) && is_email( $recipient ) ) {
				SftcyWordformAjaxhandler::$output['sendEmailOption'] = 'Yes';

				SftcyWordformFormSubmission::$sc_wordform_submission_array_data = json_decode( $data['submission_data'], true );
				$submissionData = SftcyWordformFormSubmission::sc_wordform_process_submission_data();

				$recipient        = $recipient;
				$from_name        = sanitize_text_field( get_option( 'blogname' ) );
				$subject          = 'WordForm - User Submitted Form [ ' . sanitize_text_field( $data['form_name'] ) . ' ]';
				$email_body       = $submissionData;
				$headers          = array( 'Content-Type: text/html; charset=UTF-8' );
				$mail_send_status = wp_mail( $recipient, $subject, $email_body, $headers, array() );
				SftcyWordformAjaxhandler::$output['mailSendStatus'] = $mail_send_status;
			} else {
				SftcyWordformAjaxhandler::$output['sendEmailOption'] = 'No';
			}
		}

		/**
		 * Hide Form on Submission status
		 * default - Hide Form - true
		 * return - boolean
		 */
		public static function wordform_hide_form_on_submission_status() {
			if ( $options = get_option( 'sftcy_wordform_settings_menu_general_tab_info' ) ) {
				return ( isset( $options['hide_form_on_form_submission'] ) && $options['hide_form_on_form_submission'] == 'yes' ) ? true : false;
			}
			return true;
		}

		/**
		 * Create nonce
		 * return - string - nonce value
		 */
		public static function sc_wordform_get_nonce() {
			return wp_create_nonce( 'scwordform_wpnonce' );
		}


		/**
		 * Check the current screen
		 * Check whether Post | Page add new editor
		 */
		public static function wordform_current_screen_actions( $current_screen ) {
			if ( isset( $current_screen->action ) && $current_screen->action === 'add' && isset( $current_screen->post_type ) && $current_screen->post_type === 'post' ) {
			} elseif ( isset( $current_screen->action ) && $current_screen->action === 'add' && isset( $current_screen->post_type ) && $current_screen->post_type === 'page' ) {
			}
		}

		/**
		 * 'the_content' hook callback
		 * While rendering single Post | Page
		 * return - updated filtered content - updated content with latest form elements
		 */
		public static function wordform_post_page_rendering_with_form_data( $content ) {
			// Check if we're inside the main loop in a single Post
			if ( is_singular() && in_the_loop() && is_main_query() ) {
				global $post;				
				if ( $post->ID && has_block( self::$wordform_custom_block_name ) ) {
					$rendering_post_id = $post->ID;
					$content           = self::wordform_embed_block_form_html_data_with_content( $rendering_post_id );
				}
			}
			return $content;
		}

		/**
		 * Build & Embed wordform - based on attributes 'wordformid' attached with Post | Page
		 * params - $postID - current rendering Post | Page ID
		 * return - updated content - always built the FORM with latest wordform form elements - if edited or changes after attach
		 *
		 * @since 1.0.0
		 */
		public static function wordform_embed_block_form_html_data_with_content( $postID = null ) {
			$post = null;
			$post = get_post( $postID );
			if ( ! is_null( $post ) && $post ) {
				$allblocks     = array();
				$blocks        = array();
				$blocks        = parse_blocks( $post->post_content );				
				$form_id_index = 0;
				foreach ( $blocks as $key => $block ) {
					if ( self::$wordform_custom_block_name == $block['blockName'] ) {
						if ( isset( $block['attrs']['wordformid'] ) && ! empty( $block['attrs']['wordformid'] ) ) {
							$formdata           = SftcyWordformBuildForm::wordform_built_to_display( $block['attrs']['wordformid'] );
							//$updated_formdata   = '<div class="sc-wordform-block-editor-div-wrapper">' . $formdata . '</div>';
							$block['innerHTML'] = $formdata;							
							$block['innerContent'][0] = $formdata;							
							$allblocks[] = $block;							
						}
					} else {
						$allblocks[] = $block;
					}
				} // foreach				
				$content = serialize_blocks( $allblocks );				
				return $content;
			}
		}


		/**
		 * @param array $data
		 * Uploading Wordform files
		 * Move uploaded files into destination
		 * uploads/wordform/[curYear]/[curMonth]/
		 * @return array $data
		 * @since 1.0.0
		 */
		public static function wordform_upload_files( $data = [] ) {
			self::$output = [];
			$wordform_upload = self::wordform_upload_directory();
			// echo '<pre>';
			// print_r( $data );
			// print_r( $wordform_upload );
			// echo '</pre>';						

			if ( ! $wordform_upload ) {
				return false;
			}
			else {				
				foreach( $data as $key => $filedata ) {
					if ( isset( $filedata['name'] ) && array_filter( $filedata['name'] ) ) {
						foreach( $filedata['name'] as $file_key => $file_name ) {
							// $temp = [];
							if ( isset( $file_name ) && isset( $filedata['tmp_name'][ $file_key ] ) ) {
								$file_unique_name = wp_unique_filename( $wordform_upload['fullUploadPath'], sanitize_file_name( $file_name) );
								if ( move_uploaded_file( $filedata['tmp_name'][ $file_key ], $wordform_upload['fullUploadPath'] . $file_unique_name ) ) {
									$data[ $key ]['uploadStatus'][ $file_key ] = 'success';
									$data[ $key ]['uploadFileName'][ $file_key ] = $file_unique_name; 
									$data[ $key ]['uploadFileUrl'][ $file_key ] = $wordform_upload['wordformUploadBaseurl'] . $file_unique_name; 
									$data[ $key ]['uploadFileComment'][ $file_key ] = 'Moved successfully into destination';
								}
								else {
									$data[ $key ]['uploadStatus'][ $file_key ] = 'fail';
									$data[ $key ]['uploadFileName'][ $file_key ] = $file_name; 									
									$data[ $key ]['uploadFileComment'][ $file_key ] = 'Failed to move uploaded file into destination';
									SftcyWordformSupport::log_event(
										'upload',
										'error',
										'upload_move_failed',
										'Failed to move uploaded file into destination.',
										array(
											'field_key'  => $key,
											'file_name'  => sanitize_file_name( $file_name ),
											'target_dir' => isset( $wordform_upload['fullUploadPath'] ) ? $wordform_upload['fullUploadPath'] : '',
										)
									);
								}
							}														
						} // foreach	
					}
				} // foreach
			}
			
			// echo '<pre>';
			// print_r( $data );
			// echo '</pre>';
			// exit();
			return $data;
		}

		/**
		 * check or create upload directory structure
		 * Wordform Directory structure: uploads/wordform/[curYear]/[curMonth]/
		 * @return mixed		 
		 * @since 1.0.0
		 */
		public static function wordform_upload_directory() {
			$wordform_upload_base_dir = 'wordform';
			$wp_upload_dir = wp_upload_dir();
			$wp_base_dir_path = isset( $wp_upload_dir['basedir'] ) ? $wp_upload_dir['basedir'] : '';
			$temp = [];
			if ( empty( $wp_base_dir_path ) ) {
				return false;
			}
			else {
				$cur_year = date('Y');
				$cur_month = strtolower( date('F') );				
				$wordform_subdir_path = trailingslashit( $wordform_upload_base_dir ) . trailingslashit( $cur_year ) . trailingslashit( $cur_month );
				$full_upload_dir_path = trailingslashit( $wp_base_dir_path ) . $wordform_subdir_path;								
				wp_mkdir_p( $full_upload_dir_path );
				$temp['fullUploadPath']  = $full_upload_dir_path;
				$temp['wordformUploadBaseurl'] = trailingslashit( $wp_upload_dir['baseurl'] ) . $wordform_subdir_path;
				return $temp;
			}
		}

		/**
		 * WordForm License Key Mask Format
		 * @return - string - License Key Mask
		 */
		public static function wordform_pro_license_key_mask_format( $license_key = '' ) {
			// Default - Placeholder display
			$license_key_mask = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
			if ( ! empty( $license_key ) ) {
				$license_key_mask = str_split( $license_key, 2 );	
				array_walk( $license_key_mask, function( &$val, $index ) { $val = ( $index % 2 !== 0 )? str_repeat( '*', strlen( $val )) : $val; } );		
				$license_key_mask = implode('', $license_key_mask );		
			}
			return $license_key_mask;
		}


		/**
		 * Admin notices
		 */
		public static function scwordform_empty_state_notice_styles() {
			$notice_css = '
.notice.sc-wordform-empty-state-notice{border-left-color:#FC6C85;border-radius:10px;box-shadow:0 12px 30px rgba(15,23,42,.08);margin:18px 20px 16px 0;padding:0;overflow:hidden}
.sc-wordform-empty-state-notice .notice-dismiss{top:10px;right:10px}
.sc-wordform-empty-state-notice-inner{display:flex;flex-direction:column;align-items:stretch;gap:10px;padding:24px 58px 24px 24px;background:linear-gradient(135deg,#fff 0%,#fff7fa 45%,#f2f8ff 100%)}
.sc-wordform-empty-state-notice-brand{display:flex;align-items:center;gap:10px;color:#172033;font-size:18px;font-weight:800;line-height:1.1}
.sc-wordform-empty-state-notice-icon{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;flex:0 0 38px;border-radius:10px;background:#fff;box-shadow:inset 0 0 0 1px rgba(252,108,133,.16),0 10px 24px rgba(15,23,42,.12)}
.sc-wordform-empty-state-notice-icon img{width:25px;height:25px;object-fit:contain}
.sc-wordform-empty-state-notice-content{display:flex;align-items:center;gap:16px}
.sc-wordform-empty-state-notice-copy{min-width:0;flex:1}
.sc-wordform-empty-state-notice-copy h3{margin:0;color:#172033;font-size:17px;line-height:1.25}
.sc-wordform-empty-state-notice-copy p{max-width:760px;margin:3px 0 0;color:#526070;font-size:13px;line-height:1.42}
.sc-wordform-empty-state-notice-action.button.button-primary{flex:0 0 auto;border-color:#FC6C85;background:#FC6C85;box-shadow:none;color:#fff;font-weight:600}
.sc-wordform-empty-state-notice-action.button.button-primary:hover,.sc-wordform-empty-state-notice-action.button.button-primary:focus{border-color:#e64d70;background:#e64d70;color:#fff}
@media (max-width:782px){.sc-wordform-empty-state-notice-inner{padding:22px 44px 22px 22px}.sc-wordform-empty-state-notice-content{align-items:flex-start;flex-direction:column;gap:10px}}
';
			wp_register_style( 'sc-wordform-empty-state-notice', false, array(), SFTCY_WORDFORM_VERSION );
			wp_enqueue_style( 'sc-wordform-empty-state-notice' );
			wp_add_inline_style( 'sc-wordform-empty-state-notice', $notice_css );
		}

		public static function scwordform_admin_notices() {
			$admin_notice  = false;
			$query_results = self::sc_wordform_get_all_created_forms_data();
			if ( ! $query_results || ! array_filter( $query_results ) ) {
				$admin_notice = true;
			}

			if ( $admin_notice ) {
				$page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
				if ( $page != 'sc-wordform-create-forms' ) {
					$url      = admin_url( 'admin.php?page=sc-wordform-create-forms' );
					$icon_url = plugin_dir_url( __FILE__ ) . '../admin/views/images/wordform-icon-gradient.svg';
					printf(
						'<div class="notice notice-info is-dismissible sc-wordform-empty-state-notice"><div class="sc-wordform-empty-state-notice-inner"><div class="sc-wordform-empty-state-notice-brand"><span class="sc-wordform-empty-state-notice-icon"><img src="%1$s" alt="" /></span><strong>%2$s</strong></div><div class="sc-wordform-empty-state-notice-content"><div class="sc-wordform-empty-state-notice-copy"><h3>%3$s</h3><p>%4$s</p></div><a class="button button-primary sc-wordform-empty-state-notice-action" href="%5$s">%6$s</a></div></div></div>',
						esc_url( $icon_url ),
						esc_html__( 'WordForm', 'wordform' ),
						esc_html__( 'Create your first WordForm', 'wordform' ),
						esc_html__( 'You have not created a form yet. Start with the simple drag-and-drop builder and publish your first form in minutes.', 'wordform' ),
						esc_url( $url ),
						esc_html__( 'Create Form', 'wordform' )
					);
				}
			}
		}

		public static function scwordform_row_link( $actions, $plugin_file ) {
			$wordsmtp_plugin = plugin_basename( SFTCY_WORDFORM_PLUGIN_DIR );
			$plugin_name     = basename( $plugin_file, '.php' );
			if ( $wordsmtp_plugin == $plugin_name ) {
				// $doclink[]        = '<a href="https://softcoy.com/wordform" title="WordForm - Docs" target="_blank">WordForm Docs</a>';
				// $doclink[]        = '<a href="https://softcoy.com/wordform" title="WordForm Support" target="_blank">Support</a>';
				// return array_merge( $actions, $doclink );
			}
			return $actions;
		}
	} // End class
}
