<?php
/**
 * Resolves which pricing rule applies to a matched product.
 *
 * @package EmberPrice
 */

namespace EmberPrice\Apply;

defined( 'ABSPATH' ) || exit;

/**
 * Lives in Apply (not Pricing) because it calls `wc_get_product()` --
 * Pricing stays WordPress-free so RuleEngine/Guardrails can be unit tested
 * without WP. Shared by `Rest\JobsController::preview_row()` and
 * `Apply\BatchApplier`, so a product's rule is resolved identically at
 * preview and apply time.
 */
final class RuleResolver {

	/**
	 * The first category override matching one of the product's
	 * categories, or the supplier default. A category override fully
	 * replaces the default rule, it isn't merged.
	 *
	 * @param array    $default_rule Supplier's `{ rule, category_overrides }`.
	 * @param int|null $product_id   Matched product id (the parent, for variations too --
	 *                                categories live on the parent product in WooCommerce).
	 */
	public function resolve_for_product( array $default_rule, ?int $product_id ): array {
		$rule      = (array) ( $default_rule['rule'] ?? array() );
		$overrides = (array) ( $default_rule['category_overrides'] ?? array() );

		if ( null === $product_id || empty( $overrides ) || ! function_exists( 'wc_get_product' ) ) {
			return $rule;
		}

		$product = wc_get_product( $product_id );

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

		foreach ( $product->get_category_ids() as $category_id ) {
			if ( isset( $overrides[ (string) $category_id ] ) ) {
				return (array) $overrides[ (string) $category_id ];
			}
		}

		return $rule;
	}
}
