<?php

declare(strict_types=1);

namespace Australcode\Rewards\Frontend;

use Australcode\Rewards\Domain\Settings\SettingsRepository;
use Australcode\Rewards\Service\EarningCalculator;
use WC_Product;

defined( 'ABSPATH' ) || exit;

/**
 * Shows an "Earn X points with this purchase" message on the single product
 * page. The figure is an estimate based on the displayed price and the global
 * rate (authoritative points are computed from the order at earn time).
 */
final class ProductPointsHook {

	public function __construct(
		private readonly EarningCalculator $calculator,
		private readonly SettingsRepository $settings,
	) {
	}

	public function register(): void {
		$position = self::position_hook( $this->settings->get()->product_message_position );
		add_action( $position['hook'], array( $this, 'render_product_message' ), $position['priority'] );
	}

	/**
	 * Maps a friendly position choice to the WooCommerce hook + priority that
	 * places the earn message there. Keeps raw hook names out of the admin UI
	 * (a non-dev picks "After the Add to cart button", not a hook string). Public
	 * + static so it can be unit-tested and reused.
	 *
	 * @return array{hook:string,priority:int}
	 */
	public static function position_hook( string $position ): array {
		switch ( $position ) {
			case 'before_cart':
				return array(
					'hook'     => 'woocommerce_before_add_to_cart_button',
					'priority' => 10,
				);
			case 'after_cart':
				return array(
					'hook'     => 'woocommerce_after_add_to_cart_button',
					'priority' => 10,
				);
			case 'after_meta':
				return array(
					'hook'     => 'woocommerce_product_meta_end',
					'priority' => 10,
				);
			case 'summary':
			default:
				return array(
					'hook'     => 'woocommerce_single_product_summary',
					'priority' => 25,
				);
		}
	}

	public function render_product_message(): void {
		$settings = $this->settings->get();
		if ( ! $settings->earning_enabled || ! $settings->show_product_message ) {
			return;
		}

		global $product;
		if ( ! $product instanceof WC_Product ) {
			return;
		}

		$price  = (float) wc_get_price_to_display( $product );
		$points = $this->calculator->points_for_amount( $price, $product->get_id() );
		if ( $points <= 0 ) {
			return;
		}

		$label = 1 === $points ? $settings->points_label_singular : $settings->points_label_plural;

		/* translators: keep the {points} and {points_label} placeholders. */
		$default  = __( 'Earn <strong>{points} {points_label}</strong> with this purchase.', 'australcode-points-rewards' );
		$template = '' !== $settings->msg_product ? $settings->msg_product : $default;

		$message = MessageTemplate::render(
			$template,
			array(
				'{points}'       => esc_html( number_format_i18n( $points ) ),
				'{points_label}' => esc_html( $label ),
			)
		);

		echo '<p class="acrwd-points-message">' . wp_kses_post( $message ) . '</p>';
	}
}
