<?php
/**
 * The [Send Test Order] button.
 *
 * @package Ordsync
 */

defined( 'ABSPATH' ) || exit;

/**
 * This is not a feature. It is your support department.
 * Every ticket it prevents is pure profit at this price point.
 */
class Ordsync_Ajax {

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'wp_ajax_ordsync_test', array( $this, 'test' ) );
		add_action( 'wp_ajax_ordsync_import', array( $this, 'import' ) );
		add_action( 'wp_ajax_ordsync_retry', array( $this, 'retry' ) );
	}

	/**
	 * Queue one failed order at one destination again.
	 *
	 * Free, deliberately. Without this a permanently failed send can never be
	 * recovered without changing the order status by hand, and "orders did not
	 * arrive" is never something to charge for.
	 *
	 * Safe to press twice: _ordsync_done_ makes the send itself idempotent and
	 * Ordsync_Engine::enqueue() refuses to queue an identical job that is
	 * already pending.
	 *
	 * @return void
	 */
	public function retry() {

		check_ajax_referer( 'ordsync_test', 'nonce' );

		if ( ! current_user_can( Ordsync_Admin::CAPABILITY ) ) {
			wp_send_json_error(
				array( 'message' => __( 'You do not have permission to do this.', 'ordercarry-order-automation-for-woocommerce' ) ),
				403
			);
		}

		$order_id = isset( $_POST['order'] ) ? absint( wp_unslash( $_POST['order'] ) ) : 0;
		$dest     = isset( $_POST['dest'] ) ? sanitize_key( wp_unslash( $_POST['dest'] ) ) : '';

		if ( ! $order_id || '' === $dest ) {
			wp_send_json_error(
				array( 'message' => __( 'Nothing to retry.', 'ordercarry-order-automation-for-woocommerce' ) )
			);
		}

		Ordsync_Destinations::flush();

		if ( ! Ordsync_Destinations::get( $dest ) ) {
			wp_send_json_error(
				array( 'message' => __( 'That destination no longer exists.', 'ordercarry-order-automation-for-woocommerce' ) )
			);
		}

		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			wp_send_json_error(
				array( 'message' => __( 'That order no longer exists.', 'ordercarry-order-automation-for-woocommerce' ) )
			);
		}

		/*
		 * Clear the stored error first. Leaving it would make the card keep
		 * reporting a failure that is now queued for another go.
		 */
		$order->delete_meta_data( '_ordsync_error_' . $dest );
		$order->save();

		if ( ! Ordsync_Engine::enqueue( $order_id, $dest ) ) {
			wp_send_json_success(
				array( 'message' => __( 'Already queued — give it a moment.', 'ordercarry-order-automation-for-woocommerce' ) )
			);
		}

		Ordsync_Logger::info(
			sprintf( 'Order #%d → %s: retry queued by hand.', $order_id, $dest )
		);

		wp_send_json_success(
			array( 'message' => __( 'Queued. Reload this page in a moment to see the result.', 'ordercarry-order-automation-for-woocommerce' ) )
		);
	}

	/**
	 * Queue past orders for one destination.
	 *
	 * @return void
	 */
	public function import() {

		check_ajax_referer( 'ordsync_test', 'nonce' );

		if ( ! current_user_can( Ordsync_Admin::CAPABILITY ) ) {
			wp_send_json_error(
				array( 'message' => __( 'You do not have permission to do this.', 'ordercarry-order-automation-for-woocommerce' ) ),
				403
			);
		}

		// Importing is a paid feature; gate on the licence, not the build.
		if ( ! class_exists( 'Ordsync_Import' ) || ! function_exists( 'ordsync_is_premium' ) || ! ordsync_is_premium() ) {
			wp_send_json_error(
				array( 'message' => __( 'Importing past orders is a Pro feature.', 'ordercarry-order-automation-for-woocommerce' ) ),
				403
			);
		}

		$dest   = isset( $_POST['dest'] ) ? sanitize_key( wp_unslash( $_POST['dest'] ) ) : '';
		$limit  = isset( $_POST['limit'] ) ? absint( wp_unslash( $_POST['limit'] ) ) : 100;
		$status = isset( $_POST['status'] ) ? sanitize_key( wp_unslash( $_POST['status'] ) ) : 'any';

		Ordsync_Destinations::flush();

		$result = Ordsync_Import::queue( $dest, $limit, $status );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		if ( 0 === $result['queued'] ) {
			wp_send_json_success(
				array(
					'message' => __( 'Nothing to import — those orders are already queued or already sent.', 'ordercarry-order-automation-for-woocommerce' ),
				)
			);
		}

		$minutes = max( 1, $result['minutes'] );

		/*
		 * Two sentences, each pluralised on its own number. Folding both into
		 * one string made the minutes agree with the order count, producing
		 * "Queued 50 orders ... about 1 minutes".
		 */
		$queued_text = sprintf(
			/* translators: %d: number of orders queued */
			_n( 'Queued %d order.', 'Queued %d orders.', $result['queued'], 'ordercarry-order-automation-for-woocommerce' ),
			$result['queued']
		);

		$time_text = sprintf(
			/* translators: %d: number of minutes */
			_n( 'Allow about %d minute.', 'Allow about %d minutes.', $minutes, 'ordercarry-order-automation-for-woocommerce' ),
			$minutes
		);

		wp_send_json_success( array( 'message' => $queued_text . ' ' . $time_text ) );
	}

	/**
	 * Fire a fake order at a destination and report back.
	 *
	 * @return void
	 */
	public function test() {

		check_ajax_referer( 'ordsync_test', 'nonce' );

		if ( ! current_user_can( Ordsync_Admin::CAPABILITY ) ) {
			wp_send_json_error(
				array( 'message' => __( 'You do not have permission to do this.', 'ordercarry-order-automation-for-woocommerce' ) ),
				403
			);
		}

		// An instance id such as "sheets" or "sheets_1".
		$key = isset( $_POST['dest'] ) ? sanitize_key( wp_unslash( $_POST['dest'] ) ) : '';

		Ordsync_Destinations::flush();
		$destination = Ordsync_Destinations::get( $key );

		if ( ! $destination ) {
			wp_send_json_error(
				array( 'message' => __( 'Unknown destination.', 'ordercarry-order-automation-for-woocommerce' ) )
			);
		}

		if ( ! $destination->is_enabled() ) {
			wp_send_json_error(
				array(
					'message' => __( 'Turn this destination on and save your settings first.', 'ordercarry-order-automation-for-woocommerce' ),
				)
			);
		}

		$result = $destination->send( Ordsync_Payload::sample() );
		$name   = $destination->display_name();

		if ( is_wp_error( $result ) ) {
			Ordsync_Logger::error(
				sprintf( 'Test order → %s: %s', $name, $result->get_error_message() )
			);

			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		Ordsync_Logger::info( sprintf( 'Test order → %s: success.', $name ) );

		// Lets the card say "test passed" instead of "nothing sent yet".
		Ordsync_Settings::record_test( $key );

		// And puts the same test on the activity table, not just the chip.
		Ordsync_Events::record_test( $key );

		wp_send_json_success(
			array(
				'message' => __( 'Success — a test order was sent. Go and look.', 'ordercarry-order-automation-for-woocommerce' ),
			)
		);
	}
}
