<?php
/**
 * This file is for performing the supplier management functionality.
 *
 * @package    ProductSync
 * @subpackage SupplierHandler
 * @author     miniOrange <info@miniorange.com>
 * @link       https://miniorange.com
 */

namespace MOWCPS\Common\Handlers\SupplierHandler;

use MOWCPS\Common\Models\Sync_Details_DAO;
use MOWCPS\Common\Services\Cron\Cron_Manager;
use MOWCPS\Common\Handlers\SyncHandler\Abstract_Sync_Handler;
use MOWCPS\Common\Handlers\SyncAnalytics\Sync_Analytics;
use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Utils\Response_Builder;
use MOWCPS\Common\Constants\Plugin_Filters;
use MOWCPS\Common\Services\Logging\Supplier_Logger;
use MOWCPS\Common\Services\Auditing\Supplier_Audit_Logger;
use MOWCPS\Common\Models\Supplier_Model;

/**
 * Supplier Handler.
 *
 * @package    ProductSync
 * @subpackage SupplierHandler
 * @author     miniOrange <info@miniorange.com>
 * @link       https://miniorange.com
 */

class Supplier_Handler extends Abstract_Sync_Handler {

	/**
	 * Supplier ID.
	 *
	 * @var int
	 */
	public $supplier_id;

	/**
	 * Schedule ID.
	 *
	 * @var int
	 */
	public $schedule_id;

	/**
	 * Constructor.
	 *
	 * @param int $supplier_id  Supplier ID.
	 * @param int $schedule_id  Schedule ID. Default null.
	 */
	public function __construct( $supplier_id, $schedule_id = null ) {
		$this->supplier_id = $supplier_id;
		$this->schedule_id = $schedule_id;
		Sync_Details_DAO::get_instance()->set_schedule_id( $this->schedule_id );
	}

	/**
	 * Start supplier sync manually.
	 *
	 * Initiates supplier analytics, sets priority queue, and registers the backup sync cron job before starting the sync.
	 *
	 * @throws \RuntimeException If a sync is already running for the supplier.
	 *
	 * @return string Sync status message.
	 */
	public function start_supplier_sync() {
		Supplier_Logger::debug( $this->supplier_id, 'Manual sync started by user' );
		if ( Constants::SYNC_RUNNING_STATUS_ON === $this->sync_running_status( $this->supplier_id, $this->schedule_id ) ) {
			// Sync already running → throw error.
			Supplier_Logger::debug( $this->supplier_id, 'Sync is already running. Please wait for the current sync to complete before starting a new one.' );
			return Response_Builder::error( 'Sync Already in Progress', "Sync process for supplier {$this->supplier_id} is already in progress." );
		}
		$schedule_id             = Sync_Details_DAO::get_instance()->get_schedule_id();
		$this->schedule_id       = $schedule_id;
		$supplier_sync_analytics = new Sync_Analytics( $this->supplier_id, $schedule_id );
		$supplier_sync_analytics->initiate_analytics( Constants::ANALYTICS_COMPLETE_CONNECTION );
		Sync_Details_DAO::get_instance()->set_supplier_analytics( $supplier_sync_analytics );

		$priority_queue      = $this->get_priority_queue( $this->supplier_id, $schedule_id );
		$this->connection_id = array_key_first( $priority_queue ) ?? 0;

		Supplier_Logger::debug( $this->supplier_id, 'Found ' . count( $priority_queue ) . ' connection(s) to sync. Starting with connection: ' . $this->connection_id );

		// Start audit session.
		$supplier_data = Supplier_Model::get_by_id( $this->supplier_id );
		Supplier_Audit_Logger::start_sync(
			$this->supplier_id,
			$schedule_id,
			array(
				'supplier_name' => isset( $supplier_data['name'] ) ? $supplier_data['name'] : '',
				'batch_enabled' => false,
				'batch_size'    => 0,
				'page_enabled'  => false,
			)
		);

		do_action(
			Plugin_Filters::FILTER_PERFORM_ACTION_BEFORE_SYNC,
			array(
				'connection_id' => $this->connection_id,
				'schedule_id'   => $schedule_id,
				'supplier_id'   => $this->supplier_id,
			)
		);

		/**
		 * Alter connection id.
		 *
		 * @param array $arguments Arguments.
		 * @return array
		 */
		if ( has_filter( Plugin_Filters::FILTER_ALTER_CONNECTION_ID ) ) {
			$arguments           = apply_filters(
				Plugin_Filters::FILTER_ALTER_CONNECTION_ID,
				array(
					'supplier_id'   => $this->supplier_id,
					'schedule_id'   => $this->schedule_id,
					'connection_id' => $this->connection_id,
				)
			);
			$this->connection_id = $arguments['connection_id'];
		}

		Cron_Manager::enqueue_product_sync_backup( $this->supplier_id, $this->schedule_id, $priority_queue );

		$connection_sync_analytics = new Sync_Analytics( $this->supplier_id, $schedule_id, $this->connection_id );
		$connection_sync_analytics->initiate_analytics( 'vendor-available' );
		Sync_Details_DAO::get_instance()->set_connection_analytics( $connection_sync_analytics );

		if ( empty( $priority_queue ) ) {
			Supplier_Logger::debug( $this->supplier_id, 'No connections found to sync. Sync process completed.' );
			$this->end_sync( Constants::COMPLETED_SYNC_RUNNING_STATUS );
			return Constants::COMPLETED_SYNC_RUNNING_STATUS;
		}

		Supplier_Logger::debug( $this->supplier_id, 'Initiating product sync from your supplier...' );
		$sync_end_status = $this->start_sync();
		Supplier_Logger::debug( $this->supplier_id, 'Sync process finished with status: ' . $sync_end_status );
		$this->end_sync( $sync_end_status );
		return $sync_end_status;
	}
}
