<?php
/**
 * Product Sync Controller
 *
 * This class handles synchronization of products between WooCommerce and Amazon.
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/controllers/sync
 * @author     miniOrange
 * @license    Expat
 * @link       https://miniorange.com
 */

declare(strict_types=1);

namespace MOMCS_Sync\Includes\Common\Controllers\Sync;

use MOMCS_Sync\Includes\Common\Constants\Plugin_Constants;
use MOMCS_Sync\Includes\Common\Handlers\Product_Sync_Handler;
use MOMCS_Sync\Includes\Common\Services\Channel_Service;
use MOMCS_Sync\Includes\Common\Utils\Logger;
use MOMCS_Sync\Includes\Common\Utils\AS_Log_Helper;
use MOMCS_Sync\Includes\Common\Utils\Current_Action;
use MOMCS_Sync\Includes\Common\Utils\Utils;
use MOMCS\LicenseLibrary\Mo_License_Service;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class Product_Sync_Controller
 *
 * Handles synchronization of products between WooCommerce and Amazon
 */
class Product_Sync_Controller {

	/**
	 * Product Sync Service instance
	 *
	 * @var Product_Sync_Service
	 */
	private $product_sync_service;

	/**
	 * Product Mapping Model instance
	 *
	 * @var Product_Mapping_Model
	 */
	private $product_mapping_model;

	/**
	 * Product Sync Handler instance
	 *
	 * @var Product_Sync_Handler
	 */
	private $product_sync_handler;

	/**
	 * Channel service instance
	 *
	 * @var Channel_Service
	 */
	private $channel_service;

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

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->product_sync_handler = new Product_Sync_Handler();
		$this->channel_service      = new Channel_Service();
	}

	/**
	 * Sync multiple products via AJAX.
	 */
	public function sync_products_bulk_ajax() {
		// Check nonce for security.

		check_ajax_referer( Plugin_Constants::NONCE_MAIN, 'nonce' );

		// Check user permissions.
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Permission denied' ) );
			exit;
		}

		// Verify license for premium feature only (skip license library on free).
		if ( Utils::is_premium_plan() && true === Mo_License_Service::is_license_expired()['STATUS'] ) {
			return;
		}

		$product_ids = isset( $_POST['product_ids'] ) ? array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['product_ids'] ) ) : array();
		$is_premium  = \MOMCS_Sync\Includes\Common\Utils\Utils::is_premium_plan();
		$channel_ids = array();

		// Handle both single and multiple channels based on plan.
		if ( $is_premium && isset( $_POST['channel_ids'] ) ) {
			$channel_ids = array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['channel_ids'] ) );
		} elseif ( isset( $_POST['channel_id'] ) ) {
			$channel_ids = array( sanitize_text_field( wp_unslash( $_POST['channel_id'] ) ) );
		}

		if ( empty( $product_ids ) ) {
			wp_send_json_error( array( 'message' => 'No product IDs provided' ) );
			exit;
		}

		if ( empty( $channel_ids ) ) {
			wp_send_json_error( array( 'message' => 'No channel ID provided' ) );
			exit;
		}

		// Enforce single channel limit for free plan.
		if ( ! $is_premium && count( $channel_ids ) > 1 ) {
			wp_send_json_error( array( 'message' => 'Multi-channel sync is a premium feature' ) );
			exit;
		}

		try {
			// Validate channels.
			foreach ( $channel_ids as $channel_id ) {
				$channel_details = $this->product_sync_handler->get_channel_details( $channel_id );
				if ( is_wp_error( $channel_details ) ) {
					wp_send_json_error( array( 'message' => 'Invalid channel ID: ' . $channel_id ) );
					exit;
				}
			}

			// Store first channel ID in transient (backward compatibility).
			set_transient( Plugin_Constants::TRANSIENT_CURRENT_CHANNEL, $channel_ids[0], 5 * MINUTE_IN_SECONDS );

			// Schedule the bulk sync action (processed in background).
			as_schedule_single_action(
				time() + 10,
				Plugin_Constants::CRON_SYNC_BULK,
				array(
					'product_ids' => $product_ids,
					'channel_ids' => $channel_ids,
				)
			);

			wp_send_json_success(
				array(
					'message'       => 'Bulk sync scheduled successfully. It will process in the background.',
					'product_count' => count( $product_ids ),
					'channel_count' => count( $channel_ids ),
				)
			);
		} catch ( \Exception $e ) {
			wp_send_json_error(
				array(
					'message' => 'Error: ' . $e->getMessage(),
					'trace'   => $e->getTraceAsString(),
				)
			);
			exit;
		}
	}

	/**
	 * Background Action Scheduler callback for bulk product sync.
	 *
	 * For premium with multiple channels: Schedules individual AS actions per marketplace.
	 * For free or single channel: Processes directly.
	 *
	 * @param array        $product_ids Product IDs to sync.
	 * @param string|array $channel_ids Channel ID(s) - string for backward compatibility, array for multi-channel.
	 * @return array|void
	 */
	public function process_bulk_sync_action( $product_ids, $channel_ids ) {
		// Handle both old (string) and new (array) formats.
		if ( is_string( $channel_ids ) ) {
			$channel_ids = array( $channel_ids );
		}

		if ( empty( $product_ids ) || empty( $channel_ids ) ) {
			return;
		}

		// Premium multi-channel: schedule individual marketplace syncs.
		if ( \MOMCS_Sync\Includes\Common\Utils\Utils::is_premium_plan() && count( $channel_ids ) > 1 ) {
			$premium_handler = new \MOMCS_Sync\Includes\Plans\Premium\Handlers\Multi_Channel_Sync_Handler();
			return $premium_handler->sync_products_to_multiple_channels( $product_ids, $channel_ids );
		}

		// Free or single channel: process directly.
		return $this->product_sync_handler->sync_products_by_channel( $product_ids, $channel_ids[0] );
	}


	/**
	 * Get channels via AJAX.
	 *
	 * @return void
	 */
	public function get_channels() {
		// Check nonce.
		if ( ! current_user_can( 'manage_options' ) || ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), Plugin_Constants::NONCE_MAIN ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security check failed.', 'multi-channel-for-woocommerce' ) ) );
		}

		try {
			// Delegate retrieval and formatting to service.
			$formatted_channels = $this->channel_service->get_formatted_amazon_channels();
			if ( empty( $formatted_channels ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'No Amazon channels found.', 'multi-channel-for-woocommerce' ) ) );
				return;
			}

			wp_send_json_success(
				array( 'channels' => $formatted_channels )
			);
		} catch ( \Exception $e ) {
			wp_send_json_error( array( 'message' => $e->getMessage() ) );
		}
	}

	/**
	 * AJAX handler to unlist multiple products from Amazon.
	 *
	 * Expected POST params:
	 *  - nonce         : Security nonce.
	 *  - product_ids[] : Array of WooCommerce product IDs to unlist.
	 *  - channel_id or channel_ids[] : Channel ID(s).
	 *
	 * @return void Outputs JSON response and exits.
	 */
	public function unlist_products_bulk_ajax() {
		check_ajax_referer( Plugin_Constants::NONCE_MAIN, 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'multi-channel-for-woocommerce' ) ), 403 );
		}

		// Verify license for premium feature only (skip license library on free).
		if ( Utils::is_premium_plan() && Mo_License_Service::is_license_expired()['STATUS'] ) {
			return;
		}

		$product_ids = isset( $_POST['product_ids'] ) ? array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['product_ids'] ) ) : array();
		$product_ids = array_map( 'intval', $product_ids );
		$is_premium  = \MOMCS_Sync\Includes\Common\Utils\Utils::is_premium_plan();
		$channel_ids = array();

		// Handle both single and multiple channels based on plan.
		if ( $is_premium && isset( $_POST['channel_ids'] ) ) {
			$channel_ids = array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['channel_ids'] ) );
		} elseif ( isset( $_POST['channel_id'] ) ) {
			$channel_ids = array( sanitize_text_field( wp_unslash( $_POST['channel_id'] ) ) );
		}

		if ( empty( $product_ids ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'No products selected.', 'multi-channel-for-woocommerce' ) ) );
		}

		if ( empty( $channel_ids ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'No channel ID provided.', 'multi-channel-for-woocommerce' ) ) );
		}

		// Enforce single channel limit for free plan.
		if ( ! $is_premium && count( $channel_ids ) > 1 ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Multi-channel unlist is a premium feature', 'multi-channel-for-woocommerce' ) ) );
		}

		as_schedule_single_action(
			time() + 10,
			Plugin_Constants::CRON_UNLIST_BULK,
			array(
				'product_ids' => $product_ids,
				'channel_ids' => $channel_ids,
			)
		);

		wp_send_json_success(
			array(
				'message'       => esc_html__( 'Products unlisting queued successfully.', 'multi-channel-for-woocommerce' ),
				'product_count' => count( $product_ids ),
				'channel_count' => count( $channel_ids ),
			)
		);
	}

	/**
	 * Action Scheduler callback for bulk unlisting.
	 *
	 * For premium with multiple channels: Schedules individual AS actions per marketplace.
	 * For free or single channel: Processes directly.
	 *
	 * @param array        $product_ids Product IDs.
	 * @param string|array $channel_ids Channel ID(s) - string for backward compatibility, array for multi-channel.
	 * @return void
	 */
	public function process_bulk_unlist_action( $product_ids, $channel_ids ) {
		// Handle both old (string) and new (array) formats.
		if ( is_string( $channel_ids ) ) {
			$channel_ids = array( $channel_ids );
		}

		if ( empty( $product_ids ) || empty( $channel_ids ) ) {
			return;
		}

		$action_id = Current_Action::id();
		AS_Log_Helper::log(
			$action_id,
			'info',
			0,
			array(
				'stage'         => 'unlist_bulk_start',
				'product_count' => count( $product_ids ),
				'channel_count' => count( $channel_ids ),
			)
		);

		// Premium multi-channel: schedule individual marketplace unlists.
		if ( \MOMCS_Sync\Includes\Common\Utils\Utils::is_premium_plan() && count( $channel_ids ) > 1 ) {
			$premium_handler = new \MOMCS_Sync\Includes\Plans\Premium\Handlers\Multi_Channel_Sync_Handler();
			$premium_handler->unlist_products_from_multiple_channels( $product_ids, $channel_ids );
		} else {
			// Free or single channel: process directly.
			$channel_id      = $channel_ids[0];
			$channel_details = $this->product_sync_handler->get_channel_details( $channel_id );
			$marketplace_ids = array( $channel_details['marketplace_id'] );

			if ( count( $product_ids ) >= Plugin_Constants::FEEDS_API_THRESHOLD ) {
				$this->product_sync_handler->unlist_products_with_feeds_api( $product_ids, $marketplace_ids, (int) $action_id, $channel_id );
			} else {
				$this->product_sync_handler->unlist_products_by_channel( $product_ids, $channel_id );
			}
		}

		AS_Log_Helper::log( $action_id, 'info', 0, array( 'stage' => 'unlist_bulk_end' ) );
	}
}
