<?php

// Exit if accessed directly.
if (!defined('ABSPATH')) {
    exit; // Prevent direct access to the file.
}

// Check if the class already exists to avoid redeclaration.
if (!class_exists('IAFWZDESK_FormSubmit')) {
    class IAFWZDESK_FormSubmit
    {
        public function __construct()
        {

            // Hook for Contact Form 7 submissions
            add_action('wpcf7_mail_sent', [$this, 'process_cf7_submission']);

            // Hook for WPForms submissions
            add_action('wpforms_process_complete', [$this, 'process_wpforms_submission'], 10, 4);

            // Hook for Gravity Forms submissions
            add_action('gform_after_submission', [$this, 'process_gravityform_submission'], 10, 2);

            // Add the Formidable Forms submission hook
            add_action('frm_after_create_entry', [$this, 'process_formidable_submission'], 10, 2);

            // Hook for Elementor Pro form submissions
            add_action('elementor_pro/forms/new_record', [$this, 'process_elementor_form_submission'], 10, 2);
        }

        // Main processing function for form submissions
        public function process_form_submission($data, $crm_data, $field_mapping_details, $status = null)
        {
            try {
                // Retrieve account details and access token
                $iafwzdesk_accountDBInstance = new IAFWZDESK_Account_Table();
                $account_id = $field_mapping_details->account_id;
                $account_details = $iafwzdesk_accountDBInstance->get_single_account_data($account_id);
                $accessToken = IAFWZDESK_Util::getAccessToken($account_id);
                if ($account_details) {
                    $instance = new IAFWZDESK_PRODUCT($account_details, $accessToken);
                    // Perform the CRM action based on record_action setting
                    return $this->handle_crm_action($instance, $crm_data, $field_mapping_details, $status);
                }

                return $this->create_error_response('ACCOUNT_NOT_FOUND');
            } catch (Throwable $e) {
                return $this->create_error_response('UNEXPECTED_ERROR');
            }
        }
        private function create_error_response($error_code)
        {
            return [
                'status' => 'error',
                'category' => $error_code
            ];
        }
        // Function to process Contact Form 7 submissions
        public function process_cf7_submission($contact_form)
        {
            $IAFWZDESK_Field_MappingDBInstance = new IAFWZDESK_Field_Mapping();

            try {
                // Retrieve form ID and group ID
                $form_id = $contact_form->id();
                $form_group_id = 1; // Adjust if needed

                // Get the submission instance
                $submission = WPCF7_Submission::get_instance();
                if ($submission) {
                    $session = iafwzdesk_is_valid_key();
                    if (!$session) {
                        $IAFWZDESK_Field_MappingDBInstance->block_field_mapping();
                    }
                    // Fetch field mappings from the database
                    $field_mapping_list = $IAFWZDESK_Field_MappingDBInstance->get_mapping_by_id($form_id, $form_group_id);

                    // Retrieve submitted form data
                    $form_data = $submission->get_posted_data();
                    $uploaded_files = $submission->uploaded_files();
                    // Include uploaded file paths in form data
                    if (!empty($uploaded_files)) {
                        foreach ($uploaded_files as $field_name => $file_path) {
                            if (isset($form_data[$field_name])) {
                                $form_data[$field_name] = $file_path;
                            }
                        }
                    }
                    // Process each field mapping
                    if (!empty($field_mapping_list)) {
                        foreach ($field_mapping_list as $field_mapping_details) {
                            if ((int)$field_mapping_details->integration_status === 1) {

                                $filter_criteria = $this->filter_criteria($form_data, $field_mapping_details->filter_criteria);
                                if ($filter_criteria === 1) {
                                    // Map form data to CRM format
                                    $crm_data = $this->map_form_data_to_crm($form_data, $field_mapping_details);
                                    // Process form submission and check response
                                    $response = $this->process_form_submission($form_data, $crm_data, $field_mapping_details);
                                    // Log errors if needed
                                    $this->check_and_add_error_log($response, $form_data, $crm_data, $field_mapping_details);
                                }
                            }
                        }
                    }
                }
            } catch (Throwable $e) {
                // Log the error for debugging
            }
        }

        // Function to process WPForms submissions
        public function process_wpforms_submission($fields, $entry, $form_data, $entry_id)
        {
            $IAFWZDESK_Field_MappingDBInstance = new IAFWZDESK_Field_Mapping();
            try {
                // Retrieve form ID and mapping
                $form_id = $form_data['id'] ?? null;
                $form_group_id = 2; // Adjust as needed
                $session = iafwzdesk_is_valid_key();
                if (!$session) {
                    $IAFWZDESK_Field_MappingDBInstance->block_field_mapping();
                }
                $field_mapping_list = $IAFWZDESK_Field_MappingDBInstance->get_mapping_by_id($form_id, $form_group_id);

                // Prepare form data for CRM
                $form_data_to_map = [];
                foreach ($fields as $field) {
                    // Ensure 'id' and 'value' keys exist
                    if (isset($field['id']) && isset($field['value'])) {
                        $form_data_to_map[$field['id']] = $field['value'];
                    }
                }
                // Process each field mapping
                if (!empty($field_mapping_list)) {
                    foreach ($field_mapping_list as $field_mapping_details) {
                        if ((int) $field_mapping_details->integration_status === 1) {
                            $filter_criteria = $this->filter_criteria($form_data_to_map, $field_mapping_details->filter_criteria);
                            if ($filter_criteria === 1) {
                                // Map form data to CRM format
                                $crm_data = $this->map_form_data_to_crm(
                                    $form_data_to_map,
                                    $field_mapping_details,
                                    "wpforms"
                                );

                                // Submit data to CRM and handle response
                                $response = $this->process_form_submission(
                                    $form_data_to_map,
                                    $crm_data,
                                    $field_mapping_details
                                );

                                // Log errors if the submission fails
                                $this->check_and_add_error_log(
                                    $response,
                                    $form_data_to_map,
                                    $crm_data,
                                    $field_mapping_details
                                );
                            }
                        }
                    }
                }
            } catch (Throwable $e) {
                // Log the error for debugging purposes
            }
        }

        // Function to process Gravity Forms submissions
        public function process_gravityform_submission($entry, $form)
        {
            $IAFWZDESK_Field_MappingDBInstance = new IAFWZDESK_Field_Mapping();

            try {
                // Retrieve form ID and mapping
                $form_id = $form['id'] ?? null;
                $form_group_id = 3; // Adjust as needed for Gravity Forms
                $session = iafwzdesk_is_valid_key();
                if (!$session) {
                    $IAFWZDESK_Field_MappingDBInstance->block_field_mapping();
                }
                $field_mapping_list = $IAFWZDESK_Field_MappingDBInstance->get_mapping_by_id($form_id, $form_group_id);

                // Check if mappings exist
                if (!empty($field_mapping_list)) {
                    // Prepare form data for CRM
                    $form_data = [];

                    foreach ($form['fields'] as $field) {
                        $field_id = $field->id;

                        if (!empty($field->inputs) && is_array($field->inputs)) {
                            foreach ($field->inputs as $input) {
                                $input_id = $input['id'];
                                $input_value = rgar($entry, $input_id); // Retrieve input value

                                if ($input_value !== null) {
                                    $form_data[$input_id] = $input_value;
                                }
                            }
                        } elseif ($field->type === 'fileupload') {
                            // Handle file upload fields
                            if (isset($entry[$field->id]) && !empty($entry[$field->id])) {
                                $file_path = $entry[$field->id];
                                $form_data[$field->id] = $file_path;
                            }
                        } else {
                            // Handle regular fields
                            $field_value = rgar($entry, $field_id); // Retrieve field value

                            if ($field_value !== null) {
                                $form_data[$field->id] = $field_value;
                            }
                        }
                    }

                    // Process each field mapping
                    foreach ($field_mapping_list as $field_mapping_details) {
                        if ((int) $field_mapping_details->integration_status === 1) {
                            $filter_criteria = $this->filter_criteria($form_data, $field_mapping_details->filter_criteria);
                            if ($filter_criteria === 1) {
                                // Map form data to CRM format
                                $crm_data = $this->map_form_data_to_crm(
                                    $form_data,
                                    $field_mapping_details,
                                    "gravity_forms"
                                );

                                // Submit data to CRM and handle response
                                $response = $this->process_form_submission(
                                    $form_data,
                                    $crm_data,
                                    $field_mapping_details
                                );

                                // Log errors if the submission fails
                                $this->check_and_add_error_log(
                                    $response,
                                    $form_data,
                                    $crm_data,
                                    $field_mapping_details
                                );
                            }
                        }
                    }
                }
            } catch (Throwable $e) {
                // Log the error for debugging
            }
        }
        /**
         * Process Formidable Forms submission.
         *
         * @param int $entry_id The ID of the submitted entry.
         * @param array $form The form object data.
         */
        public function process_formidable_submission($entry_id, $form_id)
        {
            $IAFWZDESK_Field_MappingDBInstance = new IAFWZDESK_Field_Mapping();
            try {
                // Retrieve form object using the form ID
                $form = FrmForm::getOne($form_id);
                if (!$form) {
                    throw new Exception('Formidable form not found for ID: ' . $form_id);
                }

                // Retrieve form group ID and mapping
                $form_group_id = 5; // Adjust group ID for Formidable Forms
                $session = iafwzdesk_is_valid_key();
                if (!$session) {
                    $IAFWZDESK_Field_MappingDBInstance->block_field_mapping();
                }
                $field_mapping_list = $IAFWZDESK_Field_MappingDBInstance->get_mapping_by_id($form_id, $form_group_id);

                // Get entry data
                $entry_data = FrmEntry::getOne($entry_id, true);
                $form_data = [];

                if (!empty($entry_data->metas)) {
                    foreach ($entry_data->metas as $field_id => $field_value) {
                        // Get field object to fetch the field name and type
                        $field_object = FrmField::getOne($field_id);

                        if ($field_object && isset($field_object->name)) {
                            // Handle file fields
                            if ($field_object->type === 'file') {
                                if (is_array($field_value)) {
                                    foreach ($field_value as $file) {
                                        $file_path = wp_get_original_image_path($file);
                                        if ($file_path) {
                                            $form_data[$field_id][] = $file_path; // Append file path to an array
                                        }
                                    }
                                } elseif (is_string($field_value)) {
                                    $file_path = wp_get_original_image_path($field_value);
                                    if ($file_path) {
                                        $form_data[$field_id] = $file_path; // Assign single file path
                                    }
                                }
                            }
                            // Handle non-file fields
                            else {
                                if (is_array($field_value) && array_keys($field_value) !== range(0, count($field_value) - 1)) {
                                    foreach ($field_value as $key => $value) {
                                        $form_data[$field_id . "_" . $key] = $value; // Use key for array items
                                    }
                                } else {
                                    $form_data[$field_id] = $field_value; // Assign single value
                                }
                            }
                        }
                    }
                }

                // Process each field mapping
                if (!empty($field_mapping_list)) {
                    foreach ($field_mapping_list as $field_mapping_details) {
                        if ((int) $field_mapping_details->integration_status === 1) {
                            $filter_criteria = $this->filter_criteria($form_data, $field_mapping_details->filter_criteria);
                            if ($filter_criteria === 1) {

                                // Map form data to CRM format
                                $crm_data = $this->map_form_data_to_crm(
                                    $form_data,
                                    $field_mapping_details,
                                    "formidable_forms"
                                );

                                // Submit data to CRM and handle response
                                $response = $this->process_form_submission(
                                    $form_data,
                                    $crm_data,
                                    $field_mapping_details
                                );

                                // Log errors if the submission fails
                                $this->check_and_add_error_log(
                                    $response,
                                    $form_data,
                                    $crm_data,
                                    $field_mapping_details
                                );
                            }
                        }
                    }
                }
            } catch (Throwable $e) {
                // Log the error for debugging purposes
            }
        }

        /**
         * Process Elementor form submissions.
         *
         * @param \ElementorPro\Modules\Forms\Classes\Ajax_Handler $record The form submission record.
         * @param \ElementorPro\Modules\Forms\Classes\Form $handler The form handler.
         */
        public function process_elementor_form_submission($record, $handler)
        {
            $IAFWZDESK_Field_MappingDBInstance = new IAFWZDESK_Field_Mapping();

            try {
                // --- Build combined form ID: {postId}_{widgetId}
                $form_widget_id = (string) $record->get_form_settings('id');
                $form_post_id   = (int) $record->get_form_settings('form_post_id');
                if ($form_post_id <= 0 || $form_widget_id === '') {
                    return;
                }
                $form_id       = $form_post_id . '_' . $form_widget_id;
                $form_group_id = 7; // Elementor Forms group
                // --- License/session check
                $session = iafwzdesk_is_valid_key();
                if (! $session) {
                    // If session invalid, block and stop further processing
                    $IAFWZDESK_Field_MappingDBInstance->block_field_mapping();
                }

                // --- Get mapping rows for this form
                $field_mapping_list = $IAFWZDESK_Field_MappingDBInstance->get_mapping_by_id($form_id, $form_group_id);
                if (empty($field_mapping_list)) {
                    return; // nothing to do
                }

                // --- Read form fields and submitted values
                $form_data = [];

                // Definitions from form settings (builder-time)
                $form_fields = $record->get_form_settings('form_fields');
                $form_fields = is_array($form_fields) ? $form_fields : [];

                // Build map: custom_id => _id (to normalize submitted keys)
                $custom_id_map = [];
                foreach ($form_fields as $field_def) {
                    if (is_array($field_def) && isset($field_def['custom_id'], $field_def['_id'])) {
                        $custom_id_map[(string) $field_def['custom_id']] = (string) $field_def['_id'];
                    }
                }

                // Submitted runtime values
                $raw_fields = $record->get('fields'); // ElementorPro\Forms\Record stores submitted fields here
                $raw_fields = is_array($raw_fields) ? $raw_fields : [];
                foreach ($raw_fields as $id => $field) {
                    if (! is_array($field)) {
                        continue;
                    }

                    $value = $field['value'] ?? '';
                    $type  = $field['type']  ?? '';

                    // Normalize key to builder _id if we have custom_id
                    $field_key = isset($custom_id_map[$id]) ? $custom_id_map[$id] : (string) $id;

                    if ($type === 'upload') {
                        // Elementor may give array or CSV; normalize to array of paths
                        if (is_array($value)) {
                            $paths = array_map('strval', $value);
                        } else {
                            $paths = array_map('trim', explode(',', (string) $value));
                            $paths = array_filter($paths, static function ($p) {
                                return $p !== '';
                            });
                        }
                        $form_data[$field_key] = array_values($paths);
                    } else {
                        // Scalar value as string
                        if (is_array($value)) {
                            // For checkbox/multi-select, implode safely
                            $form_data[$field_key] = implode(', ', array_map('strval', $value));
                        } else {
                            $form_data[$field_key] = (string) $value;
                        }
                    }
                }

                // --- Process each active mapping
                foreach ($field_mapping_list as $field_mapping_details) {
                    if ((int) $field_mapping_details->integration_status !== 1) {
                        continue;
                    }

                    $filter_ok = $this->filter_criteria($form_data, $field_mapping_details->filter_criteria);
                    if ((int) $filter_ok !== 1) {
                        continue;
                    }

                    // Build CRM payload and send
                    $crm_data = $this->map_form_data_to_crm($form_data, $field_mapping_details, 'elementor_forms');

                    $response = $this->process_form_submission($form_data, $crm_data, $field_mapping_details);

                    // Log errors if any
                    $this->check_and_add_error_log($response, $form_data, $crm_data, $field_mapping_details);
                }
            } catch (Throwable $e) {
                // Optional debug:
                return;
            }
        }

        // Include other existing methods here (e.g., process_form_submission, check_and_add_error_log, etc.)

        // Error logging function
        private function check_and_add_error_log($response, $form_data, $crm_data, $field_mapping_details)
        {
            $IAFWZDESK_Error_LogDBInstance = new IAFWZDESK_Error_Log();


            // $error_details = $response['body'] ?? 'UNKNOWN_ERROR';
            $code = $response['category'] ?? 'UNKNOWN_ERROR';
            $crm_record_id = $response['id'] ?? null;

            $IAFWZDESK_Error_LogDBInstance->add_error_log(
                $field_mapping_details->integration_id,
                $code,
                $form_data,
                $crm_data,
                $response,
                $retry_count = 0,
                $crm_record_id
            );
        }


        // Map form data to CRM structure based on field mappings
        private function map_form_data_to_crm($data, $field_mapping)
        {
            $crm_data = [];
            $custom_fields = [];

            try {
                $field_mapping_json = json_decode($field_mapping->field_mapping, true);

                foreach ($field_mapping_json as $crm_key => $mapping_info) {
                    if ($crm_key === 'attachment') {

                        $files = [];
                        $upload_dir  = wp_get_upload_dir();
                        $base_dir    = trailingslashit(wp_normalize_path($upload_dir['basedir']));
                        $base_url    = trailingslashit($upload_dir['baseurl']);


                        foreach ((array) $mapping_info as $attach_field_name) {

                            if (!isset($data[$attach_field_name])) {
                                continue;
                            }

                            $value = $data[$attach_field_name];

                            /* -----------------------------
                             * CASE 1: Already an array
                             * ----------------------------- */
                            if (is_array($value)) {
                                foreach ($value as $v) {
                                    if (is_string($v) && $v !== '') {
                                        $files[] = trim($v);
                                    }
                                }
                                continue;
                            }

                            /* -----------------------------
                             * CASE 2: String value
                             * ----------------------------- */
                            if (!is_string($value) || trim($value) === '') {
                                continue;
                            }

                            $value = trim($value);

                            /* 🔥 CASE 2A: Broken concatenated URLs */
                            // Detect broken concatenation using basedir OR baseurl
                            // Detect broken concatenated URLs (URL-based ONLY)
                            if (substr_count($value, $base_url) > 1) {

                                $parts = explode($base_url, $value);
                                foreach ($parts as $part) {
                                    if ($part === '') {
                                        continue;
                                    }
                                    $files[] = $base_url . ltrim($part, '/');
                                }

                                continue;
                            }



                            /* -----------------------------
                             * CASE 2B: Comma / space / tab / newline separated
                             * ----------------------------- */
                            $split = preg_split('/[\s,]+/', $value);

                            foreach ($split as $v) {
                                if ($v !== '') {
                                    $files[] = $v;
                                }
                            }
                        }

                        /* -----------------------------
                         * Final cleanup
                         * ----------------------------- */
                        if (!empty($files)) {
                            $crm_data['attachment'] = array_values(
                                array_unique(
                                    array_filter($files, 'is_string')
                                )
                            );
                        }

                        continue;
                    }



                    $is_custom_field = false;

                    // Identify custom field
                    if (str_starts_with($crm_key, 'iafwzdesk_cf_')) {
                        $crm_key = str_replace("iafwzdesk_cf_", "", $crm_key);
                        $is_custom_field = true;
                    }

                    $field_type  = $mapping_info['field_type'];
                    $field_value = $mapping_info['field_value'];
                    $data_type   = $mapping_info['data_type'];
                    $value       = null;

                    // Map value from form or system
                    if ($field_type === 'form field') {
                        if (str_contains($field_value, 'iafwzdesk_')) {
                            $value = $this->systemFieldsValue($field_value);
                        } else {
                            $value = $data[$field_value] ?? null;
                        }
                    } elseif ($field_type === 'custom field') {
                        $value = $field_value;
                        preg_match_all('/\${(.*?)}/', $value, $matches);
                        if (!empty($matches[1])) {
                            foreach ($matches[1] as $field_name) {

                                // ✅ array (select/checkbox) → string
                                if (isset($data[$field_name])) {
                                    $replacement = is_array($data[$field_name])
                                        ? implode(', ', array_map('strval', $data[$field_name]))
                                        : (string) $data[$field_name];
                                } else {
                                    $replacement = '';
                                }

                                $value = str_replace(
                                    '${' . $field_name . '}',
                                    $replacement,
                                    $value
                                );
                            }
                        }

                        // Unresolved placeholder
                        $value = preg_replace('/\${.*?}/', '', $value);

                        // Extra spaces
                        $value = trim(preg_replace('/\s{2,}/', ' ', $value));
                    }
                    try {
                        // If array, flatten it
                        if (is_array($value)) {
                            $value = implode(', ', $value);
                        }
                        // Handle date conversion if format is Y-m-d
                        if ($data_type === "DateTime" && !empty($value) && is_string($value) && preg_match('/^\d{4}-\d{2}-\d{2}$/', trim($value))) {
                            try {
                                $date = new DateTime(trim($value) . ' 12:00:00', new DateTimeZone('Asia/Kolkata'));
                                $date->setTimezone(new DateTimeZone('UTC'));
                                $value = $date->format('Y-m-d\TH:i:s.000\Z');
                            } catch (Exception $e) {
                                $value = (string) $value; // fallback
                            }
                        } else {
                            $value = (string) $value;
                        }

                        // Store in appropriate place
                        if ($is_custom_field) {
                            $custom_fields[$crm_key] = $value;
                        } else {
                            $crm_data[$crm_key] = $value;
                        }
                    } catch (Throwable $e) {
                        // Silent catch or log if needed
                    }
                }

                // Append customFields block
                if (!empty($custom_fields)) {
                    $crm_data['cf'] = $custom_fields;
                }

                return $crm_data;
            } catch (Throwable $e) {
                return $crm_data;
            }
        }


        private function handle_crm_action($crm_instance, $crm_data, $field_mapping_details, $status = null)
        {
            try {
                if ($status === null) {
                    $ai_settings_instance = new IAFWZDESK_AI_Settings();
                    $detection_code = $ai_settings_instance->validate_form($crm_data);
                    if (is_array($detection_code) && isset($detection_code['status']) && $detection_code['status'] === 'error') {
                        return $detection_code;
                    }
                }
                $module_name = $field_mapping_details->module_name;
                // Handle attachments
                $attachment_path_list = $crm_data["attachment"] ?? null;
                if (!empty($attachment_path_list)) {
                    unset($crm_data["attachment"]);
                }
                // Process record actions
                $response = $crm_instance->add_desk_ticket_with_contact($module_name, $crm_data);

                // If CRM response is an error, return it
                if (is_array($response) && isset($response['status']) && $response['status'] === 'error') {
                    return $response;
                }
                $desk_record_id = $response['id'] ?? null;
                if (!$desk_record_id) {
                    return $response;
                }
                // Handle attachments
                if (!empty($attachment_path_list)) {

                    $attachment_path_list = array_values(
                        array_unique(
                            array_filter($attachment_path_list)
                        )
                    );
                    foreach ($attachment_path_list as $file_path) {
                        $temp = $crm_instance->upload_attachment($desk_record_id, $file_path);
                    }
                }
                return [
                    'status'   => 'SUCCESS',
                    'category'  => 'SUCCESS',
                    'body'     => $response
                ];
            } catch (Throwable $e) {
                return $this->create_error_response('UNEXPECTED_ERROR');
            }
        }
        private function systemFieldsValue($field_value)
        {
            try {
                // Retrieve the referrer URL
                $page_url = isset($_SERVER['HTTP_REFERER']) ? esc_url_raw(wp_unslash($_SERVER['HTTP_REFERER'])) : null;

                // Parse the query parameters from the referrer URL, if available
                $query_params = [];
                if ($page_url) {
                    $url_components = wp_parse_url($page_url);
                    parse_str($url_components['query'] ?? '', $query_params);
                }

                switch ($field_value) {
                    case 'iafwzdesk_entry_added_time':
                        return gmdate('Y-m-d H:i:s'); // Current date and time
                    case 'iafwzdesk_utm_source':
                        return sanitize_text_field($query_params['utm_source'] ?? null); // Retrieve and sanitize UTM source
                    case 'iafwzdesk_utm_medium':
                        return sanitize_text_field($query_params['utm_medium'] ?? null); // Retrieve and sanitize UTM medium
                    case 'iafwzdesk_utm_campaign':
                        return sanitize_text_field($query_params['utm_campaign'] ?? null); // Retrieve and sanitize UTM campaign
                    case 'iafwzdesk_utm_term':
                        return sanitize_text_field($query_params['utm_term'] ?? null); // Retrieve and sanitize UTM term
                    case 'iafwzdesk_utm_content':
                        return sanitize_text_field($query_params['utm_content'] ?? null); // Retrieve and sanitize UTM content
                    case 'iafwzdesk_page_url':
                        return esc_url($page_url); // Return the sanitized referrer URL
                    case 'iafwzdesk_city':
                        return $this->get_user_location()['city']; // Get city from user location
                    case 'iafwzdesk_state':
                        return $this->get_user_location()['state']; // Get state from user location
                    case 'iafwzdesk_country':
                        return $this->get_user_location()['country']; // Get country from user location
                    default:
                        return null; // Return null for unrecognized keys
                }
            } catch (Throwable $e) {
                // Log the error for debugging
                return null; // Return null on error
            }
        }

        private function get_user_location()
        {
            try {
                // Retrieve the user's IP address from various headers
                if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
                    $ip = filter_var(wp_unslash($_SERVER['HTTP_CLIENT_IP']), FILTER_VALIDATE_IP);
                } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                    // Sanitize the input before further processing
                    $forwarded_for = sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
                    // Split the sanitized string into an array
                    $ip_list = array_map('sanitize_text_field', explode(',', $forwarded_for));
                    // Validate and use the first valid IP
                    $ip = isset($ip_list[0]) ? filter_var(trim($ip_list[0]), FILTER_VALIDATE_IP) : false;
                } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
                    $ip = filter_var(wp_unslash($_SERVER['HTTP_X_FORWARDED']), FILTER_VALIDATE_IP);
                } elseif (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
                    $ip = filter_var(wp_unslash($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']), FILTER_VALIDATE_IP);
                } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
                    $ip = filter_var(wp_unslash($_SERVER['HTTP_FORWARDED_FOR']), FILTER_VALIDATE_IP);
                } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
                    $ip = filter_var(wp_unslash($_SERVER['HTTP_FORWARDED']), FILTER_VALIDATE_IP);
                } else {
                    $ip = filter_var(wp_unslash($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'), FILTER_VALIDATE_IP); // Fallback to REMOTE_ADDR
                }

                // Sanitize the IP address
                $ip = sanitize_text_field($ip);

                // Handle localhost or dummy IPs
                if ($ip === '127.0.0.1' || $ip === '::1' || $ip === '0.0.0.0') {
                    $ip = '8.8.8.8'; // Use a public IP for testing
                }

                // Validate the IP address
                if (!filter_var($ip, FILTER_VALIDATE_IP)) {
                    return [
                        'city' => null,
                        'state' => null,
                        'country' => null,
                    ];
                }

                // Attempt to get location data via WordPress hooks
                $geo_data = apply_filters('iafwzdesk_get_user_location_data', [], $ip);

                // If no data is returned, fallback to an external API
                if (empty($geo_data) || !is_array($geo_data)) {
                    $url = "http://ip-api.com/json/$ip";
                    $response = wp_remote_get($url);

                    if (!is_wp_error($response)) {
                        $data = json_decode(wp_remote_retrieve_body($response), true);
                        if ($data && $data['status'] === 'success') {
                            $geo_data = [
                                'city' => $data['city'] ?? null,
                                'state' => $data['regionName'] ?? null,
                                'country' => $data['country'] ?? null,
                            ];
                        }
                    }
                }

                // Return the geolocation data
                return [
                    'city' => sanitize_text_field($geo_data['city'] ?? null),
                    'state' => sanitize_text_field($geo_data['state'] ?? null),
                    'country' => sanitize_text_field($geo_data['country'] ?? null),
                ];
            } catch (Throwable $e) {
                // Return empty values on any failure
                return [
                    'city' => null,
                    'state' => null,
                    'country' => null,
                ];
            }
        }
        public function filter_criteria($form_data, $conditions_raw)
        {
            if (!isset($conditions_raw) || empty($conditions_raw)) {
                return 1; // No conditions to evaluate
            }
            // Decode conditions JSON into an array
            $conditions = json_decode($conditions_raw, true);

            $and_list = []; // To store AND groups
            $or_list = []; // To store OR groups
            $current_and_group = []; // Temporary AND group

            // Step 1: Group conditions into AND and OR lists
            foreach ($conditions as $condition) {
                $logic = $condition['logic'] ?? null;

                // Add condition to the current AND group
                $current_and_group[] = $condition;

                // Finalize the current group if logic is OR or null
                if ($logic === 'OR' || $logic === null) {
                    // Add the current AND group to the OR list
                    $or_list[] = $current_and_group;
                    $current_and_group = []; // Reset for the next group
                }
            }
            // Ensure any remaining conditions are added as a group
            if (!empty($current_and_group)) {
                $or_list[] = $current_and_group;
            }

            // Step 2: Evaluate AND groups within each OR group
            $or_results = []; // Store the results of OR groups

            foreach ($or_list as $and_group) {
                $and_result = true; // Initialize for AND evaluation

                foreach ($and_group as $condition) {
                    $field = $condition['field'] ?? null;
                    $cond = $condition['condition'] ?? null;
                    $value = $condition['value'] ?? null;

                    // If the field is missing in form data, treat as false
                    if (!isset($form_data[$field])) {
                        $current_result = false;
                    } else {
                        $form_value = $form_data[$field];
                        // Evaluate the condition
                        switch ($cond) {
                            case 'contains':
                                $current_result = strpos($form_value, $value) !== false;
                                break;

                            case 'not_contains':
                                $current_result = strpos($form_value, $value) === false;
                                break;

                            case 'starts_with':
                                $current_result = strpos($form_value, $value) === 0;
                                break;

                            case 'ends_with':
                                $current_result = substr($form_value, -strlen($value)) === $value;
                                break;

                            case 'equals':
                                // Handle type-insensitive comparison
                                if (is_numeric($form_value) && is_numeric($value)) {
                                    $current_result = (float)$form_value == (float)$value; // Compare as numbers
                                } else {
                                    $current_result = $form_value == $value; // Loose comparison
                                }
                                break;

                            case 'not_equals':
                                // Handle type-insensitive comparison
                                if (is_numeric($form_value) && is_numeric($value)) {
                                    $current_result = (float)$form_value != (float)$value; // Compare as numbers
                                } else {
                                    $current_result = $form_value != $value; // Loose comparison
                                }
                                break;

                            case 'greater_than':
                                // Check if inputs are numeric, convert strings to numbers if necessary
                                if (is_numeric($form_value) && is_numeric($value)) {
                                    $current_result = (float)$form_value > (float)$value;
                                } else {
                                    $current_result = false; // Invalid comparison for non-numeric values
                                }
                                break;

                            case 'less_than':
                                // Check if inputs are numeric, convert strings to numbers if necessary
                                if (is_numeric($form_value) && is_numeric($value)) {
                                    $current_result = (float)$form_value < (float)$value;
                                } else {
                                    $current_result = false; // Invalid comparison for non-numeric values
                                }
                                break;

                            case 'is_empty':
                                $current_result = empty($form_value) && $form_value !== '0'; // Consider empty but not the string "0"
                                break;

                            case 'is_not_empty':
                                $current_result = !empty($form_value) || $form_value === '0'; // Consider non-empty including the string "0"
                                break;

                            default:
                                $current_result = false; // Unsupported condition
                                break;
                        }
                    }

                    // Combine results within the AND group
                    $and_result = $and_result && $current_result;

                    // If any condition fails, short-circuit the AND group
                    if (!$and_result) {
                        break;
                    }
                }

                // Store the result of this AND group in the OR results
                $or_results[] = $and_result;
            }

            // Step 3: Combine all OR group results
            $final_result = false;
            foreach ($or_results as $result) {
                $final_result = $final_result || $result;

                // If any OR group passes, short-circuit the evaluation
                if ($final_result) {
                    break;
                }
            }

            return $final_result ? 1 : 0;
        }
    }
    $iafwzdesk_formSubmit = new IAFWZDESK_FormSubmit();
}
