<?php
/**
 * WooCommerce order hooks → sync queue.
 *
 * @package StoreSheet
 */

declare( strict_types=1 );

namespace StoreSheet\Hooks;

defined( 'ABSPATH' ) || exit;

use StoreSheet\Queue\SyncQueue;
use StoreSheet\Sync\WcToSheets\OrderPusher;

class OrderHooks {

	private SyncQueue $queue;

	public function __construct( SyncQueue $queue ) {
		$this->queue = $queue;
	}

	public function init(): void {
		// New order from checkout (classic + block checkout).
		add_action( 'woocommerce_checkout_order_created', array( $this, 'on_order_created' ) );

		// New order created via REST API.
		add_action( 'woocommerce_new_order', array( $this, 'on_order_created_via_rest' ) );

		// Status changes — most useful for tracking order lifecycle.
		add_action( 'woocommerce_order_status_changed', array( $this, 'on_status_changed' ), 10, 3 );
	}

	public function on_order_created( \WC_Order $order ): void {
		if ( $this->is_sync_enabled() ) {
			$this->queue->enqueue_order( $order->get_id() );
			$this->maybe_enqueue_items( $order->get_id() );
		}
	}

	public function on_order_created_via_rest( int $order_id ): void {
		if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) {
			return;
		}
		if ( $this->is_sync_enabled() ) {
			$this->queue->enqueue_order( $order_id );
			$this->maybe_enqueue_items( $order_id );
		}
	}

	/**
	 * @param int    $order_id
	 * @param string $old_status
	 * @param string $new_status
	 */
	public function on_status_changed( int $order_id, string $old_status, string $new_status ): void {
		if ( ! $this->is_sync_enabled() ) {
			return;
		}

		$settings = get_option( 'storesheet_settings', array() );

		// When per-status tabs is on, push() widens its gate to all 7 core
		// statuses (the tabs ARE the status filter), so the enqueue trigger must
		// widen too — otherwise transitions into the 5 non-default statuses would
		// never be pushed in real time.
		$watched = ! empty( $settings['orders_per_status_tabs'] )
			? array_keys( OrderPusher::STATUS_TABS )
			: ( $settings['order_statuses'] ?? OrderPusher::DEFAULT_STATUSES );

		// Push when transitioning INTO a watched status.
		if ( in_array( $new_status, $watched, true ) ) {
			$this->queue->enqueue_order( $order_id );
			$this->maybe_enqueue_items( $order_id );
		}
	}

	private function is_sync_enabled(): bool {
		$settings = get_option( 'storesheet_settings', array() );
		return ! empty( $settings['sync_orders'] ) && ! empty( $settings['spreadsheet_id'] );
	}

	/**
	 * Enqueue the Order Items push alongside the order push, gated by the
	 * opt-in `sync_order_items` setting.
	 *
	 * @since 1.2.0
	 * @param int $order_id
	 */
	private function maybe_enqueue_items( int $order_id ): void {
		$settings = get_option( 'storesheet_settings', array() );
		if ( ! empty( $settings['sync_order_items'] ) ) {
			$this->queue->enqueue_order_items( $order_id );
		}
	}
}
