<?php
/**
 * This file is for performing the CRON specific functionality.
 *
 * @package    Common
 * @subpackage CronManager
 * @author     miniOrange <info@miniorange.com>
 * @link       https://miniorange.com
 */

namespace MOWCPS\Common\Services\Cron;

use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Model;
use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Models\Sync_Details_DAO;
use MOWCPS\Common\Utils\Model_Utils;
use MOWCPS\Common\Utils\Utils;
use MOWCPS\Common\Models\Product_Sync_Audit_Model;
use MOWCPS\Common\Constants\Plugin_Filters;
/**
 * Class to manage CRON related functionalities.
 */
class Cron_Manager {

	/**
	 * Function to set custom frequency for CRON scheduling.
	 *
	 * @param array $available_frequencies The array of schedules. Default is an empty array.
	 * @return array
	 */
	public static function custom_scheduling_frequency( $available_frequencies ) {
		$frequencies = Model_Utils::get_option( 'mowcps_frequencies', array() );
		foreach ( $frequencies as $key => $value ) {
			$title                         = 'MO every ' . $value . ' seconds';
			$available_frequencies[ $key ] = array(
				'interval' => $value,
				'display'  => $title,
			);
		}
		return $available_frequencies;
	}

	/**
	 * Function to enqueue backup for a product sync.
	 *
	 * @param int   $supplier_id Supplier ID.
	 * @param int   $schedule_id Schedule ID.
	 * @param array $priority_queue Priority queue.
	 * @return void
	 */
	public static function enqueue_product_sync_backup( $supplier_id, $schedule_id, $priority_queue ) {
		$cron_arguments                   = array();
		$next_cron                        = Utils::get_next_cron_frequency();
		$cron_arguments['supplier_id']    = $supplier_id;
		$cron_arguments['schedule_id']    = $schedule_id;
		$cron_arguments['vendor_name']    = Sync_Details_DAO::get_instance()->get_supplier_app_type();
		$cron_arguments['priority_queue'] = $priority_queue;
		\wp_schedule_event( time(), 'mowcps_' . $next_cron . '_sec', 'mowcps_product_sync_backup_cron', array( $cron_arguments ) );

		//ADD filter to add manully created backup cron for backup-cron during sync completion.
		if ( has_filter( Plugin_Filters::FILTER_MANULLAY_CREATE_BACKUP_CRON ) ) {
			$connection_id = array_key_first( $priority_queue );
			apply_filters(
				Plugin_Filters::FILTER_MANULLAY_CREATE_BACKUP_CRON,
				array(
					'event_specifier' => Plugin_Filters::EVENT_CREATE_MANUAL_BACKUP_CRON,
					'supplier_id'     => $supplier_id,
					'connection_id'   => $connection_id,
					'additional_data'   => array(
						'updated_cron_arguments' => $cron_arguments,
					),
				)
			);
		}
	}

	/**
	 * Function to run sync for a batch of products.
	 *
	 * @param int   $supplier_id Supplier ID.
	 * @param int   $schedule_id Schedule ID.
	 * @param int   $connection_id Connection ID.
	 * @param array $priority_queue Priority queue.
	 * @param array $sync_arguments Current batch number.
	 *
	 * @return void
	 */
	public static function enqueue_product_batch_sync( $supplier_id, $schedule_id, $connection_id, $priority_queue, $sync_arguments = array(
		'batch_number'   => 1,
		'page_number'    => 1,
		'cron_initiator' => Constants::VENDOR_AVAILABLE_PRODUCTS,
		'sync_type'      => null,
	) ) {
		$sync_type = Sync_Details_DAO::get_instance()->get_connection_sync_type( $connection_id );

		if ( 'outbound' === $sync_type && ! Sync_Details_DAO::get_instance()->get_outbound_sync_status( $connection_id ) ) {
			return;
		}
		if ( 'connection_sync' === $sync_arguments['sync_type'] ) {

			$backup_cron_args = array(
				'supplier_id'    => $supplier_id,
				'schedule_id'    => $schedule_id,
				'vendor_name'    => Sync_Details_DAO::get_instance()->get_supplier_app_type(),
				'priority_queue' => $priority_queue,
			);
			// Clear old backup cron.
			\wp_clear_scheduled_hook( 'mowcps_product_sync_backup_cron', array( $backup_cron_args ) );

			$priority_queue = Sync_Details_DAO::get_instance()->update_supplier_priority_queue();
			if ( empty( $priority_queue ) ) {
				// directly stop sync from here.
				$supplier_sync_analytics                      = Sync_Details_DAO::get_instance()->get_supplier_analytics( $supplier_id, $schedule_id );
				$supplier_sync_analytics->sync_status_message = Constants::COMPLETED_SYNC_RUNNING_STATUS;
				$supplier_sync_analytics->sync_status_code    = Constants::COMPLETED_SYNC_RUNNING_STATUS;
				$supplier_sync_analytics->sync_end_time       = time();
				$supplier_sync_analytics->save();
				$connection_sync_analytics                      = Sync_Details_DAO::get_instance()->get_connection_analytics( $supplier_id, $schedule_id, $connection_id );
				$connection_sync_analytics->sync_status_message = Constants::COMPLETED_SYNC_RUNNING_STATUS;
				$connection_sync_analytics->sync_status_code    = Constants::COMPLETED_SYNC_RUNNING_STATUS;
				$connection_sync_analytics->sync_end_time       = time();
				$connection_sync_analytics->save();
				Product_Sync_Audit_Model::update_sync_running_status( $supplier_id, $schedule_id, Constants::SYNC_RUNNING_STATUS_OFF );
				Model_Utils::update_option( 'mowcps_' . $supplier_id . '_' . $schedule_id . '_sync_running_status', 'Sync Completed' );
				
				//ADD filter to remove manully created backup cron for backup-cron after sync completion.
				if ( has_filter( Plugin_Filters::FILTER_MANULLAY_CREATE_BACKUP_CRON ) ) {
					apply_filters(
						Plugin_Filters::FILTER_MANULLAY_CREATE_BACKUP_CRON,
						array(
							'event_specifier' => Plugin_Filters::EVENT_REMOVE_MANUAL_BACKUP_CRON,
							'supplier_id'     => $supplier_id,
							'connection_id'   => $connection_id,
							'additional_data'   => array(),
						)
					);
				}

				return;
			}

			$updated_backup_cron_args = array(
				'supplier_id'    => $supplier_id,
				'schedule_id'    => $schedule_id,
				'vendor_name'    => Sync_Details_DAO::get_instance()->get_supplier_app_type(),
				'priority_queue' => $priority_queue,
			);
			// schedule updated backup cron.
			$next_cron = Utils::get_next_cron_frequency();
			\wp_schedule_event( time(), 'mowcps_' . $next_cron . '_sec', 'mowcps_product_sync_backup_cron', array( $updated_backup_cron_args ) );
			$connection_id = array_key_first( $priority_queue );

			//ADD filter to UPDATE  manully created backup cron for backup-cron after updating backup cron.
			if ( has_filter( Plugin_Filters::FILTER_MANULLAY_CREATE_BACKUP_CRON ) ) {
				apply_filters(
					Plugin_Filters::FILTER_MANULLAY_CREATE_BACKUP_CRON,
					array(
						'event_specifier' => Plugin_Filters::EVENT_UPDATE_MANUAL_BACKUP_CRON,
						'supplier_id'     => $supplier_id,
						'connection_id'   => $connection_id,
						'additional_data'   => array(
							'updated_cron_arguments' => $updated_backup_cron_args,
						),
					)
				);
			}

			$sync_arguments = array(
				'batch_number'   => 1,
				'page_number'    => 1,
				'cron_initiator' => Constants::VENDOR_AVAILABLE_PRODUCTS,
				'sync_type'      => null,
			);

			$cron_arguments = array(
				'supplier_id'    => $supplier_id,
				'schedule_id'    => $schedule_id,
				'vendor_name'    => Sync_Details_DAO::get_instance()->get_supplier_app_type(),
				'connection_id'  => $connection_id,
				'priority_queue' => $priority_queue,
				'sync_arguments' => $sync_arguments,
			);
			if ( ! empty( $cron_arguments['priority_queue'] ) ) {
				\wp_schedule_single_event( time() + 2, 'mowcps_product_batch_sync_cron', array( $cron_arguments ) );
			}
			return;
		}
		$cron_arguments = array(
			'supplier_id'    => $supplier_id,
			'schedule_id'    => $schedule_id,
			'vendor_name'    => Sync_Details_DAO::get_instance()->get_supplier_app_type(),
			'connection_id'  => $connection_id,
			'priority_queue' => $priority_queue,
			'sync_arguments' => $sync_arguments,
		);
		\wp_schedule_single_event( time() + 2, 'mowcps_product_batch_sync_cron', array( $cron_arguments ) );
	}
}
