<?php
/**
 * Affiliate link router.
 *
 * @package Affilun\Application\Affiliate
 */

declare(strict_types=1);

namespace Affilun\Application\Affiliate;

/**
 * Applies provider-specific affiliate routing templates.
 */
final class AffiliateLinkRouter {

	/**
	 * Templates keyed by provider.
	 *
	 * @var array<string, AffiliateRoutingTemplate>
	 */
	private array $templates;

	/**
	 * @param array<string, AffiliateRoutingTemplate> $templates Templates.
	 */
	public function __construct( array $templates ) {
		$this->templates = array_filter(
			$templates,
			static fn ( mixed $value ): bool => $value instanceof AffiliateRoutingTemplate
		);
	}

	/**
	 * Build a router from the repository.
	 *
	 * @param OptionStoreAffiliateRoutingRepository $repository Repository.
	 */
	public static function fromRepository( OptionStoreAffiliateRoutingRepository $repository ): self {
		return new self( $repository->load() );
	}

	/**
	 * Route URL when a provider template exists.
	 *
	 * @param string   $provider  Provider key.
	 * @param string   $url       URL.
	 * @param int|null $productId Product id.
	 */
	public function route( string $provider, string $url, ?int $productId = null ): string {
		$template = $this->templates[ $provider ] ?? null;
		if ( ! $template instanceof AffiliateRoutingTemplate ) {
			return $url;
		}
		return $template->apply( $url, $provider, $productId );
	}
}
