<?php
/**
 * Abstract base class for Omnibus providers.
 *
 * @package Ilabs\Firevert\Core\Integration\Omnibus
 */

declare( strict_types=1 );

namespace Ilabs\Firevert\Core\Integration\Omnibus;

use DateTime;
use Exception;
use Ilabs\Firevert\Core\Exceptions\InvalidOmnibusDateException;

/**
 * Class AbstractOmnibusProvider
 */
abstract class AbstractOmnibusProvider implements OmnibusProviderInterface {

	/**
	 * Calculates the number of days since the lowest price date.
	 *
	 * @param int $product_id WooCommerce product ID.
	 *
	 * @return int|null Number of days since the lowest price date.
	 *
	 * @throws InvalidOmnibusDateException If the date is missing or invalid.
	 */
	public function get_lowest_price_days_ago( int $product_id ): ?int {
		$date = $this->get_lowest_price_date( $product_id );

		if ( null === $date ) {
			return null;
		}

		$dt = DateTime::createFromFormat( 'Y-m-d', $date );
		if ( false === $dt || $dt->format( 'Y-m-d' ) !== $date ) {
			throw new InvalidOmnibusDateException(
				sprintf(
					'Invalid date format returned by provider for product ID %s. Expected Y-m-d, got: %s',
					esc_html( (string) $product_id ),
					esc_html( $date )
				)
			);
		}

		try {
			$now  = new DateTime();
			$diff = $now->diff( $dt );
		} catch ( Exception $e ) {
			throw new InvalidOmnibusDateException(
				sprintf(
					'Failed to calculate date difference for product ID %s: %s',
					esc_html( (string) $product_id ),
					esc_html( $e->getMessage() )
				)
			);
		}

		return (int) $diff->days;
	}

	/**
	 * Each provider must implement this to return the lowest price date in Y-m-d format.
	 *
	 * @param int $product_id WooCommerce product ID.
	 *
	 * @return string|null Date in 'Y-m-d' format, or null if unavailable.
	 */
	abstract public function get_lowest_price_date( int $product_id ): ?string;
}
