<?php
/**
 * Sync Handler
 *
 * @category   WordPress_Plugin
 * @package    Common
 * @subpackage Handlers\Rest_API
 * @author     miniOrange <info@miniorange.com>
 * @license    MIT/Expat
 * @link       https://plugins.miniorange.com/woocommerce-api-product-sync-with-woocommerce-rest-apis
 */

namespace MOWCPS\Common\Handlers\Rest_API;

use WP_Error;
use MOWCPS\Common\Models\Supplier_Model;
use MOWCPS\Common\DTO\Sync_Request;
use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Controllers\Cron_Controller;
use MOWCPS\Common\Models\Sync_Queue_Model;
use MOWCPS\Common\Models\Setting_Model;

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

/**
 * Class Sync_Handler
 *
 * Handles sync REST API operations
 */
class Sync_Handler {

	/**
	 * Start sync
	 *
	 * @param string $supplier_uuid Supplier UUID.
	 * @param array  $data Sync data.
	 * @return array|WP_Error
	 */
	public function start_sync( $supplier_uuid, $data ) {
		// Validate UUID parameter using DTO.
		$validation = Sync_Request::validate_uuid( $supplier_uuid, 'supplier_uuid' );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		// Transform and validate data using DTO.
		$sync_request = Sync_Request::from_request_parameters( $data );
		if ( is_wp_error( $sync_request ) ) {
			return $sync_request;
		}

		$supplier = Supplier_Model::get_by_uuid( $supplier_uuid );

		if ( ! $supplier ) {
			return new WP_Error(
				Constants::ERROR_SUPPLIER_NOT_FOUND,
				Constants::MSG_SUPPLIER_NOT_FOUND,
				array( 'status' => Constants::HTTP_NOT_FOUND )
			);
		}

		$result = Sync_Queue_Model::create_manual_sync_queue( $supplier['id'], $data['attribute_mapping_ids'] );

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

		Cron_Controller::start_supplier_sync( array( 'supplier_id' => $supplier['id'] ) );

		return array( 'success' => true );
	}

	/**
	 * Pause sync
	 *
	 * @param string $supplier_uuid Supplier UUID.
	 * @return array|WP_Error
	 */
	public function pause_sync( $supplier_uuid, $data = array() ) {
		// Validate UUID parameter using DTO.
		$validation = Sync_Request::validate_uuid( $supplier_uuid, 'supplier_uuid' );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		$supplier = Supplier_Model::get_by_uuid( $supplier_uuid );
		$schedule = $data['schedule_id'] ? Setting_Model::get_by_uuid( $data['schedule_id'] ) : null;

		if ( ! $supplier ) {
			return new WP_Error(
				Constants::ERROR_SUPPLIER_NOT_FOUND,
				Constants::MSG_SUPPLIER_NOT_FOUND,
				array( 'status' => Constants::HTTP_NOT_FOUND )
			);
		}

		Cron_Controller::pause_sync(
			array(
				'supplier_id' => $supplier['id'],
				'schedule_id' => $schedule['id'] ?? null,
			)
		);

		return array( 'success' => true );
	}

	/**
	 * Resume sync
	 *
	 * @param string $supplier_uuid Supplier UUID.
	 * @return array|WP_Error
	 */
	public function resume_sync( $supplier_uuid, $data = array() ) {
		// Validate UUID parameter using DTO.
		$validation = Sync_Request::validate_uuid( $supplier_uuid, 'supplier_uuid' );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		$supplier = Supplier_Model::get_by_uuid( $supplier_uuid );
		$schedule = $data['schedule_uuid'] ? Setting_Model::get_by_uuid( $data['schedule_uuid'] ) : null;

		if ( ! $supplier ) {
			return new WP_Error(
				Constants::ERROR_SUPPLIER_NOT_FOUND,
				Constants::MSG_SUPPLIER_NOT_FOUND,
				array( 'status' => Constants::HTTP_NOT_FOUND )
			);
		}

		Cron_Controller::resume_sync(
			array(
				'supplier_id' => $supplier['id'],
				'schedule_id' => $schedule['schedule_id'] ?? null,
			)
		);

		return array( 'success' => true );
	}

	/**
	 * Abort sync
	 *
	 * @param string $supplier_uuid Supplier UUID.
	 * @param array  $data Sync data.
	 * @return array|WP_Error
	 */
	public function abort_sync( $supplier_uuid, $data = array() ) {
		// Validate UUID parameter using DTO.
		$validation = Sync_Request::validate_uuid( $supplier_uuid, 'supplier_uuid' );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		$supplier = Supplier_Model::get_by_uuid( $supplier_uuid );
		$schedule = $data['schedule_uuid'] ? Setting_Model::get_by_uuid( $data['schedule_uuid'] ) : null;

		if ( ! $supplier ) {
			return new WP_Error(
				Constants::ERROR_SUPPLIER_NOT_FOUND,
				Constants::MSG_SUPPLIER_NOT_FOUND,
				array( 'status' => Constants::HTTP_NOT_FOUND )
			);
		}

		$result = Sync_Queue_Model::delete_manual_sync_queue( $supplier['id'] );

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

		Cron_Controller::stop_sync(
			array(
				'supplier_id' => $supplier['id'],
				'schedule_id' => $schedule['schedule_id'] ?? null,
			)
		);

		return array( 'success' => true );
	}

	/**
	 * Get attribute mappings
	 *
	 * @param string $supplier_uuid Supplier UUID.
	 * @param array  $data Sync data.
	 * @return array|WP_Error
	 */
	public function get_attribute_mappings( $supplier_uuid, $data = array() ) {
		// Validate UUID parameter using DTO.
		$validation = Sync_Request::validate_uuid( $supplier_uuid, 'supplier_uuid' );

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

		$supplier = Supplier_Model::get_by_uuid( $supplier_uuid );
		$result   = Sync_Queue_Model::get_attribute_mappings_from_queue( $supplier['id'] );

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

		return $result;
	}
}
