<?php
/**
 * Global Product Editor - Main Controller
 *
 * @package ShopCentral
 * @subpackage ProductEditor
 */

defined('ABSPATH') || exit;

class ShopCentral_Product_Editor
{
    const API_NAMESPACE = 'shopcentral/v1';

    const STATUS_QUEUED = 'queued';
    const STATUS_PROCESSING = 'processing';
    const STATUS_COMPLETED = 'completed';
    const STATUS_FAILED = 'failed';
    const STATUS_CANCELLED = 'cancelled';

    const CONFLICT_KEEP_SOURCE = 'keep_source';
    const CONFLICT_KEEP_DESTINATION = 'keep_destination';
    const CONFLICT_MERGE = 'merge';

    public static function init()
    {
        add_action('rest_api_init', [__CLASS__, 'register_rest_routes']);
    }

    public static function register_rest_routes()
    {
        $namespace = self::API_NAMESPACE . '/product-editor';

        // Products
        register_rest_route($namespace, '/products', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_products'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/products/(?P<store_id>\d+)/(?P<product_id>\d+)', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_product'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/products/update', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'update_product'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Variations
        register_rest_route($namespace, '/product/(?P<product_id>\d+)/variations', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_variations'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/product/(?P<product_id>\d+)/variations/update', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'update_variations'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Image upload
        register_rest_route($namespace, '/product/upload-images', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'upload_product_images'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Bulk operations
        register_rest_route($namespace, '/bulk-update', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'bulk_update'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Compare
        register_rest_route($namespace, '/compare', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'compare_products'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Deploy
        register_rest_route($namespace, '/deploy', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'deploy_changes'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Queue
        register_rest_route($namespace, '/queue', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_queue'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/queue/(?P<uuid>[a-f0-9-]+)', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_queue_item'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/queue/(?P<uuid>[a-f0-9-]+)/cancel', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'cancel_queue'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/queue/(?P<uuid>[a-f0-9-]+)/process', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'process_queue'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Pending changes
        register_rest_route($namespace, '/pending', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_pending_changes'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/pending/save', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'save_pending_changes'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Versions
        register_rest_route($namespace, '/versions/(?P<store_id>\d+)/(?P<product_id>\d+)', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_versions'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        register_rest_route($namespace, '/versions/restore', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'restore_version'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Activity log
        register_rest_route($namespace, '/activity', [
            'methods'  => 'GET',
            'callback' => [__CLASS__, 'get_activity_log'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);

        // Validation
        register_rest_route($namespace, '/validate', [
            'methods'  => 'POST',
            'callback' => [__CLASS__, 'validate_data'],
            'permission_callback' => [__CLASS__, 'check_permissions'],
        ]);
    }

    public static function check_permissions()
    {
        return current_user_can('manage_woocommerce');
    }

    /**
     * Get products from a store with filtering
     */
    public static function get_products($request)
    {
        global $wpdb;

        $store_id = $request->get_param('store_id');
        $search = $request->get_param('search');
        $category = $request->get_param('category');
        $status = $request->get_param('status');
        $type = $request->get_param('type');
        $page = max(1, intval($request->get_param('page') ?: 1));
        $per_page = min(100, max(1, intval($request->get_param('per_page') ?: 20)));

        if (!$store_id) {
            return new WP_Error('no_store', 'Store ID required', ['status' => 400]);
        }

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

        if (!$store) {
            return new WP_Error('not_found', 'Store not found', ['status' => 404]);
        }

        // Check if this is the main store (where plugin is installed)
        $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 WooCommerce Functions (no API key needed)
            return self::get_local_products($search, $category, $status, $page, $per_page, $type);
        }

        // Child Store: Use WooCommerce REST API
        return self::get_remote_products($store, $search, $category, $status, $page, $per_page, $type);
    }

    /**
     * Get products from local WooCommerce (main store)
     * Uses WC_Product functions - no API key needed
     */
    private static function get_local_products($search, $category, $status, $page, $per_page, $type = null)
    {
        if (!class_exists('WooCommerce')) {
            return new WP_Error('no_woocommerce', 'WooCommerce is not active on this site');
        }

        $args = [
            'status'  => $status ?: 'publish',
            'limit'   => $per_page,
            'page'    => $page,
            'orderby' => 'title',
            'order'   => 'ASC',
        ];

        // Filter by type if specified
        if ($type && $type !== 'all') {
            $args['type'] = [$type];
        } else {
            $args['type'] = ['simple', 'variable', 'downloadable', 'virtual', 'grouped', 'external'];
        }

        if ($search) {
            $args['s'] = $search;
        }

        if ($category) {
            $args['category'] = [$category];
        }

        $products = wc_get_products($args);
        $total = 0;

        // Get total count
        $count_args = $args;
        $count_args['limit'] = -1;
        $count_args['return'] = 'ids';
        $all_products = wc_get_products($count_args);
        $total = count($all_products);

        // Format products to match REST API response
        $formatted_products = [];
        foreach ($products as $product) {
            $formatted_products[] = [
                'id' => $product->get_id(),
                'name' => $product->get_name(),
                'slug' => $product->get_slug(),
                'sku' => $product->get_sku(),
                'type' => $product->get_type(),
                'status' => $product->get_status(),
                'featured' => $product->get_featured(),
                'catalog_visibility' => $product->get_catalog_visibility(),
                'short_description' => $product->get_short_description(),
                'description' => $product->get_description(),
                'regular_price' => $product->get_regular_price(),
                'sale_price' => $product->get_sale_price(),
                'date_on_sale_from' => $product->get_date_on_sale_from(),
                'date_on_sale_to' => $product->get_date_on_sale_to(),
                'manage_stock' => $product->get_manage_stock(),
                'stock_quantity' => $product->get_stock_quantity(),
                'stock_status' => $product->get_stock_status(),
                'backorders' => $product->get_backorders(),
                'low_stock_amount' => $product->get_low_stock_amount(),
                'weight' => $product->get_weight(),
                'length' => $product->get_length(),
                'width' => $product->get_width(),
                'height' => $product->get_height(),
                'shipping_class' => $product->get_shipping_class(),
                'shipping_class_id' => $product->get_shipping_class_id(),
                'categories' => self::get_product_categories($product),
                'tags' => self::get_product_tags($product),
                'images' => self::get_product_images($product),
                'attributes' => self::get_product_attributes($product),
                'upsell_ids' => $product->get_upsell_ids(),
                'cross_sell_ids' => $product->get_cross_sell_ids(),
                'purchase_note' => $product->get_purchase_note(),
                'reviews_enabled' => $product->get_reviews_allowed(),
                'menu_order' => $product->get_menu_order(),
            ];
        }

        return new WP_REST_Response([
            'data'  => $formatted_products,
            'total' => $total,
            'pages' => ceil($total / $per_page),
            'page'  => $page,
        ], 200);
    }

    /**
     * Get product categories in REST API format
     */
    private static function get_product_categories($product)
    {
        $categories = [];
        $terms = get_the_terms($product->get_id(), 'product_cat');
        if ($terms && !is_wp_error($terms)) {
            foreach ($terms as $term) {
                $categories[] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                    'slug' => $term->slug,
                ];
            }
        }
        return $categories;
    }

    /**
     * Get product tags in REST API format
     */
    private static function get_product_tags($product)
    {
        $tags = [];
        $terms = get_the_terms($product->get_id(), 'product_tag');
        if ($terms && !is_wp_error($terms)) {
            foreach ($terms as $term) {
                $tags[] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                    'slug' => $term->slug,
                ];
            }
        }
        return $tags;
    }

    /**
     * Get product images in REST API format
     */
    private static function get_product_images($product)
    {
        $images = [];
        $featured_image_id = $product->get_image_id();
        if ($featured_image_id) {
            $images[] = [
                'id' => $featured_image_id,
                'src' => wp_get_attachment_url($featured_image_id),
                'name' => get_the_title($featured_image_id),
            ];
        }
        $gallery_ids = $product->get_gallery_image_ids();
        foreach ($gallery_ids as $gallery_id) {
            $images[] = [
                'id' => $gallery_id,
                'src' => wp_get_attachment_url($gallery_id),
                'name' => get_the_title($gallery_id),
            ];
        }
        return $images;
    }

    /**
     * Get product attributes in REST API format
     */
    private static function get_product_attributes($product)
    {
        $attributes = [];
        $product_attributes = $product->get_attributes();
        foreach ($product_attributes as $attribute) {
            $attribute_data = [
                'id' => $attribute->get_id(),
                'name' => $attribute->get_name(),
                'position' => $attribute->get_position(),
                'visible' => $attribute->get_visible(),
                'variation' => $attribute->get_variation(),
                'options' => [],
            ];
            if ($attribute->is_taxonomy()) {
                $terms = $attribute->get_terms();
                if ($terms) {
                    foreach ($terms as $term) {
                        $attribute_data['options'][] = $term->name;
                    }
                }
            } else {
                $attribute_data['options'] = $attribute->get_options();
            }
            $attributes[] = $attribute_data;
        }
        return $attributes;
    }

    /**
     * Get products from remote store via WooCommerce REST API
     */
    private static function get_remote_products($store, $search, $category, $status, $page, $per_page, $type = null)
    {
        $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products';
        $params = [
            'page'    => $page,
            'per_page' => $per_page,
            'orderby' => 'title',
            'order'   => 'asc',
        ];

        if ($search) $params['search'] = $search;
        if ($category) $params['category'] = $category;
        if ($status) $params['status'] = $status;
        if ($type && $type !== 'all') $params['type'] = $type;

        $response = wp_remote_get(add_query_arg($params, $url), [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
            ],
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            return new WP_Error('api_error', $response->get_error_message());
        }

        $products = json_decode(wp_remote_retrieve_body($response), true);
        $total = intval($response['headers']['x-wp-total'] ?? 0);
        $pages = intval($response['headers']['x-wp-totalpages'] ?? 0);

        return new WP_REST_Response([
            'data'  => $products,
            'total' => $total,
            'pages' => $pages,
            'page'  => $page,
        ], 200);
    }

    /**
     * Get single product
     * - Main Store: Uses Local WC Functions
     * - Child Store: Uses WooCommerce REST API
     */
    public static function get_product($request)
    {
        global $wpdb;

        $store_id = intval($request->get_param('store_id'));
        $product_id = intval($request->get_param('product_id'));

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

        if (!$store) {
            return new WP_Error('not_found', 'Store not found', ['status' => 404]);
        }

        // Check if this is the main store (where plugin is installed)
        $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 = wc_get_product($product_id);
            if (!$product) {
                return new WP_Error('not_found', 'Product not found', ['status' => 404]);
            }

            $product_data = [
                'id' => $product->get_id(),
                'name' => $product->get_name(),
                'slug' => $product->get_slug(),
                'sku' => $product->get_sku(),
                'type' => $product->get_type(),
                'status' => $product->get_status(),
                'featured' => $product->get_featured(),
                'catalog_visibility' => $product->get_catalog_visibility(),
                'short_description' => $product->get_short_description(),
                'description' => $product->get_description(),
                'regular_price' => $product->get_regular_price(),
                'sale_price' => $product->get_sale_price(),
                'date_on_sale_from' => $product->get_date_on_sale_from(),
                'date_on_sale_to' => $product->get_date_on_sale_to(),
                'manage_stock' => $product->get_manage_stock(),
                'stock_quantity' => $product->get_stock_quantity(),
                'stock_status' => $product->get_stock_status(),
                'backorders' => $product->get_backorders(),
                'low_stock_amount' => $product->get_low_stock_amount(),
                'weight' => $product->get_weight(),
                'length' => $product->get_length(),
                'width' => $product->get_width(),
                'height' => $product->get_height(),
                'shipping_class' => $product->get_shipping_class(),
                'shipping_class_id' => $product->get_shipping_class_id(),
                'categories' => self::get_product_categories($product),
                'tags' => self::get_product_tags($product),
                'images' => self::get_product_images($product),
                'attributes' => self::get_product_attributes($product),
                'upsell_ids' => $product->get_upsell_ids(),
                'cross_sell_ids' => $product->get_cross_sell_ids(),
                'purchase_note' => $product->get_purchase_note(),
                'reviews_enabled' => $product->get_reviews_allowed(),
                'menu_order' => $product->get_menu_order(),
            ];

            return new WP_REST_Response($product_data, 200);
        }

        // Child Store: Use WooCommerce 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)) {
            return new WP_Error('api_error', $response->get_error_message());
        }

        $product = json_decode(wp_remote_retrieve_body($response), true);

        return new WP_REST_Response($product, 200);
    }

    /**
     * Get variations for a variable product
     * - Main Store: Uses Local WC Functions
     * - Child Store: Uses WooCommerce REST API
     */
    public static function get_variations($request)
    {
        global $wpdb;

        $store_id = intval($request->get_param('store_id'));
        $product_id = intval($request->get_param('product_id'));

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

        if (!$store) {
            return new WP_Error('not_found', 'Store not found', ['status' => 404]);
        }

        // 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 = wc_get_product($product_id);
            if (!$product || !$product->is_type('variable')) {
                return new WP_Error('not_found', 'Variable product not found', ['status' => 404]);
            }

            $variations_data = [];
            $children = $product->get_children();

            foreach ($children as $variation_id) {
                $variation = wc_get_product($variation_id);
                if (!$variation) continue;

                $variations_data[] = [
                    'id' => $variation->get_id(),
                    'sku' => $variation->get_sku(),
                    'regular_price' => $variation->get_regular_price(),
                    'sale_price' => $variation->get_sale_price(),
                    'stock_quantity' => $variation->get_stock_quantity(),
                    'stock_status' => $variation->get_stock_status(),
                    'attributes' => self::get_variation_attributes($variation),
                ];
            }

            return new WP_REST_Response(['data' => $variations_data], 200);
        }

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

        if (is_wp_error($response)) {
            return new WP_Error('api_error', $response->get_error_message());
        }

        $variations = json_decode(wp_remote_retrieve_body($response), true);

        // Format variations to match our structure
        $variations_data = [];
        foreach ($variations as $variation) {
            $variations_data[] = [
                'id' => $variation['id'],
                'sku' => $variation['sku'] ?? '',
                'regular_price' => $variation['regular_price'] ?? '',
                'sale_price' => $variation['sale_price'] ?? '',
                'stock_quantity' => $variation['stock_quantity'] ?? 0,
                'stock_status' => $variation['stock_status'] ?? 'instock',
                'attributes' => array_map(function ($attr) {
                    return ['name' => $attr['name'], 'option' => $attr['option']];
                }, $variation['attributes'] ?? []),
            ];
        }

        return new WP_REST_Response(['data' => $variations_data], 200);
    }

    /**
     * Get variation attributes in formatted structure
     */
    private static function get_variation_attributes($variation)
    {
        $attributes = [];
        $raw_attributes = $variation->get_attributes();

        foreach ($raw_attributes as $name => $value) {
            $attr_name = str_replace('attribute_', '', $name);
            $attributes[] = [
                'name' => $attr_name,
                'option' => $value,
            ];
        }

        return $attributes;
    }

    /**
     * Update variations for a variable product
     */
    public static function update_variations($request)
    {
        global $wpdb;

        $params = $request->get_json_params();
        $store_id = intval($params['store_id'] ?? 0);
        $product_id = intval($request->get_param('product_id'));
        $variations = $params['variations'] ?? [];

        if (empty($variations)) {
            return new WP_Error('no_variations', 'No variations provided', ['status' => 400]);
        }

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

        if (!$store) {
            return new WP_Error('not_found', 'Store not found', ['status' => 404]);
        }

        // 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']);

        $updated = 0;
        $failed = 0;

        if ($is_main_site) {
            // Main Store: Use Local WC Functions
            foreach ($variations as $var_data) {
                $variation_id = intval($var_data['id'] ?? 0);
                if (!$variation_id) continue;

                $variation = wc_get_product($variation_id);
                if (!$variation) {
                    $failed++;
                    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();
                $updated++;
            }
        } else {
            // Child Store: Use WooCommerce REST API batch endpoint
            $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)) {
                $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' => $batch_items]),
                    'timeout' => 60,
                ]);

                if (is_wp_error($response)) {
                    return new WP_Error('api_error', $response->get_error_message());
                }

                $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'])) {
                    $updated = count($body['update']);
                    $failed = count($batch_items) - $updated;
                } else {
                    $failed = count($batch_items);
                }
            }
        }

        return new WP_REST_Response([
            'message' => 'Variations updated',
            'updated' => $updated,
            'failed'  => $failed,
        ], 200);
    }

    /**
     * Upload product images (featured + gallery)
     * Handles both main store (WC Functions) and remote store (REST API)
     */
    public static function upload_product_images($request)
    {
        global $wpdb;

        $product_id = intval($_POST['product_id'] ?? 0);
        $store_id = intval($_POST['store_id'] ?? 0);

        if (!$product_id) {
            return new WP_Error('missing_data', 'Product ID required', ['status' => 400]);
        }

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

        if (!$store) {
            return new WP_Error('not_found', 'Store not found', ['status' => 404]);
        }

        // 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) {
            return self::upload_images_local($product_id, $_FILES);
        }

        return self::upload_images_remote($product_id, $store, $_FILES);
    }

    /**
     * Upload images to local store using WP media functions
     */
    private static function upload_images_local($product_id, $files)
    {
        if (!class_exists('WooCommerce')) {
            return new WP_Error('no_woocommerce', 'WooCommerce is not active');
        }

        $product = wc_get_product($product_id);
        if (!$product) {
            return new WP_Error('not_found', 'Product not found', ['status' => 404]);
        }

        $featured_id = null;
        $gallery_ids = [];

        // Handle featured image
        if (!empty($files['featured_image'])) {
            $featured_id = self::handle_image_upload($files['featured_image']);
            if ($featured_id && !is_wp_error($featured_id)) {
                $product->set_image_id($featured_id);
            }
        }

        // Handle gallery images
        if (!empty($files['gallery_images'])) {
            $gallery_files = $files['gallery_images'];
            $num_files = is_array($gallery_files['name']) ? count($gallery_files['name']) : 1;

            for ($i = 0; $i < $num_files; $i++) {
                $file = [
                    'name' => is_array($gallery_files['name']) ? $gallery_files['name'][$i] : $gallery_files['name'],
                    'type' => is_array($gallery_files['type']) ? $gallery_files['type'][$i] : $gallery_files['type'],
                    'tmp_name' => is_array($gallery_files['tmp_name']) ? $gallery_files['tmp_name'][$i] : $gallery_files['tmp_name'],
                    'error' => is_array($gallery_files['error']) ? $gallery_files['error'][$i] : $gallery_files['error'],
                    'size' => is_array($gallery_files['size']) ? $gallery_files['size'][$i] : $gallery_files['size'],
                ];

                $attachment_id = self::handle_image_upload($file);
                if ($attachment_id && !is_wp_error($attachment_id)) {
                    $gallery_ids[] = $attachment_id;
                }
            }

            // Append to existing gallery
            $existing_gallery = $product->get_gallery_image_ids();
            $product->set_gallery_image_ids(array_merge($existing_gallery, $gallery_ids));
        }

        $product->save();

        return new WP_REST_Response([
            'message' => 'Images uploaded successfully',
            'featured_image' => $featured_id,
            'gallery_images' => $gallery_ids,
        ], 200);
    }

    /**
     * Handle single image upload to WP media library
     */
    private static function handle_image_upload($file)
    {
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');

        $upload = wp_handle_upload($file, ['test_form' => false]);

        if (isset($upload['error'])) {
            return new WP_Error('upload_error', $upload['error']);
        }

        // Create attachment
        $attachment = [
            'post_mime_type' => $upload['type'],
            'post_title' => sanitize_file_name($file['name']),
            'post_content' => '',
            'post_status' => 'inherit',
        ];

        $attachment_id = wp_insert_attachment($attachment, $upload['file']);

        if (is_wp_error($attachment_id)) {
            return $attachment_id;
        }

        // Generate metadata and thumbnails
        $attach_data = wp_generate_attachment_metadata($attachment_id, $upload['file']);
        wp_update_attachment_metadata($attachment_id, $attach_data);

        return $attachment_id;
    }

    /**
     * Upload images to remote store via REST API
     */
    private static function upload_images_remote($product_id, $store, $files)
    {
        $uploaded_featured = null;
        $uploaded_gallery = [];

        // First, upload images to get IDs
        $url = trailingslashit($store['url']) . 'wp-json/wp/v2/media';

        // Upload featured image
        if (!empty($files['featured_image'])) {
            $featured_id = self::upload_single_image_to_remote($files['featured_image'], $url, $store);
            if ($featured_id && !is_wp_error($featured_id)) {
                $uploaded_featured = $featured_id;
            }
        }

        // Upload gallery images
        if (!empty($files['gallery_images'])) {
            $gallery_files = $files['gallery_images'];
            $num_files = is_array($gallery_files['name']) ? count($gallery_files['name']) : 1;

            for ($i = 0; $i < $num_files; $i++) {
                $file = [
                    'name' => is_array($gallery_files['name']) ? $gallery_files['name'][$i] : $gallery_files['name'],
                    'type' => is_array($gallery_files['type']) ? $gallery_files['type'][$i] : $gallery_files['type'],
                    'tmp_name' => is_array($gallery_files['tmp_name']) ? $gallery_files['tmp_name'][$i] : $gallery_files['tmp_name'],
                    'error' => is_array($gallery_files['error']) ? $gallery_files['error'][$i] : $gallery_files['error'],
                    'size' => is_array($gallery_files['size']) ? $gallery_files['size'][$i] : $gallery_files['size'],
                ];

                $attachment_id = self::upload_single_image_to_remote($file, $url, $store);
                if ($attachment_id && !is_wp_error($attachment_id)) {
                    $uploaded_gallery[] = $attachment_id;
                }
            }
        }

        // Now update product with image IDs
        if ($uploaded_featured || !empty($uploaded_gallery)) {
            $product_url = trailingslashit($store['url']) . "wp-json/wc/v3/products/$product_id";
            $update_data = [];

            if ($uploaded_featured) {
                $update_data['images'] = [['id' => $uploaded_featured]];
            }

            if (!empty($uploaded_gallery)) {
                // Get existing images first
                $existing = self::get_remote_product($store, $product_id);
                $existing_images = $existing['images'] ?? [];

                // Replace featured, append gallery
                $new_images = [];
                if ($uploaded_featured) {
                    $new_images[] = ['id' => $uploaded_featured];
                } elseif (!empty($existing_images)) {
                    $new_images[] = $existing_images[0]; // Keep existing featured
                }

                // Add gallery images (skip first which is featured)
                $existing_gallery = array_slice($existing_images, 1);
                $new_images = array_merge($new_images, $existing_gallery);
                foreach ($uploaded_gallery as $gid) {
                    $new_images[] = ['id' => $gid];
                }

                $update_data['images'] = $new_images;
            }

            if (!empty($update_data)) {
                wp_remote_post($product_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,
                ]);
            }
        }

        return new WP_REST_Response([
            'message' => 'Images uploaded successfully',
            'featured_image' => $uploaded_featured,
            'gallery_images' => $uploaded_gallery,
        ], 200);
    }

    /**
     * Upload single image to remote store
     */
    private static function upload_single_image_to_remote($file, $url, $store)
    {
        if (!file_exists($file['tmp_name'])) {
            return new WP_Error('file_error', 'File not found');
        }

        $file_content = file_get_contents($file['tmp_name']);
        $filename = $file['name'];

        $response = wp_remote_post($url, [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                'Content-Type'  => $file['type'],
                'Content-Disposition' => 'attachment; filename="' . $filename . '"',
            ],
            'body'    => $file_content,
            'timeout' => 60,
        ]);

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

        $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['id'])) {
            return $body['id'];
        }

        return new WP_Error('upload_error', 'Failed to upload image to remote store');
    }

    /**
     * Update product directly (no queue)
     * - Main Store: Uses Local WC Functions
     * - Child Store: Uses WooCommerce REST API (PUT /wp-json/wc/v3/products/<id>)
     */
    public static function update_product($request)
    {
        global $wpdb;

        $params = $request->get_json_params();

        if (empty($params['product_id']) || empty($params['target_store_ids'])) {
            return new WP_Error('missing_data', 'Product ID and target stores required', ['status' => 400]);
        }

        $product_id = intval($params['product_id']);
        $target_store_ids = array_map('intval', $params['target_store_ids']);
        $changes = $params['changes'] ?? [];
        $results = [];

        // Get source product data for matching in remote stores
        $source_product = self::get_source_product_data($product_id);

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

            if (!$store) {
                $results[] = [
                    'store_id' => $store_id,
                    'status' => 'error',
                    'message' => 'Store not found',
                ];
                continue;
            }

            // 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
                $result = self::update_product_local($product_id, $changes);
                $results[] = [
                    'store_id' => $store_id,
                    'store_name' => $store['name'],
                    'status' => $result ? 'success' : 'error',
                    'message' => $result ? 'Product updated' : 'Failed to update product',
                ];
            } else {
                // Child Store: Find matching product by SKU first
                $target_product_id = self::find_matching_product_for_store($store, $source_product, $product_id);

                if (!$target_product_id) {
                    $results[] = [
                        'store_id' => $store_id,
                        'store_name' => $store['name'],
                        'status' => 'error',
                        'message' => 'Matching product not found in this store (SKU: ' . ($source_product['sku'] ?? 'N/A') . ')',
                    ];
                    continue;
                }

                // Child Store: Use WooCommerce REST API with matched ID
                $result = self::update_product_remote($target_product_id, $store, $changes);
                $results[] = [
                    'store_id' => $store_id,
                    'store_name' => $store['name'],
                    'status' => $result['success'] ? 'success' : 'error',
                    'message' => $result['message'],
                    'code' => $result['code'] ?? null,
                ];
            }
        }

        return new WP_REST_Response([
            'message' => 'Product update completed',
            'results' => $results,
        ], 200);
    }

    /**
     * Get source product data for matching (SKU, slug)
     */
    private static function get_source_product_data($product_id)
    {
        // Try local first (main store)
        $product = wc_get_product($product_id);
        if ($product) {
            return [
                'id' => $product->get_id(),
                'name' => $product->get_name(),
                'sku' => $product->get_sku(),
                'slug' => $product->get_slug(),
            ];
        }
        return null;
    }

    /**
     * Update product on local store using WC functions
     */
    private static function update_product_local($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['sale_price_date_from'])) $product->set_date_on_sale_from($changes['sale_price_date_from']);
        if (isset($changes['sale_price_date_to'])) $product->set_date_on_sale_to($changes['sale_price_date_to']);
        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
     * Uses PUT /wp-json/wc/v3/products/<id>
     * Returns array with status and message
     */
    private static function update_product_remote($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', 'date_on_sale_from', 'date_on_sale_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' => false, 'message' => 'No valid fields to update'];
        }

        $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 ['success' => false, 'message' => $response->get_error_message()];
        }

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

        // Check for error response
        if ($status_code < 200 || $status_code > 299) {
            $error_message = isset($body['message']) ? $body['message'] : "HTTP Error: $status_code";
            $error_code = isset($body['code']) ? $body['code'] : 'unknown_error';
            return ['success' => false, 'message' => $error_message, 'code' => $error_code];
        }

        // Update variations if provided (for variable products)
        if (!empty($changes['variations'])) {
            self::update_remote_variations($product_id, $store, $changes['variations']);
        }

        return ['success' => true, 'message' => 'Product updated successfully'];
    }

    /**
     * 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,
        ]);
    }

    /**
     * Bulk update products - Synchronous with progress tracking
     * Max 50 products, uses Batch API for efficiency
     */
    public static function bulk_update($request)
    {
        $params = $request->get_json_params();

        if (empty($params['product_ids']) || empty($params['target_store_ids'])) {
            return new WP_Error('missing_data', 'Product IDs and target stores required', ['status' => 400]);
        }

        // Limit to 50 products max
        if (count($params['product_ids']) > 50) {
            return new WP_Error('too_many_products', 'Maximum 50 products allowed at once. Please select fewer products.', ['status' => 400]);
        }

        global $wpdb;

        $product_ids = array_map('intval', $params['product_ids']);
        $target_store_ids = array_map('intval', $params['target_store_ids']);
        $changes_data = $params['changes'] ?? [];

        $total_products = count($product_ids);
        $total_stores = count($target_store_ids);
        $processed = 0;
        $failed = 0;
        $skipped = 0;
        $results = [];

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

            if (!$store) {
                $results[] = [
                    'store_id' => $store_id,
                    'status' => 'error',
                    'message' => 'Store not found',
                ];
                $failed += $total_products;
                continue;
            }

            // Find matching products
            $products_to_update = [];
            $store_skipped = 0;

            foreach ($product_ids as $product_id) {
                $source_product = self::get_source_product_for_matching($product_id);
                $target_product_id = self::find_matching_product_for_store($store, $source_product, $product_id);

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

            // Update using batch API
            if (!empty($products_to_update)) {
                $batch_result = self::update_products_batch_on_store($products_to_update, $store, $changes_data);
                $processed += $batch_result['success'];
                $failed += $batch_result['failed'];
                $skipped += $store_skipped;

                $results[] = [
                    'store_id' => $store_id,
                    'store_name' => $store['name'],
                    'status' => 'success',
                    'updated' => $batch_result['success'],
                    'failed' => $batch_result['failed'],
                    'skipped' => $store_skipped,
                ];
            } else {
                $skipped += $store_skipped;
                $results[] = [
                    'store_id' => $store_id,
                    'store_name' => $store['name'],
                    'status' => 'skipped',
                    'message' => 'No matching products found',
                    'skipped' => $store_skipped,
                ];
            }
        }

        return new WP_REST_Response([
            'message' => 'Bulk update completed',
            'summary' => [
                'total_products' => $total_products,
                'total_stores' => $total_stores,
                'processed' => $processed,
                'failed' => $failed,
                'skipped' => $skipped,
            ],
            'results' => $results,
        ], 200);
    }

    /**
     * Get source product data for matching
     */
    private static function get_source_product_for_matching($product_id)
    {
        // Try local first
        $product = wc_get_product($product_id);
        if ($product) {
            return [
                'id' => $product->get_id(),
                'name' => $product->get_name(),
                'sku' => $product->get_sku(),
                'slug' => $product->get_slug(),
            ];
        }
        return null;
    }

    /**
     * Find matching product in target store
     */
    private static function find_matching_product_for_store($store, $source_product, $source_product_id)
    {
        if (!$source_product) {
            return null;
        }

        $main_site_url = home_url();
        $store_url = trailingslashit($store['url']);
        $is_main_site = (trailingslashit($main_site_url) === $store_url) || !empty($store['is_current']);

        // Primary: Match by SKU
        if (!empty($source_product['sku'])) {
            if ($is_main_site) {
                $product_id = wc_get_product_id_by_sku($source_product['sku']);
                if ($product_id) return $product_id;
            } else {
                $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products';
                $response = wp_remote_get(add_query_arg(['sku' => $source_product['sku']], $url), [
                    'headers' => [
                        'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                    ],
                    'timeout' => 30,
                ]);
                if (!is_wp_error($response)) {
                    $products = json_decode(wp_remote_retrieve_body($response), true);
                    if (!empty($products[0]['id'])) {
                        return $products[0]['id'];
                    }
                }
            }
        }

        // Fallback: Match by Slug
        if (!empty($source_product['slug'])) {
            if ($is_main_site) {
                $page = get_page_by_path($source_product['slug'], OBJECT, 'product');
                if ($page) return $page->ID;
            } else {
                $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products';
                $response = wp_remote_get(add_query_arg(['slug' => $source_product['slug']], $url), [
                    'headers' => [
                        'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                    ],
                    'timeout' => 30,
                ]);
                if (!is_wp_error($response)) {
                    $products = json_decode(wp_remote_retrieve_body($response), true);
                    if (!empty($products[0]['id'])) {
                        return $products[0]['id'];
                    }
                }
            }
        }

        return null;
    }

    /**
     * Update products on store using batch API
     */
    private static function update_products_batch_on_store($product_mapping, $store, $changes)
    {
        $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
     */
    private static function update_local_products_batch($product_mapping, $changes)
    {
        $success = 0;
        $failed = 0;

        foreach ($product_mapping as $source_id => $target_id) {
            $product = wc_get_product($target_id);
            if (!$product) {
                $failed++;
                continue;
            }

            // Apply changes
            if (isset($changes['action'])) {
                self::apply_changes_to_product($product, $changes);
            }

            $product->save();
            $success++;
        }

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

    /**
     * Apply changes to product based on action
     * Handles simple, variable products, regular & sale price
     */
    private static function apply_changes_to_product($product, $changes)
    {
        $action = $changes['action'] ?? '';
        $value = $changes['value'] ?? '';

        // Handle variable products - update all variations
        if ($product->is_type('variable')) {
            self::apply_changes_to_variable_product($product, $changes);
            return;
        }

        // Apply changes based on action type
        switch ($action) {
            case 'price_increase':
                $current = $product->get_regular_price();
                $product->set_regular_price($current + floatval($value));
                // Also update sale price if it exists
                $sale_price = $product->get_sale_price();
                if ($sale_price) {
                    $product->set_sale_price($sale_price + floatval($value));
                }
                break;
            case 'price_decrease':
                $current = $product->get_regular_price();
                $product->set_regular_price(max(0, $current - floatval($value)));
                $sale_price = $product->get_sale_price();
                if ($sale_price) {
                    $product->set_sale_price(max(0, $sale_price - floatval($value)));
                }
                break;
            case 'percentage_increase':
                $current = $product->get_regular_price();
                $new_price = $current * (1 + floatval($value) / 100);
                $product->set_regular_price(round($new_price, 2));
                $sale_price = $product->get_sale_price();
                if ($sale_price) {
                    $new_sale = $sale_price * (1 + floatval($value) / 100);
                    $product->set_sale_price(round($new_sale, 2));
                }
                break;
            case 'percentage_decrease':
                $current = $product->get_regular_price();
                $new_price = $current * (1 - floatval($value) / 100);
                $product->set_regular_price(round($new_price, 2));
                $sale_price = $product->get_sale_price();
                if ($sale_price) {
                    $new_sale = $sale_price * (1 - floatval($value) / 100);
                    $product->set_sale_price(round($new_sale, 2));
                }
                break;
            case 'fixed_increase':
                $current = $product->get_regular_price();
                $product->set_regular_price($current + floatval($value));
                $sale_price = $product->get_sale_price();
                if ($sale_price) {
                    $product->set_sale_price($sale_price + floatval($value));
                }
                break;
            case 'fixed_decrease':
                $current = $product->get_regular_price();
                $product->set_regular_price(max(0, $current - floatval($value)));
                $sale_price = $product->get_sale_price();
                if ($sale_price) {
                    $product->set_sale_price(max(0, $sale_price - floatval($value)));
                }
                break;
            case 'set_regular_price':
                $product->set_regular_price(floatval($value));
                break;
            case 'set_sale_price':
                $product->set_sale_price(floatval($value));
                break;
            case 'stock_increase':
                $current = $product->get_stock_quantity();
                $product->set_stock_quantity($current + intval($value));
                break;
            case 'stock_decrease':
                $current = $product->get_stock_quantity();
                $product->set_stock_quantity(max(0, $current - intval($value)));
                break;
            case 'change_status':
                $product->set_status($value);
                break;
            case 'enable_featured':
                $product->set_featured(true);
                break;
            case 'disable_featured':
                $product->set_featured(false);
                break;
        }

        // Smart pricing
        if (!empty($changes['smart_pricing']['enabled'])) {
            $round_to = $changes['smart_pricing']['roundTo'] ?? '99';
            $round_nearest = $changes['smart_pricing']['roundNearest'] ?? '1';
            $price = $product->get_regular_price();

            if ($price) {
                // Round to nearest
                if ($round_nearest != '1') {
                    $price = round($price / $round_nearest) * $round_nearest;
                }
                // Add decimal part
                if ($round_to != '00') {
                    $price = floor($price) + ('0.' . $round_to);
                }
                $product->set_regular_price(round($price, 2));
            }
        }
    }

    /**
     * Apply changes to variable product and all its variations
     */
    private static function apply_changes_to_variable_product($product, $changes)
    {
        $action = $changes['action'] ?? '';
        $value = $changes['value'] ?? '';

        // Get all variations
        $variations = $product->get_children();

        foreach ($variations as $variation_id) {
            $variation = wc_get_product($variation_id);
            if (!$variation) continue;

            switch ($action) {
                case 'price_increase':
                    $current = $variation->get_regular_price();
                    $variation->set_regular_price($current + floatval($value));
                    $sale_price = $variation->get_sale_price();
                    if ($sale_price) {
                        $variation->set_sale_price($sale_price + floatval($value));
                    }
                    break;
                case 'price_decrease':
                    $current = $variation->get_regular_price();
                    $variation->set_regular_price(max(0, $current - floatval($value)));
                    $sale_price = $variation->get_sale_price();
                    if ($sale_price) {
                        $variation->set_sale_price(max(0, $sale_price - floatval($value)));
                    }
                    break;
                case 'percentage_increase':
                    $current = $variation->get_regular_price();
                    $new_price = $current * (1 + floatval($value) / 100);
                    $variation->set_regular_price(round($new_price, 2));
                    $sale_price = $variation->get_sale_price();
                    if ($sale_price) {
                        $new_sale = $sale_price * (1 + floatval($value) / 100);
                        $variation->set_sale_price(round($new_sale, 2));
                    }
                    break;
                case 'percentage_decrease':
                    $current = $variation->get_regular_price();
                    $new_price = $current * (1 - floatval($value) / 100);
                    $variation->set_regular_price(round($new_price, 2));
                    $sale_price = $variation->get_sale_price();
                    if ($sale_price) {
                        $new_sale = $sale_price * (1 - floatval($value) / 100);
                        $variation->set_sale_price(round($new_sale, 2));
                    }
                    break;
                case 'fixed_increase':
                    $current = $variation->get_regular_price();
                    $variation->set_regular_price($current + floatval($value));
                    $sale_price = $variation->get_sale_price();
                    if ($sale_price) {
                        $variation->set_sale_price($sale_price + floatval($value));
                    }
                    break;
                case 'fixed_decrease':
                    $current = $variation->get_regular_price();
                    $variation->set_regular_price(max(0, $current - floatval($value)));
                    $sale_price = $variation->get_sale_price();
                    if ($sale_price) {
                        $variation->set_sale_price(max(0, $sale_price - floatval($value)));
                    }
                    break;
                case 'set_regular_price':
                    $variation->set_regular_price(floatval($value));
                    break;
                case 'set_sale_price':
                    $variation->set_sale_price(floatval($value));
                    break;
                case 'stock_increase':
                    $current = $variation->get_stock_quantity();
                    $variation->set_stock_quantity($current + intval($value));
                    break;
                case 'stock_decrease':
                    $current = $variation->get_stock_quantity();
                    $variation->set_stock_quantity(max(0, $current - intval($value)));
                    break;
                case 'change_status':
                    $variation->set_status($value);
                    break;
            }

            $variation->save();
        }
    }

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

        // For price actions that need per-product calculation, fetch each product first
        $needs_per_product_calc = in_array($action, [
            'price_increase', 'price_decrease',
            'fixed_increase', 'fixed_decrease',
            'percentage_increase', 'percentage_decrease'
        ]);

        $batch_items = [];

        foreach ($product_mapping as $source_id => $target_id) {
            $update_data = ['id' => $target_id];

            if ($needs_per_product_calc) {
                // Fetch current product prices from remote store
                $product_data = self::get_remote_product($store, $target_id);
                if ($product_data) {
                    $current_regular = floatval($product_data['regular_price'] ?? 0);
                    $current_sale = floatval($product_data['sale_price'] ?? 0);

                    // Calculate new prices based on action
                    $new_prices = self::calculate_new_prices($action, $value, $current_regular, $current_sale);

                    if (isset($new_prices['regular_price'])) {
                        $update_data['regular_price'] = $new_prices['regular_price'];
                    }
                    if (isset($new_prices['sale_price'])) {
                        $update_data['sale_price'] = $new_prices['sale_price'];
                    }
                }
            } elseif (in_array($action, ['set_regular_price', 'set_sale_price'])) {
                if ($action === 'set_regular_price') {
                    $update_data['regular_price'] = floatval($value);
                }
                if ($action === 'set_sale_price') {
                    $update_data['sale_price'] = floatval($value);
                }
            }

            // Add other direct field changes
            $direct_fields = ['name', 'sku', 'description', 'short_description', 'stock_quantity', 'status', 'weight', 'length', 'width', 'height'];
            foreach ($direct_fields as $field) {
                if (isset($changes[$field])) {
                    $update_data[$field] = $changes[$field];
                }
            }

            if (count($update_data) > 1) { // Has more than just 'id'
                $batch_items[] = $update_data;
            }
        }

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

        // Chunk into 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,
            ]);

            if (is_wp_error($response)) {
                $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'])) {
                $total_success += count($body['update']);
                $total_failed += (count($chunk) - count($body['update']));
            } else {
                $total_failed += count($chunk);
            }
        }

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

    /**
     * Get a single product from remote store
     */
    private static function get_remote_product($store, $product_id)
    {
        $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)) {
            return null;
        }

        return json_decode(wp_remote_retrieve_body($response), true);
    }

    /**
     * Calculate new prices based on action
     */
    private static function calculate_new_prices($action, $value, $current_regular, $current_sale)
    {
        $result = [];
        $value = floatval($value);

        switch ($action) {
            case 'price_increase':
                $result['regular_price'] = $current_regular + $value;
                if ($current_sale) {
                    $result['sale_price'] = $current_sale + $value;
                }
                break;
            case 'price_decrease':
                $result['regular_price'] = max(0, $current_regular - $value);
                if ($current_sale) {
                    $result['sale_price'] = max(0, $current_sale - $value);
                }
                break;
            case 'percentage_increase':
                $result['regular_price'] = round($current_regular * (1 + $value / 100), 2);
                if ($current_sale) {
                    $result['sale_price'] = round($current_sale * (1 + $value / 100), 2);
                }
                break;
            case 'percentage_decrease':
                $result['regular_price'] = round($current_regular * (1 - $value / 100), 2);
                if ($current_sale) {
                    $result['sale_price'] = round($current_sale * (1 - $value / 100), 2);
                }
                break;
            case 'fixed_increase':
                $result['regular_price'] = $current_regular + $value;
                if ($current_sale) {
                    $result['sale_price'] = $current_sale + $value;
                }
                break;
            case 'fixed_decrease':
                $result['regular_price'] = max(0, $current_regular - $value);
                if ($current_sale) {
                    $result['sale_price'] = max(0, $current_sale - $value);
                }
                break;
        }

        return $result;
    }

    /**
     * Calculate price changes based on action (legacy method, kept for reference)
     * Returns array with regular_price and/or sale_price
     */
    private static function calculate_price_changes($changes)
    {
        $action = $changes['action'] ?? '';
        $value = $changes['value'] ?? '';
        $result = [];

        switch ($action) {
            case 'set_regular_price':
                $result['regular_price'] = floatval($value);
                break;
            case 'set_sale_price':
                $result['sale_price'] = floatval($value);
                break;
            case 'price_increase':
            case 'price_decrease':
            case 'fixed_increase':
            case 'fixed_decrease':
            case 'percentage_increase':
            case 'percentage_decrease':
                $result['_action'] = $action;
                $result['_value'] = $value;
                break;
        }

        return $result;
    }

    /**
     * Compare products across stores
     */
    public static function compare_products($request)
    {
        global $wpdb;

        $params = $request->get_json_params();
        $product_id = $params['product_id'] ?? null;
        $sku = $params['sku'] ?? null;
        $store_ids = $params['store_ids'] ?? [];

        if (!$product_id && !$sku) {
            return new WP_Error('missing_data', 'Product ID or SKU required', ['status' => 400]);
        }

        $results = [];

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

            if (!$store) continue;

            $url = trailingslashit($store['url']) . 'wp-json/wc/v3/products';
            $search_params = $product_id ? ['id' => $product_id] : ['sku' => $sku];

            $response = wp_remote_get(add_query_arg($search_params, $url), [
                'headers' => [
                    'Authorization' => 'Basic ' . base64_encode($store['consumer_key'] . ':' . $store['consumer_secret']),
                ],
                'timeout' => 30,
            ]);

            if (!is_wp_error($response)) {
                $products = json_decode(wp_remote_retrieve_body($response), true);
                if (!empty($products)) {
                    $results[] = [
                        'store_id'   => $store_id,
                        'store_name' => $store['name'],
                        'product'    => $products[0],
                    ];
                }
            }
        }

        return new WP_REST_Response([
            'data' => $results,
            'total' => count($results),
        ], 200);
    }

    /**
     * Deploy changes to stores directly (no queue)
     * Deploys product changes to target stores
     */
    public static function deploy_changes($request)
    {
        global $wpdb;

        $params = $request->get_json_params();

        if (empty($params['changes']) || empty($params['target_store_ids'])) {
            return new WP_Error('missing_data', 'Changes and target stores required', ['status' => 400]);
        }

        $product_id = intval($params['product_id'] ?? 0);
        $target_store_ids = array_map('intval', $params['target_store_ids']);
        $changes = $params['changes'];
        $results = [];

        // Get source product data for matching in remote stores
        $source_product = self::get_source_product_data($product_id);

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

            if (!$store) {
                $results[] = [
                    'store_id' => $store_id,
                    'status' => 'error',
                    'message' => 'Store not found',
                ];
                continue;
            }

            // 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
                $result = self::update_product_local($product_id, $changes);
                $results[] = [
                    'store_id' => $store_id,
                    'store_name' => $store['name'],
                    'status' => $result ? 'success' : 'error',
                    'message' => $result ? 'Product deployed' : 'Failed to deploy',
                ];
            } else {
                // Child Store: Find matching product by SKU first
                $target_product_id = self::find_matching_product_for_store($store, $source_product, $product_id);

                if (!$target_product_id) {
                    $results[] = [
                        'store_id' => $store_id,
                        'store_name' => $store['name'],
                        'status' => 'error',
                        'message' => 'Matching product not found in this store (SKU: ' . ($source_product['sku'] ?? 'N/A') . ')',
                    ];
                    continue;
                }

                // Child Store: Use WooCommerce REST API with matched ID
                $result = self::update_product_remote($target_product_id, $store, $changes);
                $results[] = [
                    'store_id' => $store_id,
                    'store_name' => $store['name'],
                    'status' => $result['success'] ? 'success' : 'error',
                    'message' => $result['message'],
                    'code' => $result['code'] ?? null,
                ];
            }
        }

        return new WP_REST_Response([
            'message' => 'Deploy completed',
            'results' => $results,
        ], 200);
    }

    /**
     * Get queue items
     */
    public static function get_queue($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';

        $status = $request->get_param('status');
        $page = max(1, intval($request->get_param('page') ?: 1));
        $per_page = min(100, max(1, intval($request->get_param('per_page') ?: 20)));
        $offset = ($page - 1) * $per_page;

        $where = 'WHERE 1=1';
        $prepare_args = [];

        if ($status) {
            $where .= ' AND status = %s';
            $prepare_args[] = $status;
        }

        $total = $wpdb->get_var(
            $prepare_args
                ? $wpdb->prepare("SELECT COUNT(*) FROM $table $where", ...$prepare_args)
                : "SELECT COUNT(*) FROM $table $where"
        );

        $query = "SELECT * FROM $table $where ORDER BY created_at DESC LIMIT %d OFFSET %d";
        $prepare_args[] = $per_page;
        $prepare_args[] = $offset;

        $items = $wpdb->get_results($wpdb->prepare($query, ...$prepare_args), ARRAY_A);

        return new WP_REST_Response([
            'data'  => $items,
            'total' => intval($total),
            'pages' => ceil($total / $per_page),
            'page'  => $page,
        ], 200);
    }

    /**
     * Get single queue item
     */
    public static function get_queue_item($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';
        $uuid = $request->get_param('uuid');

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

        if (!$item) {
            return new WP_Error('not_found', 'Queue item not found', ['status' => 404]);
        }

        return new WP_REST_Response($item, 200);
    }

    /**
     * Cancel queue item
     */
    public static function cancel_queue($request)
    {
        $uuid = $request->get_param('uuid');
        ShopCentral_Editor_Queue::update_status($uuid, self::STATUS_CANCELLED);
        return new WP_REST_Response(['message' => 'Queue item cancelled'], 200);
    }

    /**
     * Manually trigger queue processing
     * Uses Action Scheduler for reliable background processing
     */
    public static function process_queue($request)
    {
        $uuid = $request->get_param('uuid');

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

        // Reset chunk offset for fresh processing
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_deploy_queue';
        $wpdb->update($table, [
            'chunk_offset' => 0,
            'status' => self::STATUS_QUEUED,
            'processed_items' => 0,
            'failed_items' => 0,
            'skipped_items' => 0,
            'progress_percent' => 0,
        ], ['queue_uuid' => $uuid]);

        // Schedule processing via Action Scheduler
        ShopCentral_Editor_Queue::schedule_processing($uuid);

        return new WP_REST_Response([
            'message' => 'Processing started',
            'uuid' => $uuid,
        ], 200);
    }

    /**
     * Get pending changes
     */
    public static function get_pending_changes($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_pending_changes';

        $status = $request->get_param('status') ?: 'pending';
        $page = max(1, intval($request->get_param('page') ?: 1));
        $per_page = min(100, max(1, intval($request->get_param('per_page') ?: 50)));
        $offset = ($page - 1) * $per_page;

        $total = $wpdb->get_var(
            $wpdb->prepare("SELECT COUNT(*) FROM $table WHERE status = %s", $status)
        );

        $items = $wpdb->get_results(
            $wpdb->prepare("SELECT * FROM $table WHERE status = %s ORDER BY created_at DESC LIMIT %d OFFSET %d", $status, $per_page, $offset),
            ARRAY_A
        );

        return new WP_REST_Response([
            'data'  => $items,
            'total' => intval($total),
            'pages' => ceil($total / $per_page),
            'page'  => $page,
        ], 200);
    }

    /**
     * Save pending changes
     */
    public static function save_pending_changes($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_pending_changes';
        $params = $request->get_json_params();

        if (empty($params['changes'])) {
            return new WP_Error('no_changes', 'No changes provided', ['status' => 400]);
        }

        foreach ($params['changes'] as $change) {
            $wpdb->insert($table, [
                'pending_uuid' => wp_generate_uuid4(),
                'product_uuid' => $change['product_uuid'] ?? '',
                'store_id'     => $change['store_id'] ?? 0,
                'product_id'   => $change['product_id'] ?? 0,
                'field_name'   => $change['field_name'] ?? '',
                'old_value'    => $change['old_value'] ?? null,
                'new_value'    => $change['new_value'] ?? null,
                'change_type'  => $change['change_type'] ?? 'update',
                'status'       => 'pending',
            ]);
        }

        return new WP_REST_Response(['message' => 'Changes saved'], 201);
    }

    /**
     * Get product versions
     */
    public static function get_versions($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_product_versions';
        $store_id = intval($request->get_param('store_id'));
        $product_id = intval($request->get_param('product_id'));

        $versions = $wpdb->get_results(
            $wpdb->prepare("SELECT * FROM $table WHERE store_id = %d AND product_id = %d ORDER BY version_number DESC", $store_id, $product_id),
            ARRAY_A
        );

        return new WP_REST_Response(['data' => $versions], 200);
    }

    /**
     * Restore version
     */
    public static function restore_version($request)
    {
        global $wpdb;
        $params = $request->get_json_params();
        $version_id = $params['version_id'] ?? null;

        if (!$version_id) {
            return new WP_Error('no_version', 'Version ID required', ['status' => 400]);
        }

        $table = $wpdb->prefix . 'shopcentral_product_versions';
        $version = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $table WHERE id = %d", $version_id),
            ARRAY_A
        );

        if (!$version) {
            return new WP_Error('not_found', 'Version not found', ['status' => 404]);
        }

        // Create restore job
        $queue = ShopCentral_Editor_Queue::create_job([
            'job_type'         => 'restore',
            'source_store_id'  => $version['store_id'],
            'target_store_ids' => [$version['store_id']],
            'product_ids'      => [$version['product_id']],
            'changes_data'     => json_decode($version['product_data'], true),
        ]);

        if (is_wp_error($queue)) {
            return $queue;
        }

        ShopCentral_Editor_Queue::schedule_processing($queue['queue_uuid']);

        return new WP_REST_Response([
            'message'    => 'Restore job created',
            'queue_uuid' => $queue['queue_uuid'],
        ], 201);
    }

    /**
     * Get activity log
     */
    public static function get_activity_log($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'shopcentral_activity_log';

        $action = $request->get_param('action');
        $store_id = $request->get_param('store_id');
        $page = max(1, intval($request->get_param('page') ?: 1));
        $per_page = min(100, max(1, intval($request->get_param('per_page') ?: 50)));
        $offset = ($page - 1) * $per_page;

        $where = 'WHERE 1=1';
        $prepare_args = [];

        if ($action) {
            $where .= ' AND action = %s';
            $prepare_args[] = $action;
        }
        if ($store_id) {
            $where .= ' AND store_id = %d';
            $prepare_args[] = $store_id;
        }

        $total = $wpdb->get_var(
            $prepare_args
                ? $wpdb->prepare("SELECT COUNT(*) FROM $table $where", ...$prepare_args)
                : "SELECT COUNT(*) FROM $table $where"
        );

        $query = "SELECT * FROM $table $where ORDER BY created_at DESC LIMIT %d OFFSET %d";
        $prepare_args[] = $per_page;
        $prepare_args[] = $offset;

        $items = $wpdb->get_results($wpdb->prepare($query, ...$prepare_args), ARRAY_A);

        return new WP_REST_Response([
            'data'  => $items,
            'total' => intval($total),
            'pages' => ceil($total / $per_page),
            'page'  => $page,
        ], 200);
    }

    /**
     * Validate data before deploy
     */
    public static function validate_data($request)
    {
        $params = $request->get_json_params();
        $changes = $params['changes'] ?? [];
        $target_store_ids = $params['target_store_ids'] ?? [];

        $errors = [];
        $warnings = [];

        foreach ($changes as $change) {
            // Validate price
            if (in_array($change['field_name'], ['regular_price', 'sale_price'])) {
                if (isset($change['new_value']) && $change['new_value'] !== '') {
                    if (!is_numeric($change['new_value']) || floatval($change['new_value']) < 0) {
                        $errors[] = "Invalid price for {$change['field_name']}";
                    }
                }
            }

            // Validate stock
            if ($change['field_name'] === 'stock_quantity') {
                if (isset($change['new_value']) && intval($change['new_value']) < 0) {
                    $errors[] = "Stock quantity cannot be negative";
                }
            }

            // Validate name
            if ($change['field_name'] === 'name' && empty($change['new_value'])) {
                $errors[] = "Product name cannot be empty";
            }
        }

        return new WP_REST_Response([
            'valid'    => empty($errors),
            'errors'   => $errors,
            'warnings' => $warnings,
        ], 200);
    }
}

ShopCentral_Product_Editor::init();
