<?php

if (! defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

class INTEGRAZO_WZ_Form_Hooks
{
    public static function extract_field_id_from_identifier($identifier)
    {
        // Check if the string starts with ${ and ends with }
        if (preg_match('/^\$\{(.+?)\}$/', $identifier, $match)) {
            $inner = $match[1]; // e.g., "name_1"
            if (preg_match('/_(\d+)$/', $inner, $idMatch)) {
                return '${' . $idMatch[1] . '}'; // return like ${1}
            }
        }

        // If not wrapped with ${}, return as-is
        return $identifier;
    }

    /**
     * Common process function for all form submissions
     */
    public static function process_submission($form_id, $form_data, $plugin_name)
    {
        try {

            $integration_model = new INTEGRAZO_WZ_Integration_Model();
            $integration_model->block_field_mapping();
            $integrations = $integration_model->get_integrations_by_form_id($form_id);
            $integrations = self::integrazo_wz_sort_integrations_by_priority($integrations);
            //
            foreach ($integrations as $integration) {
                try {
                    $product = $integration['to_product'];
                    $integration_status = $integration['integration_status'];
                    $field_mapping = $integration['field_mapping'];

                    if ($integration_status != 2) {
                        continue;
                    }
                    $final_mapping_data = self::prepare_final_crm_data($form_data, $field_mapping, $plugin_name);
                    $account_details = self::get_account_details($integration['account_id']);
                    $filter_result = (int) INTEGRAZO_WZ_Util::filter_criteria($form_data, $integration['filter_criteria_json']);
                    if ($filter_result === 0) {
                        $response =  INTEGRAZO_WZ_Product_Util::create_error_response(
                            'FILTER_NOT_MET',
                            'Record skipped: did not meet filter criteria.',
                            null
                        );
                    } else {
                        $response = self::handle_crm_submission($product, $final_mapping_data, $integration, $account_details);
                    }
                    self::add_log(
                        $form_data,
                        $integration['id'],
                        $response['category'],
                        $response['message'] ?? '-',
                        $response['body'] ?? [],
                        0
                    );
                } catch (Throwable $e) {
                    $error_response = INTEGRAZO_WZ_Product_Util::create_error_response('EXCEPTION_THROWN', $e->getMessage(), null);
                    self::add_log(
                        $form_data,
                        $integration['id'],
                        $error_response['category'],
                        $error_response['message'] ?? '-',
                        $error_response['body'] ?? [],
                        0
                    );

                    return;
                }
            }
        } catch (Throwable $e) {
            return;
        }
    }
    /**
     * Sort integrations by integrazo_wz_run_priority (ascending).
     * Integrations without this key are placed at the end.
     *
     * @param array $integrations List of integrations.
     * @return array Sorted integrations.
     */
    public static function  integrazo_wz_sort_integrations_by_priority(array $integrations): array
    {
        if (empty($integrations)) {
            return $integrations;
        }

        // Helper function to extract priority from integration data
        $get_priority = function ($integration) {
            if (empty($integration['integration_data'])) {
                return PHP_INT_MAX;
            }

            $data = is_string($integration['integration_data'])
                ? json_decode($integration['integration_data'], true)
                : $integration['integration_data'];

            if (!is_array($data) || empty($data['integrazo_wz_run_priority'])) {
                return PHP_INT_MAX;
            }

            return (int) $data['integrazo_wz_run_priority'];
        };

        // Sort integrations
        usort($integrations, function ($a, $b) use ($get_priority) {
            $pa = $get_priority($a);
            $pb = $get_priority($b);

            if ($pa === $pb) {
                // Stable fallback: compare IDs if present
                return ($a['id'] ?? 0) <=> ($b['id'] ?? 0);
            }

            return $pa <=> $pb;
        });

        return $integrations;
    }

    public static function resync_process_submission($integration_details, $log_details)
    {
        try {

            $integration_data = json_decode($integration_details['integration_data'], true);

            $form_id            = $integration_data['integrazo_wz_form_id'];
            $form_data          = maybe_unserialize($log_details->submitted_data ?? []);
            $product            = $integration_details['to_product'] ?? '';
            $from_plugin            = $integration_details['from_plugin'] ?? '';
            $integration_status = $integration_details['integration_status'] ?? 0;
            $field_mapping      = $integration_details['field_mapping'] ?? [];
            $account_id         = $integration_details['account_id'] ?? 0;

            $final_mapping_data = self::prepare_final_crm_data($form_data, $field_mapping, $from_plugin);
            $account_details    = self::get_account_details($account_id);
            $response           = self::handle_crm_submission($product, $final_mapping_data, $integration_details, $account_details);

            $logs_model = new INTEGRAZO_WZ_Logs_Model();
            $logs_model->update_log(
                $log_details->id,
                $response['category'],
                $response['message'] ?? '-',
                $response['body'] ?? []
            );

            if (($response['category'] ?? '') === 'SUCCESS') {
                return [
                    'success' => true,
                    'message' => 'Record has been successfully resynced.'
                ];
            }

            return [
                'success' => false,
                'message' => 'Resync failed - ' . ($response['message'] ?? 'please try again later.')
            ];
        } catch (Throwable $e) {
            return [
                'success' => false,
                'message' => 'Resync failed - ' . $e->getMessage()
            ];
        }
    }

    private static function get_account_details($account_id)
    {
        $account_model = new INTEGRAZO_WZ_Account_Model();
        return $account_model->get_account_by_id($account_id);
    }

    private static function handle_crm_submission($product, $final_mapping_data, $integration_data, $account_details)
    {
        $response = [];

        switch ($product) {
            case 'zoho_crm':
                if (class_exists('INTEGRAZO_WZ_Zoho_CRM_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_CRM_Util($account_details);
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
            case 'zoho_bigin':
                if (class_exists('INTEGRAZO_WZ_Zoho_Bigin_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_Bigin_Util($account_details);
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
            case 'zoho_desk':
                if (class_exists('INTEGRAZO_WZ_Zoho_Desk_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_Desk_Util($account_details);
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
            case 'zoho_campaign':
                if (class_exists('INTEGRAZO_WZ_Zoho_Campaigns_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_Campaigns_Util($account_details);
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
            case 'zoho_inventory':
                if (class_exists('INTEGRAZO_WZ_Zoho_Inventory_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_Inventory_Util();
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
            case 'zoho_books':
                if (class_exists('INTEGRAZO_WZ_Zoho_Books_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_Books_Util();
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
            case 'zoho_invoice':
                if (class_exists('INTEGRAZO_WZ_Zoho_Invoice_Util')) {
                    $zoho_crm_util = new INTEGRAZO_WZ_Zoho_Invoice_Util();
                    $response = $zoho_crm_util->send_to_crm($final_mapping_data, $integration_data, $account_details);
                }
                break;
        }

        return $response;
    }




    private static function add_log($form_data, $integration_id, $category, $message, $body, $retry_count)
    {
        // Log CRM submission result
        $logs_model = new INTEGRAZO_WZ_Logs_Model();
        $logs_model->add_log(
            $integration_id,
            $category,
            $message ?? '-',
            $form_data,
            $body ?? [],
            $retry_count
        );
    }

    /**
     * Prepare final CRM data based on form data and field mapping
     *
     * @param array $form_data Submitted form data.
     * @param array|string $field_mapping Field mapping array or JSON string.
     * @return array Final CRM data.
     */
    private static function prepare_final_crm_data($form_data, $field_mapping, $plugin_name)
    {
        if (empty($field_mapping)) {
            return [];
        }

        // Decode JSON if needed
        if (is_string($field_mapping)) {
            $field_mapping = json_decode($field_mapping, true);
        }

        if (!is_array($field_mapping)) {
            return [];
        }

        $final_data = [];
        $counter = 1;
        foreach ($field_mapping as $mapping) {
            if (!array_key_exists('product_field', $mapping)) {
                continue;
            }

            $crm_field = $mapping['product_field'];
            $source = $mapping['source'] ?? '';
            $value = $mapping['value'] ?? '';
            $product_data_type = $mapping['product_data_type'] ?? '';

            switch ($source) {
                case 'form_field':
                case 'option_map_form_field':
                    $final_value = isset($form_data[$value]) ? $form_data[$value] : '';
                    break;

                case 'custom_value':
                case 'option_custom_value':
                    $final_value = self::replace_placeholders($value, $form_data, $plugin_name);
                    break;

                case 'option_value':
                    $final_value = $value;
                    break;

                default:
                    $final_value = '';
                    break;
            }
            if (isset($final_data[$crm_field])) {
                $crm_field = $crm_field . '_' . $counter;
                $counter++;
            }

            $final_data[$crm_field] = [
                'value' => $final_value,
                'product_data_type' => $product_data_type
            ];
        }

        return $final_data;
    }


    /**
     * Replace placeholders like ${field_name} with actual form data values
     *
     * @param string $text
     * @param array $form_data
     * @return string
     */
    private static function replace_placeholders($text, $form_data, $plugin_name)
    {
        $is_identifier = INTEGRAZO_WZ_Identifier_Util::get_plugin_identifier_support($plugin_name);
        return preg_replace_callback('/\$\{(.+?)\}/', function ($matches) use ($form_data, $is_identifier) {
            $field_key = $matches[1]; // like name_1
            if ($is_identifier === true) {
                $field_key = INTEGRAZO_WZ_Identifier_Util::extract_field_id_from_identifier($field_key);
            }

            return isset($form_data[$field_key]) ? $form_data[$field_key] : '';
        }, $text);
    }
}
