<?php
/**
 * Amazon discount repository contract.
 *
 * @package Affilun\Application\AmazonDiscount
 */

declare(strict_types=1);

namespace Affilun\Application\AmazonDiscount;

use DateTimeImmutable;

/**
 * Persists daily Amazon discount snapshots separately from saved products.
 */
interface AmazonDiscountRepository {

	/**
	 * Atomically replace one category snapshot.
	 *
	 * @param string                      $searchIndex Amazon SearchIndex.
	 * @param list<AmazonDiscountProduct> $products    Products in upstream order.
	 */
	public function replaceCategory( string $searchIndex, array $products ): int;

	/**
	 * Atomically replace one brand snapshot.
	 *
	 * @param string                      $brand    Priority brand.
	 * @param list<AmazonDiscountProduct> $products Products in upstream order.
	 */
	public function replaceBrand( string $brand, array $products ): int;

	/**
	 * Delete one brand snapshot.
	 *
	 * @param string $brand Priority brand.
	 */
	public function deleteBrand( string $brand ): void;

	/**
	 * Load grouped rows for shortcode rendering.
	 *
	 * @param list<string> $categories  Category order.
	 * @param string       $sort        Closed sort token.
	 * @param int          $perCategory Maximum rows per category.
	 *
	 * @return array<string,list<AmazonDiscountProduct>>
	 */
	public function findGrouped( array $categories, string $sort, int $perCategory ): array;

	/**
	 * Load grouped rows for priority-brand rendering.
	 *
	 * @param list<string> $brands   Brand order.
	 * @param string       $sort     Closed sort token.
	 * @param int          $perBrand Maximum rows per brand.
	 *
	 * @return array<string,list<AmazonDiscountProduct>>
	 */
	public function findBrandsGrouped( array $brands, string $sort, int $perBrand ): array;

	/**
	 * Count all stored discount products.
	 */
	public function count(): int;

	/**
	 * Return the newest upstream fetch timestamp.
	 */
	public function latestFetchedAt(): ?DateTimeImmutable;
}
