<?php
/**
 * Product Sync Handler
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/handlers
 * @author     miniOrange
 */

declare(strict_types=1);

namespace MOMCS_Sync\Includes\Common\Handlers;

use MOMCS_Sync\Includes\Common\Services\Amazon\Product_Sync_Service;
use MOMCS_Sync\Includes\Common\Services\Amazon\Listings_Service;
use MOMCS_Sync\Includes\Common\Handlers\Feed_Handler;
use MOMCS_Sync\Includes\Common\Models\Product_Mapping_Model;
use MOMCS_Sync\Includes\Common\Models\Multichannels_Model;
use MOMCS_Sync\Includes\Common\Utils\Logger;
use MOMCS_Sync\Includes\Common\Utils\Variation_Helper;
use MOMCS_Sync\Includes\Common\Constants\Plugin_Constants;
use MOMCS_Sync\Includes\Common\Handlers\Payload\Payload_Builder;
use MOMCS_Sync\Includes\Common\Exceptions\Sync_Exception;

/**
 * Product Sync Handler Class
 *
 * Handles product synchronization with Amazon
 */
class Product_Sync_Handler {
	/**
	 * Product sync service instance
	 *
	 * @var Product_Sync_Service
	 */
	private $product_sync_service;

	/**
	 * Feed handler instance
	 *
	 * @var Feed_Handler
	 */
	private $feed_handler;

	/**
	 * Product mapping model instance
	 *
	 * @var Product_Mapping_Model
	 */
	private $product_model;

	/**
	 * Simple in-memory cache for brand look-ups to avoid repeated taxonomy queries.
	 *
	 * @var array<int,string>
	 */
	private array $brand_cache = array();

	/**
	 * Payload Builder instance
	 *
	 * @var Payload_Builder
	 */
	private $payload_builder;

	/**
	 * Logger instance
	 *
	 * @var Logger
	 */
	private $logger;

	/**
	 * Listings service for Listings API operations.
	 *
	 * @var Listings_Service
	 */
	private $listings_service;

	/**
	 * Multichannels model for channel lookups.
	 *
	 * @var Multichannels_Model
	 */
	private $multichannels_model;

	/**
	 * Constructor
	 *
	 * Resolves dependencies via the Service Container.
	 */
	public function __construct() {
		$this->product_sync_service = new Product_Sync_Service();
		$this->feed_handler         = new Feed_Handler();
		$this->product_model        = new Product_Mapping_Model();
		$this->multichannels_model  = new Multichannels_Model();
		$this->payload_builder      = new Payload_Builder();
		$this->listings_service     = new Listings_Service();
		$this->logger               = new Logger( 'product-sync-handler' );
	}

	/**
	 * Sync products with Amazon
	 *
	 * Supports variable products by expanding to include all variations.
	 * The expanded list maintains parent-first ordering for proper Amazon sync.
	 *
	 * @param array       $product_ids     Array of product IDs to sync.
	 * @param array       $marketplace_ids Array of marketplace IDs.
	 * @param string|null $channel_id Channel ID.
	 *
	 * @return array Result of the sync operation.
	 */
	public function sync_products( $product_ids, $marketplace_ids, $channel_id = null ) {
		$this->logger->info( 'Starting product sync for ' . count( $product_ids ) . ' products' );

		// Expand product IDs to include variations (parent-first ordering).
		$expanded_product_ids = Variation_Helper::expand_product_ids_with_variations( $product_ids );

		$this->logger->info(
			'Product IDs expanded',
			array(
				'original_count' => count( $product_ids ),
				'expanded_count' => count( $expanded_product_ids ),
			)
		);

		// Decide which API to use based on the number of products.
		if ( count( $product_ids ) >= Plugin_Constants::FEEDS_API_THRESHOLD ) {
			$this->logger->info( 'Using Feeds API for bulk sync' );
			// Build product template mappings (includes product_type and full template_config).
			$product_template_mappings = $this->build_product_template_mappings( $expanded_product_ids, (string) $channel_id );
			return $this->feed_handler->sync_products_with_feeds_api( $expanded_product_ids, (array) $marketplace_ids, (string) $channel_id, $product_template_mappings );
		} else {
			$this->logger->info( 'Using Listings API for individual sync' );
			return $this->sync_products_with_listings_api( $expanded_product_ids, $marketplace_ids, $channel_id );
		}
	}

	/**
	 * Build product template mappings for a list of product IDs.
	 *
	 * For variations, uses the parent's template configuration.
	 * Returns both product_type and full template_config for each product.
	 *
	 * @param array  $product_ids Array of product IDs (may include variations).
	 * @param string $channel_id  Channel ID.
	 * @return array Map of product_id => ['product_type' => string, 'template_config' => array].
	 */
	private function build_product_template_mappings( array $product_ids, string $channel_id ): array {
		$product_template_mappings = array();
		$template_cache            = array(); // Cache template configs by parent ID.

		foreach ( $product_ids as $product_id ) {
			// Determine which product to use for template resolution.
			$template_product_id = $product_id;

			// For variations, use parent's template.
			if ( Variation_Helper::is_variation( $product_id ) ) {
				$parent_id = Variation_Helper::get_parent_id( $product_id );
				if ( $parent_id ) {
					$template_product_id = $parent_id;
				}
			}

			// Check cache first.
			if ( isset( $template_cache[ $template_product_id ] ) ) {
				$template_config = $template_cache[ $template_product_id ];
			} else {
				$template_config                       = $this->get_template_mapping_config( $channel_id, (int) $template_product_id );
				$template_cache[ $template_product_id ] = $template_config;
			}

			if ( $template_config && ! empty( $template_config['selected_category'] ) ) {
				$product_template_mappings[ $product_id ] = array(
					'product_type'    => $template_config['selected_category'],
					'template_config' => $template_config,
				);
			} else {
				$this->logger->error( 'No valid template config found for product ' . $product_id . ' - skipping sync' );
			}
		}

		return $product_template_mappings;
	}

	/**
	 * Sync products using Listings API (for fewer than 10 products)
	 *
	 * Handles variable products by syncing parent first, then all variations.
	 * This ensures Amazon receives the parent listing before child variations.
	 *
	 * @param array       $product_ids    Array of product IDs to sync (already expanded).
	 * @param array       $marketplace_ids Array of marketplace IDs.
	 * @param string|null $channel_id Channel ID.
	 *
	 * @return array Result of the sync operation.
	 */
	private function sync_products_with_listings_api( array $product_ids, array $marketplace_ids, ?string $channel_id = null ) {
		$results = array(
			'success' => array(),
			'error'   => array(),
		);

		// Cache for template configs to avoid repeated lookups.
		$template_cache = array();
		// Track failed parents to skip their variations.
		$failed_parents = array();

		foreach ( $product_ids as $product_id ) {
			try {
				$marketplace_id = $marketplace_ids[0] ?? '';

				// Determine template product ID (use parent for variations).
				$template_product_id = $product_id;
				$is_variation        = Variation_Helper::is_variation( $product_id );
				$parent_id           = 0;

				if ( $is_variation ) {
					$parent_id = Variation_Helper::get_parent_id( $product_id );
					if ( $parent_id ) {
						$template_product_id = $parent_id;

						// Skip variation if parent failed.
						if ( isset( $failed_parents[ $parent_id ] ) ) {
							$this->logger->warning( 'Skipping variation ' . $product_id . ' because parent ' . $parent_id . ' failed' );
							$results['error'][ $product_id ] = 'Parent product sync failed';
							continue;
						}
					}
				}

				// Get template config (cached).
				if ( isset( $template_cache[ $template_product_id ] ) ) {
					$template_config = $template_cache[ $template_product_id ];
				} else {
					$template_config                        = $this->get_template_mapping_config( $channel_id, (int) $template_product_id );
					$template_cache[ $template_product_id ] = $template_config;
				}

				// Get seller ID from channel.
				$channel_details = $this->get_channel_details( $channel_id );
				$seller_id       = is_wp_error( $channel_details ) ? 'ARFOUL5QD8W1L' : $channel_details['seller_id'];

				$result = $this->product_sync_service->sync_product( (int) $product_id, $channel_id, $template_config, $marketplace_id, $seller_id );
				$this->logger->info( 'Successfully synced product ' . $product_id );
				$results['success'][ $product_id ] = $result;
			} catch ( Sync_Exception $e ) {
				$this->logger->error( 'Failed to sync product ' . $product_id . ': ' . $e->getMessage() );
				$results['error'][ $product_id ] = $e->getMessage();

				// Mark parent as failed to skip variations.
				if ( Variation_Helper::is_variable_product( $product_id ) ) {
					$failed_parents[ $product_id ] = true;
				}
			} catch ( \Exception $e ) {
				// Catch any unexpected exceptions to avoid breaking the bulk loop.
				$this->logger->error( 'Unexpected error syncing product ' . $product_id . ': ' . $e->getMessage() );
				$results['error'][ $product_id ] = 'Unexpected error: ' . $e->getMessage();

				// Mark parent as failed to skip variations.
				if ( Variation_Helper::is_variable_product( $product_id ) ) {
					$failed_parents[ $product_id ] = true;
				}
			}
		}

		return $results;
	}

	/**
	 * Unlist products using Feeds API by delegating to Feed_Handler.
	 *
	 * @param array       $product_ids     WooCommerce product IDs to unlist.
	 * @param array       $marketplace_ids Amazon marketplace IDs.
	 * @param int         $action_id       Action Scheduler log id.
	 * @param string|null $channel_id      Channel UUID/ID.
	 * @return array                       Result array with success / error keys.
	 */
	public function unlist_products_with_feeds_api( array $product_ids, array $marketplace_ids, int $action_id = 0, ?string $channel_id = null ) {
		return $this->feed_handler->unlist_products_with_feeds_api( $product_ids, $marketplace_ids, $action_id, $channel_id );
	}

	/**
	 * Poll Amazon feed status by delegating to Feed_Handler.
	 *
	 * @param string      $feed_id    Feed ID returned by create_feed().
	 * @param int         $action_id  Original Action Scheduler job ID for consolidated logging.
	 * @param string|null $channel_id Channel UUID.
	 * @return void
	 */
	public function check_feed_status( string $feed_id, int $action_id = 0, ?string $channel_id = null ) {
		$this->feed_handler->check_feed_status( $feed_id, $action_id, $channel_id );
	}

	/**
	 * Build feed payload
	 *
	 * @param array       $product_ids    Array of product IDs to sync.
	 * @param array       $marketplace_ids Array of marketplace IDs.
	 * @param string|null $channel_id Channel ID (optional).
	 * @param array       $product_type_mappings Product type mappings per product ID.
	 *
	 * @return array|WP_Error Feed payload with messageId mapping or error.
	 *                        Format: ['payload' => array, 'message_id_to_sku_mapping' => array]
	 */
	private function build_feed_payload( array $product_ids, array $marketplace_ids, ?string $channel_id = null, array $product_type_mappings = array() ) {
		// Delegate payload building to Feed_Handler.
		return $this->feed_handler->build_feed_payload( $product_ids, $marketplace_ids, $channel_id, $product_type_mappings );
	}

	/**
	 * Unlist multiple products for a given channel using Listings API (per SKU delete).
	 *
	 * @param array  $product_ids WooCommerce product IDs.
	 * @param string $channel_id  Channel UUID/ID.
	 * @return array{success: array<int,string>, error: array<int,string>} Result mapping.
	 */
	public function unlist_products_by_channel( array $product_ids, string $channel_id ): array {
		$success = array();
		$error   = array();

		$channel_details = $this->get_channel_details( $channel_id );
		if ( is_wp_error( $channel_details ) ) {
			return array(
				'success' => array(),
				'error'   => array_fill_keys( $product_ids, $channel_details->get_error_message() ),
			);
		}

		$seller_id      = $channel_details['seller_id'];
		$marketplace_id = $channel_details['marketplace_id'];

		foreach ( $product_ids as $product_id ) {
			$wc_product = wc_get_product( $product_id );
			if ( ! $wc_product ) {
				$error[ $product_id ] = __( 'Invalid product', 'multi-channel-for-woocommerce' );
				continue;
			}

			$sku = $wc_product->get_sku();
			if ( empty( $sku ) ) {
				$error[ $product_id ] = __( 'SKU missing', 'multi-channel-for-woocommerce' );
				continue;
			}

			$response = $this->listings_service->delete_listing( $channel_id, $seller_id, $sku, $marketplace_id );
			if ( is_wp_error( $response ) ) {
				$error[ $product_id ] = $response->get_error_message();
				continue;
			}

			if ( empty( $response['success'] ) ) {
				$issue_messages       = wp_list_pluck( $response['issues'] ?? array(), 'message' );
				$error[ $product_id ] = implode( ', ', $issue_messages );
				continue;
			}

			$success[ $product_id ] = (string) ( $response['submission_id'] ?? '' );
		}

		return array(
			'success' => $success,
			'error'   => $error,
		);
	}

	/**
	 * Fetch seller_id and marketplace_id for a given channel.
	 *
	 * @param string $channel_id Channel UUID.
	 * @return array|\WP_Error
	 */
	/**
	 * Sync multiple products for a given channel.
	 *
	 * Wrapper that resolves marketplace ID and delegates to sync_products().
	 *
	 * @param array  $product_ids  WooCommerce product IDs.
	 * @param string $channel_id   Channel UUID/ID.
	 * @return array               Success / failed results.
	 */
	public function sync_products_by_channel( array $product_ids, string $channel_id ): array {
		$channel_details = $this->get_channel_details( $channel_id );
		if ( is_wp_error( $channel_details ) ) {
			return array(
				'success' => array(),
				'failed'  => array_fill_keys( $product_ids, $channel_details->get_error_message() ),
			);
		}
		$marketplace_ids = array( $channel_details['marketplace_id'] );
		return $this->sync_products( $product_ids, $marketplace_ids, $channel_id );
	}

	/**
	 * Get template mapping config for a channel and product.
	 *
	 * @param string $channel_id Channel ID.
	 * @param int    $product_id WooCommerce product ID.
	 *
	 * @return array|null Mapping configuration or null.
	 */
	public function get_template_mapping_config( string $channel_id, int $product_id ): ?array {
		$this->logger->debug( 'Starting template resolution', array( 
			'product_id' => $product_id, 
			'channel_id' => $channel_id 
		) );

		// Fetch all mappings for this channel via the model and filter in PHP for template configs.
		$mappings = $this->product_model->get_mappings_by_channel_id( $channel_id );
		if ( empty( $mappings ) ) {
			$this->logger->error( 'No template configurations found for channel', array( 'channel_id' => $channel_id ) );
			return $this->get_default_mapping_config( $channel_id );
		}

		$this->logger->debug( 'Found mappings for channel', array( 
			'channel_id' => $channel_id,
			'total_mappings' => count( $mappings ),
			'mapping_types' => array_column( $mappings, 'config_name' )
		) );

		// Use hierarchical template resolution with child-first priority.
		$resolved = $this->resolve_hierarchical_template( $mappings, $product_id );
		
		if ( $resolved ) {
			$this->logger->debug( 'Template resolved successfully', array(
				'product_id' => $product_id,
				'selected_category' => $resolved['selected_category'] ?? 'MISSING',
				'has_field_mappings' => !empty( $resolved['field_mappings'] )
			) );
			
			// Validate resolved template has required fields
			if ( empty( $resolved['selected_category'] ) ) {
				$this->logger->error( 'Resolved template missing selected_category', array(
					'product_id' => $product_id,
					'template_keys' => array_keys( $resolved )
				) );
				return $this->get_default_mapping_config( $channel_id );
			}
			
			// Allow premium to override/augment resolution (product-level override, tie-breaker, etc.).
			$resolved = apply_filters( 'momcs_resolve_template_config', $resolved, $product_id, $channel_id, $mappings );
			return $resolved;
		}

		$this->logger->warning( 'No template resolved, falling back to default', array(
			'product_id' => $product_id,
			'channel_id' => $channel_id
		) );

		// Fallback to default mapping.
		$default_config = $this->get_default_mapping_config( $channel_id );
		if ( $default_config ) {
			$this->logger->debug( 'Using default mapping config', array(
				'product_id' => $product_id,
				'has_selected_category' => !empty( $default_config['selected_category'] )
			) );
		} else {
			$this->logger->error( 'No default mapping config available', array(
				'product_id' => $product_id,
				'channel_id' => $channel_id
			) );
		}

		return $default_config;
	}

	/**
	 * Resolve template configuration using hierarchical matching with child-first priority.
	 *
	 * @param array $mappings    All template mappings for the channel.
	 * @param int   $product_id  WooCommerce product ID.
	 *
	 * @return array|null Resolved template configuration or null.
	 */
	private function resolve_hierarchical_template( array $mappings, int $product_id ): ?array {
		$product = wc_get_product( $product_id );
		if ( ! $product ) {
			$this->logger->error( 'Product not found', array( 'product_id' => $product_id ) );
			return null;
		}

		// Get all product categories and their full hierarchy.
		$product_category_hierarchy = $this->get_product_category_hierarchy( $product_id );
		$this->logger->debug( 'Product category hierarchy for template matching', array(
			'product_id' => $product_id,
			'hierarchy' => $product_category_hierarchy,
			'category_ids' => array_keys( $product_category_hierarchy ),
			'priority_levels' => array_values( $product_category_hierarchy )
		) );
		
		if ( empty( $product_category_hierarchy ) ) {
			$this->logger->debug( 'No categories found for product', array( 'product_id' => $product_id ) );
			return null;
		}

		// Find all matching templates with their priority level.
		$template_matches = array();
		$this->logger->debug( 'Checking templates against product categories', array(
			'product_id' => $product_id,
			'total_mappings' => count( $mappings ),
			'category_hierarchy' => $product_category_hierarchy,
			'categories_to_match' => array_keys( $product_category_hierarchy )
		) );
		
		foreach ( $mappings as $mapping_index => $mapping ) {
			if ( empty( $mapping['config_name'] ) || 'template_config' !== $mapping['config_name'] ) {
				continue;
			}
			if ( empty( $mapping['config'] ) ) {
				$this->logger->debug( 'Skipping mapping with empty config', array( 'index' => $mapping_index ) );
				continue;
			}
			$config = json_decode( $mapping['config'], true );
			if ( JSON_ERROR_NONE !== json_last_error() || ! is_array( $config ) ) {
				$this->logger->debug( 'Skipping mapping with invalid JSON config', array( 
					'index' => $mapping_index,
					'json_error' => json_last_error_msg()
				) );
				continue;
			}
			if ( ! isset( $config['category_mappings']['wc_category'] ) ) {
				$this->logger->debug( 'Skipping mapping missing wc_category', array( 
					'index' => $mapping_index,
					'config_keys' => array_keys( $config )
				) );
				continue;
			}

			$template_category = (int) $config['category_mappings']['wc_category'];
			$priority          = $this->get_template_priority( $template_category, $product_category_hierarchy );
			
			$this->logger->debug( 'Evaluating template', array(
				'product_id' => $product_id,
				'template_category' => $template_category,
				'priority' => $priority,
				'selected_category' => $config['selected_category'] ?? 'MISSING',
				'amazon_category' => $config['category_mappings']['amazon_category'] ?? 'MISSING'
			) );
			
			if ( $priority > 0 ) {
				$template_matches[] = array(
					'config'   => $config,
					'priority' => $priority,
					'category' => $template_category,
					'updated_at' => $mapping['updated_at'] ?? '',
				);
				
				$this->logger->debug( 'Template matched!', array(
					'product_id' => $product_id,
					'template_category' => $template_category,
					'priority' => $priority
				) );
			}
		}

		// Sort by priority (lower number = higher priority) and updated_at for tie-breaking.
		if ( empty( $template_matches ) ) {
			$this->logger->warning( 'No template matches found for product', array(
				'product_id' => $product_id,
				'category_hierarchy' => $product_category_hierarchy
			) );
			return null;
		}

		$this->logger->debug( 'Template matches before sorting', array(
			'product_id' => $product_id,
			'matches' => array_map( function($match) {
				return array(
					'category' => $match['category'],
					'priority' => $match['priority'],
					'selected_category' => $match['config']['selected_category'] ?? 'MISSING',
					'updated_at' => $match['updated_at']
				);
			}, $template_matches )
		) );

		usort( $template_matches, function( $a, $b ) {
			// First sort by priority (lower number = higher priority).
			if ( $a['priority'] !== $b['priority'] ) {
				return $a['priority'] <=> $b['priority'];
			}
			// Tie-breaker: more recent update wins.
			return strcmp( $b['updated_at'], $a['updated_at'] );
		});

		$best_match = $template_matches[0];
		$this->logger->info( 
			'Hierarchical template resolved', 
			array(
				'product_id'         => $product_id,
				'selected_template'  => $best_match['category'],
				'priority'          => $best_match['priority'],
				'total_candidates'  => count( $template_matches ),
				'selected_category' => $best_match['config']['selected_category'] ?? 'MISSING',
				'template_config_keys' => array_keys( $best_match['config'] )
			)
		);

		return $best_match['config'];
	}

	/**
	 * Get the full category hierarchy for a product including all ancestor categories.
	 *
	 * @param int $product_id WooCommerce product ID.
	 *
	 * @return array Array of category data with hierarchy levels.
	 */
	private function get_product_category_hierarchy( int $product_id ): array {
		$terms = get_the_terms( $product_id, 'product_cat' );
		if ( ! $terms || is_wp_error( $terms ) ) {
			return array();
		}

		$this->logger->debug( 'Raw product categories from get_the_terms', array(
			'product_id' => $product_id,
			'categories' => array_map( function( $term ) {
				return array( 'id' => $term->term_id, 'name' => $term->name, 'parent' => $term->parent );
			}, $terms )
		) );

		$hierarchy = array();
		foreach ( $terms as $term ) {
			$ancestors = $this->get_category_ancestors( $term->term_id );
			$this->logger->debug( 'Category ancestors', array(
				'category_id' => $term->term_id,
				'category_name' => $term->name,
				'ancestors' => $ancestors
			) );
			
			// Fix: Correct variable order - ancestors array has [category_id => level] structure
			foreach ( $ancestors as $ancestor_id => $level ) {
				$hierarchy[ $ancestor_id ] = $level + 1; // Level 1 = most specific (product's direct category).
			}
		}

		$this->logger->debug( 'Final product category hierarchy', array(
			'product_id' => $product_id,
			'hierarchy' => $hierarchy
		) );

		return $hierarchy;
	}

	/**
	 * Get all ancestor categories for a given category ID, including itself.
	 *
	 * @param int $category_id Category ID to get ancestors for.
	 *
	 * @return array Array with category IDs as keys and hierarchy levels as values (1 = most specific).
	 */
	private function get_category_ancestors( int $category_id ): array {
		$ancestors  = array();
		$current_id = $category_id;
		$level      = 0;
		$max_depth  = 10; // Prevent infinite loops.

		while ( $current_id && $level < $max_depth ) {
			$ancestors[ $current_id ] = $level;
			$category = get_term( $current_id, 'product_cat' );
			if ( ! $category || is_wp_error( $category ) || ! $category->parent ) {
				break;
			}
			$current_id = $category->parent;
			$level++;
		}

		return $ancestors;
	}

	/**
	 * Get the priority level for a template category against product category hierarchy.
	 *
	 * @param int   $template_category Template category ID.
	 * @param array $hierarchy         Product's category hierarchy with levels.
	 *
	 * @return int Priority level (1 = highest/most specific, higher number = lower priority, 0 = no match).
	 */
	private function get_template_priority( int $template_category, array $hierarchy ): int {
		if ( isset( $hierarchy[ $template_category ] ) ) {
			return $hierarchy[ $template_category ];
		}
		return 0; // No match.
	}

	/**
	 * Get default mapping config for a channel.
	 *
	 * @param string $channel_id Channel ID.
	 *
	 * @return array|null Mapping configuration or null.
	 */
	public function get_default_mapping_config( string $channel_id ): ?array {
		$mapping = $this->product_model->get_mapping_by_channel_and_config( $channel_id, 'default_mapping' );
		if ( ! $mapping || empty( $mapping['config'] ) ) {
			$this->logger->debug( 'No default mapping found for channel', array( 'channel_id' => $channel_id ) );
			return null;
		}

		$config = json_decode( $mapping['config'], true );
		if ( JSON_ERROR_NONE !== json_last_error() ) {
			$this->logger->error( 'Invalid JSON in default mapping config', array( 
				'channel_id' => $channel_id,
				'json_error' => json_last_error_msg()
			) );
			return null;
		}

		// Validate that default mapping has required fields
		if ( empty( $config['selected_category'] ) ) {
			$this->logger->error( 'Default mapping missing selected_category - sync cannot proceed', array(
				'channel_id' => $channel_id,
				'config_keys' => array_keys( $config )
			) );
			return null;
		}

		$this->logger->debug( 'Default mapping config loaded', array(
			'channel_id' => $channel_id,
			'selected_category' => $config['selected_category']
		) );

		return $config;
	}

	// ---------------------------------------------------------------------


	/**
	 * Bulk fetch WooCommerce products by IDs.
	 * Wrapper around WC_Product_Query to reduce DB queries.
	 *
	 * @param int[] $ids WooCommerce product IDs.
	 *
	 * @return array<int, \WC_Product>
	 */
	private function get_products_by_ids( array $ids ): array {
		if ( empty( $ids ) ) {
			return array();
		}
		$query    = new \WC_Product_Query(
			array(
				'limit'   => count( $ids ),
				'return'  => 'objects',
				'orderby' => 'post__in',
				'include' => $ids,
			)
		);
		$products = $query->get_products();
		$map      = array();
		foreach ( $products as $prod ) {
			$map[ $prod->get_id() ] = $prod;
		}
		return $map;
	}

	/**
	 * Get channel details by channel ID.
	 *
	 * @param string $channel_id Channel ID.
	 * @return array|\WP_Error
	 */
	public function get_channel_details( string $channel_id ) {
		$channel = $this->multichannels_model->get_channel_by_uuid( $channel_id );
		if ( ! $channel ) {
			return new \WP_Error( 'invalid_channel', 'Channel not found' );
		}
		$marketplace_id = ! empty( $channel['region'] ) ? $channel['region'] : '';
		if ( empty( $marketplace_id ) ) {
			return new \WP_Error( 'invalid_marketplace_id', 'Marketplace ID not found' );
		}
		$seller_id = $channel['seller_id'] ?? $channel_id;
		return array(
			'seller_id'      => $seller_id,
			'marketplace_id' => $marketplace_id,
		);
	}
}
