<?php
/**
 * Global Product Editor - Queue Handler
 *
 * @package ShopCentral
 * @subpackage ProductEditor
 */

defined('ABSPATH') || exit;

class ShopCentral_Editor_Queue
{
    const CHUNK_SIZE = 20;
    const MAX_RETRIES = 3;

    /**
     * Create a new queue job
     */
    public static function create_job($args)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';

        $uuid = wp_generate_uuid4();

        $defaults = [
            'job_type'         => 'deploy',
            'source_store_id'  => null,
            'target_store_ids' => [],
            'product_ids'      => [],
            'changes_data'     => [],
            'conflict_strategy' => 'keep_source',
        ];

        $args = wp_parse_args($args, $defaults);

        $total_items = count($args['target_store_ids']) * count($args['product_ids']);

        $result = $wpdb->insert($table, [
            'queue_uuid'        => $uuid,
            'job_type'          => $args['job_type'],
            'source_store_id'   => $args['source_store_id'],
            'target_store_ids'  => wp_json_encode($args['target_store_ids']),
            'product_ids'       => !empty($args['product_ids']) ? wp_json_encode($args['product_ids']) : null,
            'changes_data'      => !empty($args['changes_data']) ? wp_json_encode($args['changes_data']) : null,
            'conflict_strategy' => $args['conflict_strategy'],
            'status'            => ShopCentral_Product_Editor::STATUS_QUEUED,
            'total_items'       => $total_items,
        ]);

        if ($result === false) {
            return new WP_Error('db_error', 'Failed to create queue job: ' . $wpdb->last_error);
        }

        return [
            'id'         => $wpdb->insert_id,
            'queue_uuid' => $uuid,
            'status'     => ShopCentral_Product_Editor::STATUS_QUEUED,
        ];
    }

    /**
     * Schedule job processing using Action Scheduler
     * Works on all hosting: Shared, VPS, Dedicated
     */
    public static function schedule_processing($uuid)
    {
        // DEBUG: Log when schedule_processing is called
        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] schedule_processing() called for UUID: $uuid", [
                'as_function_exists' => function_exists('as_enqueue_async_action'),
                'wp_cron_enabled' => !defined('DISABLE_WP_CRON') || !DISABLE_WP_CRON,
            ]);
        }

        // Check if Action Scheduler is available (included with WooCommerce)
        if (!function_exists('as_enqueue_async_action')) {
            // Fallback to WP Cron if Action Scheduler not available
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::warning('product_sync', "[QUEUE DEBUG] Action Scheduler NOT available, using WP Cron fallback for UUID: $uuid");
            }

            if (!wp_next_scheduled('shopcentral_process_editor_queue', ['uuid' => $uuid])) {
                wp_schedule_single_event(time() + 5, 'shopcentral_process_editor_queue', ['uuid' => $uuid]);
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] WP Cron event scheduled for UUID: $uuid");
                }
            } else {
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::warning('product_sync', "[QUEUE DEBUG] WP Cron event already scheduled for UUID: $uuid");
                }
            }
            add_action('shopcentral_process_editor_queue', [__CLASS__, 'process_job']);
            return;
        }

        // Use Action Scheduler - works reliably on all hosting
        $next_scheduled = as_next_scheduled_action('shopcentral_process_editor_queue', ['uuid' => $uuid]);
        if (!$next_scheduled) {
            $action_id = as_enqueue_async_action('shopcentral_process_editor_queue', ['uuid' => $uuid]);
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] Action Scheduler enqueued for UUID: $uuid", [
                    'action_id' => $action_id,
                ]);
            }

            // IMPORTANT: Also schedule WP Cron as backup (Action Scheduler may not run immediately)
            if (!wp_next_scheduled('shopcentral_process_editor_queue', ['uuid' => $uuid])) {
                wp_schedule_single_event(time() + 30, 'shopcentral_process_editor_queue', ['uuid' => $uuid]);
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] WP Cron backup scheduled for UUID: $uuid (30 sec delay)");
                }
            }
            add_action('shopcentral_process_editor_queue', [__CLASS__, 'process_job']);
        } else {
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::warning('product_sync', "[QUEUE DEBUG] Action Scheduler already scheduled for UUID: $uuid", [
                    'next_scheduled' => $next_scheduled,
                ]);
            }
        }
    }

    /**
     * Process a queue job
     * Handles both initial call and chunk continuation
     */
    public static function process_job($uuid_or_args)
    {
        // DEBUG: Log when process_job is called
        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] process_job() called", [
                'input_type' => gettype($uuid_or_args),
                'input_value' => is_array($uuid_or_args) ? wp_json_encode($uuid_or_args) : $uuid_or_args,
            ]);
        }

        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';

        // Handle both direct UUID (legacy) and args array (chunk processing)
        if (is_array($uuid_or_args)) {
            $uuid = $uuid_or_args['uuid'] ?? '';
        } else {
            $uuid = $uuid_or_args;
        }

        if (empty($uuid)) {
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] process_job() - UUID is empty!");
            }
            return;
        }

        $job = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $table WHERE queue_uuid = %s", $uuid),
            ARRAY_A
        );

        if (!$job) {
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] process_job() - Job not found for UUID: $uuid");
            }
            return;
        }

        if ($job['status'] === ShopCentral_Product_Editor::STATUS_CANCELLED) {
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] process_job() - Job cancelled for UUID: $uuid");
            }
            return;
        }

        // Prevent duplicate processing - only allow if queued or if chunk_offset > 0 (continuation)
        if ($job['status'] === ShopCentral_Product_Editor::STATUS_PROCESSING) {
            // Check if this is a chunk continuation
            $chunk_offset = (int) ($job['chunk_offset'] ?? 0);
            if ($chunk_offset === 0) {
                // Already processing, prevent duplicate
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::warning('product_sync', "[QUEUE DEBUG] process_job() - Already processing, skipping UUID: $uuid");
                }
                return;
            }
        }

        $update_result = $wpdb->update($table, [
            'status'     => ShopCentral_Product_Editor::STATUS_PROCESSING,
            'started_at' => current_time('mysql'),
        ], ['queue_uuid' => $uuid]);

        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] process_job() - Status updated to processing for UUID: $uuid", [
                'update_result' => $update_result,
            ]);
        }

        try {
            self::execute_job($job);
        } catch (Exception $e) {
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] process_job() - Exception for UUID: " . $uuid, [
                    'error' => $e->getMessage(),
                    'trace' => $e->getTraceAsString(),
                ]);
            }
            $wpdb->update($table, [
                'status'        => ShopCentral_Product_Editor::STATUS_FAILED,
                'error_message'  => $e->getMessage(),
                'completed_at'  => current_time('mysql'),
            ], ['queue_uuid' => $uuid]);
        }
    }

    /**
     * Execute the job with chunk processing
     * - Processes products in chunks (CHUNK_SIZE) to prevent hanging
     * - Schedules next chunk via Action Scheduler if more products remain
     * - Works reliably on Shared Hosting, VPS, and Dedicated servers
     */
    private static function execute_job($job)
    {
        // DEBUG: Log when execute_job starts
        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() started for UUID: " . $job['queue_uuid'], [
                'job_type' => $job['job_type'],
                'target_store_ids' => $job['target_store_ids'],
                'product_ids' => $job['product_ids'],
                'changes_data' => $job['changes_data'],
            ]);
        }

        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';

        // Ensure chunk_offset column exists (fix for missing column)
        if (method_exists('ShopCentral_DB', 'ensure_chunk_offset_column')) {
            ShopCentral_DB::ensure_chunk_offset_column();
        }

        $target_store_ids = json_decode($job['target_store_ids'], true) ?: [];
        $product_ids = json_decode($job['product_ids'], true) ?: [];
        $changes_data = json_decode($job['changes_data'], true) ?: [];
        $source_store_id = $job['source_store_id'] ?? null;

        // Get chunk tracking data from job meta or initialize
        $chunk_offset = (int) ($job['chunk_offset'] ?? 0);
        $processed = (int) ($job['processed_items'] ?? 0);
        $failed = (int) ($job['failed_items'] ?? 0);
        $skipped = (int) ($job['skipped_items'] ?? 0);
        $total = count($target_store_ids) * count($product_ids);

        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Processing details", [
                'uuid' => $job['queue_uuid'],
                'target_store_ids' => $target_store_ids,
                'product_ids_count' => count($product_ids),
                'chunk_offset' => $chunk_offset,
                'total' => $total,
            ]);
        }

        // Get source products data for matching
        $source_products = self::get_source_products($source_store_id, $product_ids);

        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Source products fetched", [
                'uuid' => $job['queue_uuid'],
                'source_products_count' => count($source_products),
            ]);
        }

        // Process only current chunk of products
        $chunk_products = array_slice($product_ids, $chunk_offset, self::CHUNK_SIZE, true);

        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Chunk products", [
                'uuid' => $job['queue_uuid'],
                'chunk_offset' => $chunk_offset,
                'chunk_size' => self::CHUNK_SIZE,
                'chunk_products_count' => count($chunk_products),
                'chunk_products' => array_keys($chunk_products),
            ]);
        }

        foreach ($target_store_ids as $store_id) {
            // Check status - allow cancellation
            $current_status = $wpdb->get_var(
                $wpdb->prepare("SELECT status FROM $table WHERE queue_uuid = %s", $job['queue_uuid'])
            );

            if ($current_status === ShopCentral_Product_Editor::STATUS_CANCELLED) {
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Job cancelled during processing");
                }
                return;
            }

            // Get store
            $store = $wpdb->get_row(
                $wpdb->prepare("SELECT * FROM {$wpdb->prefix}shopcentral_stores WHERE id = %d", $store_id),
                ARRAY_A
            );

            if (!$store) {
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] execute_job() - Store not found: $store_id");
                }
                $failed += count($chunk_products);
                continue;
            }

            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Processing store: " . $store['name'], [
                    'store_id' => $store_id,
                    'store_url' => $store['url'],
                ]);
            }

            // Update current store
            $wpdb->update($table, [
                'current_store_id' => $store_id,
            ], ['queue_uuid' => $job['queue_uuid']]);

            // Collect all matching products for batch update
            $products_to_update = [];
            $products_to_skip = [];

            foreach ($chunk_products as $product_id) {
                $source_product = $source_products[$product_id] ?? null;

                // Find matching product in target store
                $target_product_id = self::find_matching_product($store, $source_product, $product_id);

                if ($target_product_id) {
                    $products_to_update[$product_id] = $target_product_id;
                } else {
                    $products_to_skip[] = $product_id;
                }
            }

            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Batch preparation", [
                    'uuid' => $job['queue_uuid'],
                    'store_id' => $store_id,
                    'products_to_update' => count($products_to_update),
                    'products_to_skip' => count($products_to_skip),
                ]);
            }

            // Skip products that don't match
            $skipped += count($products_to_skip);

            // Update products using batch API (more efficient)
            if (!empty($products_to_update)) {
                $batch_result = self::update_products_batch($products_to_update, $store, $changes_data);

                $processed += $batch_result['success'];
                $failed += $batch_result['failed'];

                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Batch update result", [
                        'uuid' => $job['queue_uuid'],
                        'store_id' => $store_id,
                        'success' => $batch_result['success'],
                        'failed' => $batch_result['failed'],
                    ]);
                }
            }

            // Update progress after processing store
            $progress = $total > 0 ? round(($processed + $failed + $skipped) / $total * 100) : 0;
            $wpdb->update($table, [
                'processed_items'  => $processed,
                'failed_items'     => $failed,
                'skipped_items'    => $skipped,
                'progress_percent' => min(100, $progress),
            ], ['queue_uuid' => $job['queue_uuid']]);
        }

        // Calculate next chunk offset
        $next_offset = $chunk_offset + self::CHUNK_SIZE;

        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Chunk completed", [
                'uuid' => $job['queue_uuid'],
                'chunk_offset' => $chunk_offset,
                'next_offset' => $next_offset,
                'total_products' => count($product_ids),
                'processed' => $processed,
                'failed' => $failed,
                'skipped' => $skipped,
            ]);
        }

        if ($next_offset < count($product_ids)) {
            // More products to process - schedule next chunk
            $wpdb->update($table, [
                'chunk_offset'     => $next_offset,
                'processed_items'  => $processed,
                'failed_items'     => $failed,
                'skipped_items'    => $skipped,
                'progress_percent' => $total > 0 ? round(($processed + $failed + $skipped) / $total * 100) : 0,
            ], ['queue_uuid' => $job['queue_uuid']]);

            // Schedule next chunk via Action Scheduler
            if (function_exists('as_enqueue_async_action')) {
                $action_id = as_enqueue_async_action('shopcentral_process_editor_queue', [
                    'uuid' => $job['queue_uuid'],
                ]);
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Next chunk scheduled via Action Scheduler", [
                        'action_id' => $action_id,
                        'next_offset' => $next_offset,
                    ]);
                }
            } else {
                // Fallback to WP Cron
                wp_schedule_single_event(time() + 5, 'shopcentral_process_editor_queue', [
                    'uuid' => $job['queue_uuid'],
                ]);
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] execute_job() - Next chunk scheduled via WP Cron");
                }
            }
        } else {
            // All products processed - mark completed
            $wpdb->update($table, [
                'status'           => ShopCentral_Product_Editor::STATUS_COMPLETED,
                'progress_percent' => 100,
                'completed_at'     => current_time('mysql'),
                'processed_items'  => $processed,
                'failed_items'     => $failed,
                'skipped_items'    => $skipped,
            ], ['queue_uuid' => $job['queue_uuid']]);

            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::success('product_sync', "[QUEUE DEBUG] execute_job() - Job completed!", [
                    'uuid' => $job['queue_uuid'],
                    'processed' => $processed,
                    'failed' => $failed,
                    'skipped' => $skipped,
                ]);
            }

            // Log activity
            self::log_activity($job['queue_uuid'], null, 'deploy', 'product', null, null, "Deployed: $processed updated, $failed failed, $skipped skipped");
        }
    }

    /**
     * Get source products data for matching
     */
    private static function get_source_products($store_id, $product_ids)
    {
        global $wpdb;
        $products = [];

        if (empty($product_ids)) {
            return $products;
        }

        $store = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM {$wpdb->prefix}shopcentral_stores WHERE id = %d", $store_id),
            ARRAY_A
        );

        if (!$store) {
            if (class_exists('ShopCentral_Logger')) {
                ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] get_source_products() - Store not found: $store_id");
            }
            return $products;
        }

        // Check if this is the main store
        $main_site_url = home_url();
        $store_url = trailingslashit($store['url']);
        $is_main_site = (trailingslashit($main_site_url) === $store_url) || !empty($store['is_current']);

        if (class_exists('ShopCentral_Logger')) {
            ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] get_source_products() - Store details", [
                'store_id' => $store_id,
                'store_url' => $store['url'],
                'main_site_url' => $main_site_url,
                'is_main_site' => $is_main_site,
            ]);
        }

        foreach ($product_ids as $product_id) {
            if ($is_main_site) {
                // Main Store: Use Local WC Functions
                $product = wc_get_product($product_id);
                if ($product) {
                    $products[$product_id] = [
                        'id' => $product->get_id(),
                        'name' => $product->get_name(),
                        'sku' => $product->get_sku(),
                        'slug' => $product->get_slug(),
                    ];
                } else {
                    if (class_exists('ShopCentral_Logger')) {
                        ShopCentral_Logger::warning('product_sync', "[QUEUE DEBUG] get_source_products() - Product not found locally: $product_id");
                    }
                }
            } else {
                // Child Store: Use REST API
                $url = trailingslashit($store['url']) . "wp-json/wc/v3/products/$product_id";
                $response = wp_remote_get($url, [
                    'headers' => [
                        'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                    ],
                    'timeout' => 30,
                ]);

                if (is_wp_error($response)) {
                    if (class_exists('ShopCentral_Logger')) {
                        ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] get_source_products() - API error for product $product_id", [
                            'error' => $response->get_error_message(),
                        ]);
                    }
                } else {
                    $product = json_decode(wp_remote_retrieve_body($response), true);
                    if ($product) {
                        $products[$product_id] = [
                            'id' => $product['id'],
                            'name' => $product['name'] ?? '',
                            'sku' => $product['sku'] ?? '',
                            'slug' => $product['slug'] ?? '',
                        ];
                    }
                }
            }
        }

        return $products;
    }

    /**
     * Find matching product in target store
     * Primary: Match by SKU
     * Fallback: Match by Slug
     * Return: Target product ID or null
     */
    private static function find_matching_product($store, $source_product, $source_product_id)
    {
        if (!$source_product) {
            return null;
        }

        $target_product_id = null;

        // Primary: Match by SKU (if SKU exists)
        if (!empty($source_product['sku'])) {
            $target_product_id = self::find_product_by_sku($store, $source_product['sku']);
        }

        // Fallback: Match by Slug
        if (!$target_product_id && !empty($source_product['slug'])) {
            $target_product_id = self::find_product_by_slug($store, $source_product['slug']);
        }

        return $target_product_id;
    }

    /**
     * Find product by SKU in target store
     */
    private static function find_product_by_sku($store, $sku)
    {
        // Check if this is the main store
        $main_site_url = home_url();
        $store_url = trailingslashit($store['url']);
        $is_main_site = (trailingslashit($main_site_url) === $store_url) || !empty($store['is_current']);

        if ($is_main_site) {
            // Main Store: Use Local WC Functions
            $product_id = wc_get_product_id_by_sku($sku);
            return $product_id ?: null;
        }

        // Child Store: Use REST API
        $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products';
        $response = wp_remote_get(add_query_arg(['sku' => $sku], $url), [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
            ],
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            return null;
        }

        $products = json_decode(wp_remote_retrieve_body($response), true);
        return $products[0]['id'] ?? null;
    }

    /**
     * Find product by Slug in target store
     */
    private static function find_product_by_slug($store, $slug)
    {
        // Check if this is the main store
        $main_site_url = home_url();
        $store_url = trailingslashit($store['url']);
        $is_main_site = (trailingslashit($main_site_url) === $store_url) || !empty($store['is_current']);

        if ($is_main_site) {
            // Main Store: Use Local WP Functions
            $page = get_page_by_path($slug, OBJECT, 'product');
            return $page ? $page->ID : null;
        }

        // Child Store: Use REST API
        $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products';
        $response = wp_remote_get(add_query_arg(['slug' => $slug], $url), [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
            ],
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            return null;
        }

        $products = json_decode(wp_remote_retrieve_body($response), true);
        return $products[0]['id'] ?? null;
    }

    /**
     * Update product on a specific store
     * - Main Store: Uses Local WC Functions
     * - Child Store: Uses WooCommerce REST API
     */
    private static function update_product_on_store($product_id, $store, $changes)
    {
        if (!$product_id || !$store) {
            return false;
        }

        // Check if this is the main store
        $main_site_url = home_url();
        $store_url = trailingslashit($store['url']);
        $is_main_site = (trailingslashit($main_site_url) === $store_url) || !empty($store['is_current']);

        if ($is_main_site) {
            // Main Store: Use Local WC Functions
            return self::update_local_product($product_id, $changes);
        }

        // Child Store: Use WooCommerce REST API
        return self::update_remote_product($product_id, $store, $changes);
    }

    /**
     * Update product on local store using WC functions
     */
    private static function update_local_product($product_id, $changes)
    {
        $product = wc_get_product($product_id);

        if (!$product) {
            return false;
        }

        // Apply changes using WC_Product methods
        if (isset($changes['name'])) $product->set_name($changes['name']);
        if (isset($changes['slug'])) $product->set_slug($changes['slug']);
        if (isset($changes['sku'])) $product->set_sku($changes['sku']);
        if (isset($changes['status'])) $product->set_status($changes['status']);
        if (isset($changes['featured'])) $product->set_featured($changes['featured']);
        if (isset($changes['catalog_visibility'])) $product->set_catalog_visibility($changes['catalog_visibility']);
        if (isset($changes['regular_price'])) $product->set_regular_price($changes['regular_price']);
        if (isset($changes['sale_price'])) $product->set_sale_price($changes['sale_price']);
        if (isset($changes['manage_stock'])) $product->set_manage_stock($changes['manage_stock']);
        if (isset($changes['stock_quantity'])) $product->set_stock_quantity($changes['stock_quantity']);
        if (isset($changes['stock_status'])) $product->set_stock_status($changes['stock_status']);
        if (isset($changes['backorders'])) $product->set_backorders($changes['backorders']);
        if (isset($changes['weight'])) $product->set_weight($changes['weight']);
        if (isset($changes['length'])) $product->set_length($changes['length']);
        if (isset($changes['width'])) $product->set_width($changes['width']);
        if (isset($changes['height'])) $product->set_height($changes['height']);
        if (isset($changes['description'])) $product->set_description($changes['description']);
        if (isset($changes['short_description'])) $product->set_short_description($changes['short_description']);
        if (isset($changes['purchase_note'])) $product->set_purchase_note($changes['purchase_note']);
        if (isset($changes['reviews_enabled'])) $product->set_reviews_allowed($changes['reviews_enabled']);
        if (isset($changes['menu_order'])) $product->set_menu_order($changes['menu_order']);

        $product->save();

        // Update variations if provided (for variable products)
        if (!empty($changes['variations']) && $product->is_type('variable')) {
            self::update_local_variations($changes['variations']);
        }

        return true;
    }

    /**
     * Update variations on local store using WC functions
     */
    private static function update_local_variations($variations)
    {
        foreach ($variations as $var_data) {
            $variation_id = intval($var_data['id'] ?? 0);
            if (!$variation_id) continue;

            $variation = wc_get_product($variation_id);
            if (!$variation) continue;

            if (isset($var_data['regular_price'])) $variation->set_regular_price($var_data['regular_price']);
            if (isset($var_data['sale_price'])) $variation->set_sale_price($var_data['sale_price']);
            if (isset($var_data['sku'])) $variation->set_sku($var_data['sku']);
            if (isset($var_data['stock_quantity'])) $variation->set_stock_quantity(intval($var_data['stock_quantity']));

            $variation->save();
        }
    }

    /**
     * Update product on remote store via WooCommerce REST API
     */
    private static function update_remote_product($product_id, $store, $changes)
    {
        $url = trailingslashit($store['url']) . "wp-json/wc/v3/products/$product_id";

        // Filter out non-updatable fields
        $allowed_fields = [
            'name', 'slug', 'sku', 'status', 'featured', 'catalog_visibility',
            'regular_price', 'sale_price', 'sale_price_date_from', 'sale_price_date_to',
            'manage_stock', 'stock_quantity', 'stock_status', 'backorders',
            'weight', 'length', 'width', 'height', 'shipping_class_id',
            'description', 'short_description', 'categories', 'tags', 'images',
            'upsell_ids', 'cross_sell_ids', 'related_ids', 'purchase_note',
            'reviews_enabled', 'menu_order', 'type', 'virtual', 'downloadable'
        ];

        $update_data = array_intersect_key($changes, array_flip($allowed_fields));

        // Extract variations to handle separately
        $variations = $changes['variations'] ?? [];

        if (empty($update_data) && empty($variations)) {
            return false;
        }

        // Update main product if there are changes
        if (!empty($update_data)) {
            $response = wp_remote_post($url, [
                'method'  => 'PUT',
                'headers' => [
                    'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                    'Content-Type'  => 'application/json',
                ],
                'body'    => wp_json_encode($update_data),
                'timeout' => 30,
            ]);

            if (is_wp_error($response)) {
                return false;
            }

            $status_code = wp_remote_retrieve_response_code($response);
            if ($status_code < 200 || $status_code > 299) {
                return false;
            }
        }

        // Update variations if provided
        if (!empty($variations)) {
            self::update_remote_variations($product_id, $store, $variations);
        }

        return true;
    }

    /**
     * Update variations on remote store via WooCommerce REST API batch endpoint
     */
    private static function update_remote_variations($product_id, $store, $variations)
    {
        $url = trailingslashit($store['url']) . "wp-json/wc/v3/products/$product_id/variations/batch";

        $batch_items = [];
        foreach ($variations as $var_data) {
            $variation_id = intval($var_data['id'] ?? 0);
            if (!$variation_id) continue;

            $item = ['id' => $variation_id];
            if (isset($var_data['regular_price'])) $item['regular_price'] = $var_data['regular_price'];
            if (isset($var_data['sale_price'])) $item['sale_price'] = $var_data['sale_price'];
            if (isset($var_data['sku'])) $item['sku'] = $var_data['sku'];
            if (isset($var_data['stock_quantity'])) $item['stock_quantity'] = intval($var_data['stock_quantity']);

            $batch_items[] = $item;
        }

        if (empty($batch_items)) {
            return;
        }

        wp_remote_post($url, [
            'method'  => 'POST',
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode(['update' => $batch_items]),
            'timeout' => 60,
        ]);
    }

    /**
     * Update multiple products on remote store using WooCommerce Batch API
     * More efficient - updates up to 100 products in a single request
     *
     * @param array $product_mapping Source ID => Target ID mapping
     * @param array $store Store data
     * @param array $changes Changes to apply
     * @return array ['success' => int, 'failed' => int]
     */
    private static function update_products_batch($product_mapping, $store, $changes)
    {
        // Check if this is the main store - use local batch update
        $main_site_url = home_url();
        $store_url = trailingslashit($store['url']);
        $is_main_site = (trailingslashit($main_site_url) === $store_url) || !empty($store['is_current']);

        if ($is_main_site) {
            return self::update_local_products_batch($product_mapping, $changes);
        }

        return self::update_remote_products_batch($product_mapping, $store, $changes);
    }

    /**
     * Batch update for local store using WC functions
     */
    private static function update_local_products_batch($product_mapping, $changes)
    {
        $success = 0;
        $failed = 0;

        foreach ($product_mapping as $source_id => $target_id) {
            $result = self::update_local_product($target_id, $changes);
            if ($result) {
                $success++;
            } else {
                $failed++;
            }
        }

        return ['success' => $success, 'failed' => $failed];
    }

    /**
     * Batch update for remote store using WooCommerce REST API
     * Uses /wp-json/wc/v3/products/batch endpoint
     */
    private static function update_remote_products_batch($product_mapping, $store, $changes)
    {
        $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products/batch';

        // Filter out non-updatable fields
        $allowed_fields = [
            'name', 'slug', 'sku', 'status', 'featured', 'catalog_visibility',
            'regular_price', 'sale_price', 'sale_price_date_from', 'sale_price_date_to',
            'manage_stock', 'stock_quantity', 'stock_status', 'backorders',
            'weight', 'length', 'width', 'height', 'shipping_class_id',
            'description', 'short_description', 'categories', 'tags', 'images',
            'upsell_ids', 'cross_sell_ids', 'related_ids', 'purchase_note',
            'reviews_enabled', 'menu_order', 'type', 'virtual', 'downloadable'
        ];

        $update_data = array_intersect_key($changes, array_flip($allowed_fields));

        if (empty($update_data)) {
            return ['success' => 0, 'failed' => count($product_mapping)];
        }

        // Build batch update array
        $batch_items = [];
        foreach ($product_mapping as $source_id => $target_id) {
            $batch_items[] = array_merge(['id' => $target_id], $update_data);
        }

        // WooCommerce batch API supports max 100 items per request
        $chunks = array_chunk($batch_items, 100);

        $total_success = 0;
        $total_failed = 0;

        foreach ($chunks as $chunk) {
            $response = wp_remote_post($url, [
                'method'  => 'POST',
                'headers' => [
                    'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                    'Content-Type'  => 'application/json',
                ],
                'body'    => wp_json_encode(['update' => $chunk]),
                'timeout' => 60, // Longer timeout for batch
            ]);

            if (is_wp_error($response)) {
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] Batch API error", [
                        'error' => $response->get_error_message(),
                    ]);
                }
                $total_failed += count($chunk);
                continue;
            }

            $status_code = wp_remote_retrieve_response_code($response);
            $body = json_decode(wp_remote_retrieve_body($response), true);

            if ($status_code >= 200 && $status_code <= 299 && isset($body['update'])) {
                // Count successful updates
                $chunk_success = count($body['update']);
                $total_success += $chunk_success;
                $total_failed += (count($chunk) - $chunk_success);

                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::info('product_sync', "[QUEUE DEBUG] Batch API success", [
                        'status_code' => $status_code,
                        'success_count' => $chunk_success,
                        'total_in_chunk' => count($chunk),
                    ]);
                }
            } else {
                $total_failed += count($chunk);
                if (class_exists('ShopCentral_Logger')) {
                    ShopCentral_Logger::error('product_sync', "[QUEUE DEBUG] Batch API failed", [
                        'status_code' => $status_code,
                        'response' => $body,
                    ]);
                }
            }
        }

        return ['success' => $total_success, 'failed' => $total_failed];
    }

    /**
     * Update queue status
     */
    public static function update_status($uuid, $status)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';

        $wpdb->update($table, ['status' => $status], ['queue_uuid' => $uuid]);
    }

    /**
     * Log activity
     */
    private static function log_activity($queue_uuid, $entity_id, $action, $entity_type = 'product', $store_id = null, $user_id = null, $details = null)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_activity_log';

        $queue_id = $wpdb->get_var(
            $wpdb->prepare("SELECT id FROM {$wpdb->prefix}shopcentral_deploy_queue WHERE queue_uuid = %s", $queue_uuid)
        );

        $wpdb->insert($table, [
            'queue_id'    => $queue_id,
            'action'      => $action,
            'entity_type' => $entity_type,
            'entity_id'   => $entity_id,
            'store_id'    => $store_id,
            'user_id'     => $user_id ?: get_current_user_id(),
            'details'     => $details,
            'ip_address'  => $_SERVER['REMOTE_ADDR'] ?? null,
        ]);
    }
}
