<?php
/**
 * Wire order lifecycle hooks to customer emails.
 *
 * @package WPDudeProducts
 */

declare(strict_types=1);

namespace WPDude\Products\Emails;

use WPDude\Products\Access\Order_Magic_Link_Service;
use WPDude\Products\Orders\Statuses;

/**
 * Sends Order Received / Shipped / Refund emails.
 */
final class Email_Listener {

	private Email_Service $emails;
	private Order_Magic_Link_Service $links;

	public function __construct(
		?Email_Service $emails = null,
		?Order_Magic_Link_Service $links = null
	) {
		$this->emails = $emails ?? new Email_Service();
		$this->links  = $links ?? new Order_Magic_Link_Service();
	}

	/**
	 * Register hooks.
	 */
	public function register(): void {
		add_action( 'wpdude_dc_payment_completed', array( $this, 'on_payment_completed' ), 10, 1 );
		add_action( 'wpdude_dc_order_status_changed', array( $this, 'on_status_changed' ), 10, 3 );
	}

	/**
	 * @param array<string, mixed> $order Order.
	 */
	public function on_payment_completed( array $order ): void {
		$url = $this->links->get_or_create_url( $order );
		$this->emails->send_order_received( $order, $url );
	}

	/**
	 * @param array<string, mixed> $order Order.
	 * @param string               $from  Previous status.
	 * @param string               $to    New status.
	 */
	public function on_status_changed( array $order, string $from, string $to ): void {
		unset( $from );

		if ( Statuses::SHIPPED === $to ) {
			$url = $this->links->get_or_create_url( $order );
			$this->emails->send_order_shipped( $order, $url );
			return;
		}

		if ( Statuses::REFUNDED === $to ) {
			$url = $this->links->get_or_create_url( $order );
			$this->emails->send_refund_processed( $order, $url );
		}
	}
}
