<?php
/**
 * Writes one batch of a job's snapshots back onto their products.
 *
 * @package EmberPrice
 */

namespace EmberPrice\Apply;

defined( 'ABSPATH' ) || exit;

/**
 * SPEC §6 step 4, per snapshot: `wc_get_product`, restore
 * `_regular_price`/`_sale_price` to the values Apply\Snapshotter recorded
 * before the job was applied, `save()`, `wc_delete_product_transients` --
 * the exact inverse of BatchApplier's per-row write, and reusing the same
 * WooCommerce calls so the same hooks (lookup table sync, cache purge) fire.
 * A snapshot whose product can't be resolved, or whose write throws, is
 * skipped without aborting the rest of the batch, same as BatchApplier.
 */
final class RollbackApplier {

	/**
	 * Restores every snapshot in the batch, continuing past individual failures.
	 *
	 * @param array $snapshots Batch of snapshots (Core\Snapshots rows).
	 *
	 * @return array{applied: int, failed: int}
	 */
	public function apply_batch( array $snapshots ): array {
		$applied = 0;
		$failed  = 0;

		foreach ( $snapshots as $snapshot ) {
			if ( $this->restore_snapshot( $snapshot ) ) {
				++$applied;
			} else {
				++$failed;
			}
		}

		return array(
			'applied' => $applied,
			'failed'  => $failed,
		);
	}

	/**
	 * Restores one snapshot's prices onto its matched product/variation.
	 *
	 * @param array $snapshot A Core\Snapshots row.
	 */
	private function restore_snapshot( array $snapshot ): bool {
		if ( ! function_exists( 'wc_get_product' ) ) {
			return false;
		}

		$product = wc_get_product( $snapshot['variation_id'] ?? $snapshot['product_id'] );

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

		try {
			$product->set_regular_price( null !== $snapshot['old_regular_price'] ? (string) $snapshot['old_regular_price'] : '' );
			$product->set_sale_price( null !== $snapshot['old_sale_price'] ? (string) $snapshot['old_sale_price'] : '' );
			$product->save();

			wc_delete_product_transients( $product->get_id() );
		} catch ( \Throwable $exception ) {
			return false;
		}

		return true;
	}
}
