<?php
// Exit if accessed directly.
if (! defined('ABSPATH')) {
    exit;
}
include INTEGRAZO_WZ_PLUGIN_DIR . 'src/util/advanced-fields.php'; // this sets $integrazo_wz_advanced_fields globally

global $integrazo_wz_advanced_fields;

if (! class_exists('INTEGRAZO_WZ_Integration_Model')) {

    class INTEGRAZO_WZ_Integration_Model
    {

        private $wpdb;
        private $table_name;

        public function __construct()
        {
            global $wpdb;
            $this->wpdb = $wpdb;
            $this->table_name = $wpdb->prefix . 'integrazo_wz_integrations';
            //
            $this->block_field_mapping();
        }

        /**
         * Add new integration with basic fields.
         *
         * @param string $integration_name
         * @param string $from_plugin
         * @param string $to_product
         * @return int|false Inserted ID on success, false on failure
         */
        public function add_integration($integration_name, $from_plugin, $to_product)
        {
            $current_user_id = get_current_user_id();

            $result = $this->wpdb->insert(
                $this->table_name,
                [
                    'integration_name' => $integration_name,
                    'from_plugin'      => $from_plugin,
                    'to_product'       => $to_product,
                    'created_by'       => $current_user_id,
                    'created_at'       => current_time('mysql'),
                    'updated_at'       => current_time('mysql'),
                ]
            );

            return $result ? $this->wpdb->insert_id : false;
        }

        /**
         * Get the integration name by integration ID.
         *
         * @param int $integration_id Integration ID.
         * @return string|null Integration name if found, null if not.
         */
        public function get_integration_name($integration_id)
        {
            if (!is_numeric($integration_id)) {
                return null;
            }
            global $wpdb;
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching	
            $result = $wpdb->get_var(
                $wpdb->prepare(
                    // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                    "SELECT integration_name FROM {$this->table_name} WHERE id = %d",
                    $integration_id
                )
            );

            return $result ? $result : null;
        }

        /**
         * Get all integration records ordered by updated_at descending.
         *
         * @return array List of integrations as associative arrays.
         */
        public function get_all_integrations()
        {
            $table_name = esc_sql($this->table_name);
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $results = $this->wpdb->get_results(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "SELECT * FROM {$table_name} ORDER BY updated_at DESC",
                ARRAY_A
            );

            return $results;
        }

        /**
         * Get integration details by ID.
         *
         * @param int $id Integration ID
         * @return array|null Integration row as associative array, or null if not found
         */
        public function get_integration_by_id($id)
        {
            if (! is_numeric($id)) {
                return null;
            }

            global $wpdb;
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching	
            return $wpdb->get_row(
                $wpdb->prepare(
                    // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                    "SELECT * FROM {$this->table_name} WHERE id = %d",
                    $id
                ),
                ARRAY_A
            );
        }
        /**
         * Get total number of integrations.
         *
         * @return int Total count of rows in the integrations table.
         */
        public function get_total_integrations_count()
        {
            $table_name = esc_sql($this->table_name);
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            $count = $this->wpdb->get_var("SELECT COUNT(*) FROM {$table_name}");
            return (int) $count;
        }
        /**
         * Update account_id for a given integration ID.
         *
         * @param int $integration_id The integration ID.
         * @param int $account_id The new account ID to set.
         * @return bool True on success, false on failure.
         */
        public function update_account_id_by_integration_id($integration_id, $account_id)
        {
            if (!is_numeric($integration_id) || !is_numeric($account_id)) {
                return false;
            }

            $result = $this->wpdb->update(
                $this->table_name,
                ['account_id' => $account_id],
                ['id' => $integration_id],
                ['%d'],
                ['%d']
            );

            return $result !== false;
        }
        /**
         * Update integration name by integration ID.
         *
         * @param int $integration_id The integration ID.
         * @param string $integration_name The new integration name.
         * @return bool True on success, false on failure.
         */
        public function update_integration_name_by_id($integration_id, $integration_name)
        {
            if (!is_numeric($integration_id) || empty($integration_name)) {
                return false;
            }

            $result = $this->wpdb->update(
                $this->table_name,
                [
                    'integration_name' => sanitize_text_field($integration_name),
                    'updated_at'       => current_time('mysql'),
                ],
                ['id' => $integration_id],
                ['%s', '%s'],
                ['%d']
            );

            return $result !== false;
        }
        /**
         * Update integration_data (JSON format) for a given integration ID.
         *
         * @param int $integration_id Integration ID.
         * @param array $data Associative array to be stored as JSON.
         * @return bool True on success, false on failure.
         */
        public function update_integration_data($integration_id, $data)
        {
            if (!is_numeric($integration_id) || !is_array($data)) {
                return false;
            }

            $json_data = wp_json_encode($data);

            $result = $this->wpdb->update(
                $this->table_name,
                [
                    'integration_data'     => $json_data,
                    'record_action'        => null,
                    'primary_key'          => null,
                    'filter_criteria'      => null,
                    'filter_criteria_json' => null,
                    'field_mapping'        => null,
                    'integration_status'   => 1,
                    'updated_at'           => current_time('mysql'),
                ],
                ['id' => $integration_id],
                ['%s', null, null, null, null, null, '%d', '%s'], // Use `null` in formats for null values
                ['%d']
            );

            return $result !== false;
        }

        public function update_fieldmapping_data($integration_id, $record_action, $primary_key, $filter_criteria, $filter_criteria_json, $field_mapping)
        {
            if (!is_numeric($integration_id) || !is_array($field_mapping)) {
                return false;
            }

            $field_mapping_json = wp_json_encode($field_mapping);

            $result = $this->wpdb->update(
                $this->table_name,
                [
                    'record_action'        => $record_action,
                    'primary_key'          => $primary_key,
                    'filter_criteria'      => $filter_criteria,
                    'filter_criteria_json' => $filter_criteria_json,
                    'field_mapping'        => $field_mapping_json,
                    'integration_status'   => 2,
                    'updated_at'           => current_time('mysql'),
                ],
                ['id' => (int) $integration_id],
                ['%s', '%s', '%s', '%s', '%s', '%d', '%s'],
                ['%d']
            );

            return ($result !== false);
        }

        /**
         * Delete an integration by ID.
         *
         * @param int $integration_id Integration ID to delete.
         * @return bool True on success, false on failure.
         */
        public function delete_integration_by_id($integration_id)
        {
            if (!is_numeric($integration_id)) {
                return false;
            }

            $result = $this->wpdb->delete(
                $this->table_name,
                ['id' => $integration_id],
                ['%d']
            );

            return $result !== false;
        }
        /**
         * Update the integration status by integration ID.
         *
         * @param int $integration_id Integration ID.
         * @param int $integration_status New status (e.g., 0 = Inactive, 1 = Draft, 2 = Active).
         * @return bool True on success, false on failure.
         */
        public function update_integration_status($integration_id, $integration_status)
        {
            if (!is_numeric($integration_id) || !is_numeric($integration_status)) {
                return false;
            }

            $result = $this->wpdb->update(
                $this->table_name,
                [
                    'integration_status' => (int) $integration_status,
                    'updated_at' => current_time('mysql'),
                ],
                ['id' => $integration_id],
                ['%d', '%s'],
                ['%d']
            );

            return $result !== false;
        }
        /**
         * Get integrations by form ID from integration_data JSON.
         *
         * @param int $form_id Form ID to search.
         * @return array List of matching integrations (each integration as associative array)
         */
        public function get_integrations_by_form_id($form_id)
        {
            // Get all integrations
            $integrations = $this->get_all_integrations();
            $matched_integrations = [];

            foreach ($integrations as $integration) {
                if (empty($integration['integration_data'])) {
                    continue;
                }

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

                if (
                    (isset($data['integrazo_wz_form_id']) && $data['integrazo_wz_form_id'] == $form_id) ||
                    (isset($data['integrazo_wz_event_name']) && $data['integrazo_wz_event_name'] == $form_id)
                ) {
                    $matched_integrations[] = $integration;
                }
            }

            return $matched_integrations; // Return array (may be empty if no match)
        }
        public function block_field_mapping()
        {
            $session = integrazo_wz_session();
            if (!$session) {
                global $wpdb;
                global $integrazo_wz_advanced_fields; // ✅ this is required!
                global $integrazo_wz_allowed_modules;
                global $integrazo_wz_integration_sources;
                $premium_fields = [];
                // Ensure table name is escaped for safety
                $table_name = esc_sql($this->table_name);

                // Get all rows from the table
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
                $rows = $wpdb->get_results("SELECT id,integration_status,integration_data, field_mapping, record_action, to_product, from_plugin FROM {$table_name} ORDER BY id ASC");
                $non_premium_count = 0;
                // Running count of active free-plan integrations.
                $free_integration_count = 0;
                $pro_product_ids = integrazo_wz_get_pro_product_ids($integrazo_wz_integration_sources['products']);
                $pro_plugin_ids = integrazo_wz_get_pro_plugin_ids($integrazo_wz_integration_sources['plugins']);

                if (!empty($rows)) {
                    foreach ($rows as $row) {
                        $field_mapping = json_decode($row->field_mapping ?? '', true);
                        $integration_data = json_decode($row->integration_data ?? '', true);
                        $record_action = $row->record_action;
                        $safe_product = sanitize_key($row->to_product);
                        $safe_plugin =  sanitize_key($row->from_plugin);
                        //
                        if (is_array($field_mapping) && intval($row->integration_status) === 2) {
                            $has_premium = false;
                            $premium_fields = $integrazo_wz_advanced_fields[$row->to_product] ?? [];
                            // Iterate through field mapping to check premium and count non-premium fields
                            foreach ($field_mapping as $mapping) {
                                $product_field = $mapping['product_field'];
                                if (in_array($product_field, $premium_fields, true)) {
                                    $has_premium = true; // Mark as having a premium field
                                    break; // Exit the loop immediately if a premium field is found
                                }
                            }
                            $has_custom_fields = false;

                            // Iterate through field mapping to check for custom fields
                            foreach ($field_mapping as $mapping) {
                                $product_field = $mapping['product_field'];
                                if (strpos($product_field, 'integrazo_wz_cf_') === 0) { // Check if the field name starts with 'cf_'
                                    $has_custom_fields = true; // Mark as having a custom field
                                    break; // Exit the loop immediately if a custom field is found
                                }
                            }

                          $has_custom_module = false;

                            $module_name = isset($integration_data['integrazo_wz_module']) && !empty($integration_data['integrazo_wz_module'])
                                ? $integration_data['integrazo_wz_module']
                                : ($integration_data['integrazo_wz_product_event'] ?? '');

                            if (strpos($module_name, 'integrazo_wz_cm_') !== false) {
                                $has_custom_module = true;
                            }

                            // If no premium field found, count non-premium fields
                            if (!$has_premium && !$has_custom_fields && !$has_custom_module) {
                                $non_premium_count++; // Count non-premium fields
                            }

                            // Only whitelisted modules are allowed per product on the free plan.
                            $has_disallowed_module = false;
                            $allowed_modules_for_product = $integrazo_wz_allowed_modules[$row->to_product] ?? null;
                            if (!$has_custom_module && !empty($allowed_modules_for_product) && !empty($module_name)) {
                                if (!in_array($module_name, $allowed_modules_for_product, true)) {
                                    $has_disallowed_module = true;
                                }
                            }

                            //------record_action
                            $has_record_action = false;
                            if (!empty($record_action) && $record_action !== "add") {
                                $has_record_action = true;
                            }

                            //---------ProProduct
                            $has_pro_product = false;
                            if (in_array($safe_product, $pro_product_ids, true)) {
                                // Pro product → load from Pro plugin dir
                                $has_pro_product = true;
                            }

                            //---------ProPlugin
                            $has_pro_plugin = false;
                            if (in_array($safe_plugin, $pro_plugin_ids, true)) {
                                // Pro product → load from Pro plugin dir
                                $has_pro_plugin = true;
                            }

                            //---------
                            $is_pro_only = $has_premium || $has_custom_fields || $has_record_action || $has_custom_module || $has_pro_product || $has_pro_plugin || $has_disallowed_module;

                            $has_extra_integration = false;
                            if (!$is_pro_only) {
                                $free_integration_count++;
                                if ($free_integration_count > 1) { // Free plan allows only 1 integration
                                    $has_extra_integration = true;
                                }
                            }

                            // If any Pro-only feature is used, or this is beyond the 1 free integration allowed
                            if ($is_pro_only || $has_extra_integration) {
                                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
                                $wpdb->update(
                                    $table_name,
                                    [
                                        'integration_status' => 3,       // Data to update
                                        'record_action' => "add", // Data to update
                                    ],
                                    [
                                        'id' => $row->id // WHERE condition
                                    ],
                                    [
                                        '%d', // Format for integration_status
                                        '%s', // Format for record_action
                                    ],
                                    [
                                        '%d' // Format for WHERE condition (integration_id)
                                    ]
                                );
                            }
                        }
                    }
                }
            }
        }
    }
}
