<?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('INTEGRAZO_WZ_Util')) {

    /**
     * Utility class for handling Zoho-related operations, such as access token management.
     */
    class INTEGRAZO_WZ_Util
    {
        private static $option_name = 'integrazo_wz_access_tokens';

        /**
         * Retrieves the access token for a given account ID.
         *
         * @param int $account_id The account ID to retrieve the access token for.
         * @return string|null The decrypted access token, or null if not found.
         */
        public static function getAccessToken($account_id)
        {
            // Retrieve all access tokens stored in the WordPress option.
            $stored_tokens = get_option(self::$option_name);

            // Check if tokens exist and if the requested ID is present.
            if ($stored_tokens && isset($stored_tokens[$account_id])) {
                // Decrypt and return the access token for the specific account ID.
                return base64_decode($stored_tokens[$account_id]);
            }

            // Return null if the access token is not found.
            return null;
        }

        /**
         * Updates the access token for a given account ID.
         *
         * @param int $account_id The account ID to associate with the access token.
         * @param string $access_token The access token to encrypt and store.
         * @return bool True if the token was successfully updated, false otherwise.
         */
        public static function updateAccessToken($account_id, $access_token)
        {
            // Retrieve existing tokens or initialize an empty array.
            $stored_tokens = get_option(self::$option_name, []);

            // Encrypt the access token and store it with the account ID as the key.
            $stored_tokens[$account_id] = base64_encode($access_token);

            // Update the option with the new or modified access token array.
            return update_option(self::$option_name, $stored_tokens, false);
        }
        public static function is_acceptance_true($value)
        {
            // Step 1: Normalize to scalar string
            if (is_array($value)) {
                $value = reset($value); // first element if array
            }

            // Step 2: Convert to lowercase string
            $string_value = strtolower(trim((string) $value));

            // Step 3: Define all accepted truthy values
            $truthy_values = ['yes', 'on', 'true', '1', 'accepted', 'agree', 'checked'];

            // Step 4: Check and return
            return in_array($string_value, $truthy_values, true);
        }
        /**
         * Normalize a value into a valid Zoho date string (Y-m-d).
         *
         * @param string $value The raw input value.
         * @return string A formatted date string or empty string if invalid.
         */
        public static function formatDate($value, string $format = 'Y-m-d')
        {
            try {
                $cleaned = trim((string)$value);
                if ($cleaned === '') {
                    return '';
                }

                $timestamp = strtotime($cleaned);
                if ($timestamp !== false) {
                    return gmdate($format, $timestamp);
                }
            } catch (\Throwable $e) {
                // ignore
            }
            return '';
        }


        /**
         * Normalize a value into a valid Zoho datetime string (Y-m-dTH:i:s).
         *
         * @param string $value The raw input value.
         * @return string A formatted datetime string or empty string if invalid.
         */
        public static function formatDateTime($value, string $format = 'Y-m-d\TH:i:s')
        {
            try {
                $cleaned = trim((string)$value);
                if ($cleaned === '') {
                    return '';
                }

                $timestamp = strtotime($cleaned);
                if ($timestamp !== false) {
                    return gmdate($format, $timestamp);
                }
            } catch (\Throwable $e) {
                // ignore
            }
            return '';
        }

        /**
         * Normalize a value into an array for multiselect picklist.
         *
         * @param mixed $value Raw input value (string or array).
         * @return array Normalized array of values.
         */
        public static function normalizeMultiSelect($value)
        {
            if (is_array($value)) {
                // Already an array, just trim each item
                return array_map('trim', $value);
            }

            if (!empty($value)) {
                // Convert string to array using common separators
                $items = preg_split('/[,|;:]+/', $value);
                return array_map('trim', $items);
            }

            return [];
        }
        /**
         * Remove the custom field prefix from a CRM field key.
         *
         * @param string $field_key
         * @return string
         */
        public static function normalizeFieldKey($field_key)
        {
            $prefix = 'integrazo_wz_cf_';
            if (strpos($field_key, $prefix) === 0) {
                return substr($field_key, strlen($prefix));
            }
            return $field_key;
        }

        /**
         * Remove the custom module prefix from a module ID.
         *
         * @param string $module_id
         * @return string
         */
        public static function normalizeModuleId($module_id)
        {
            $prefix = 'integrazo_wz_cm_';
            if (strpos($module_id, $prefix) === 0) {
                return substr($module_id, strlen($prefix));
            }
            return $module_id;
        }
        public static function get_event_value(?array $integration_data): string
        {
            if (empty($integration_data) || !is_array($integration_data)) {
                return '';
            }

            foreach (['integrazo_wz_form_id', 'integrazo_wz_event_name'] as $key) {
                if (!empty($integration_data[$key])) {
                    $val = $integration_data[$key];
                    if (is_array($val)) { // safety: sometimes form data is an array
                        $val = reset($val);
                    }
                    return sanitize_text_field(wp_unslash((string) $val));
                }
            }

            return '';
        }
        public static 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);
            if (json_last_error() !== JSON_ERROR_NONE || !is_array($conditions)) {
                return 1; // invalid JSON → filter disabled (treat as pass)
            }
            $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;
        }
    }
}
