<?php
/**
 * Amazon discount product record.
 *
 * @package Affilun\Application\AmazonDiscount
 */

declare(strict_types=1);

namespace Affilun\Application\AmazonDiscount;

use DateTimeImmutable;

/**
 * Immutable product row stored outside the normal affiliate product table.
 */
final class AmazonDiscountProduct {

	/**
	 * Create an immutable discount snapshot.
	 *
	 * @param string            $searchIndex       Amazon SearchIndex.
	 * @param int               $position          Upstream result position.
	 * @param string            $asin              Amazon product identifier.
	 * @param string            $title             Product title.
	 * @param string|null       $brand             Product brand.
	 * @param string            $detailUrl         Canonical detail URL.
	 * @param string            $affiliateUrl      Affiliate detail URL.
	 * @param string|null       $imageUrl          Primary image URL.
	 * @param string|null       $priceAmount       Decimal price amount.
	 * @param string|null       $priceCurrency     ISO currency code.
	 * @param string|null       $priceLabel        Formatted price.
	 * @param int|null          $savingsPercentage Selected listing saving.
	 * @param int               $minSavingPercent  Search threshold.
	 * @param DateTimeImmutable $fetchedAt         Snapshot timestamp.
	 */
	public function __construct(
		private string $searchIndex,
		private int $position,
		private string $asin,
		private string $title,
		private ?string $brand,
		private string $detailUrl,
		private string $affiliateUrl,
		private ?string $imageUrl,
		private ?string $priceAmount,
		private ?string $priceCurrency,
		private ?string $priceLabel,
		private ?int $savingsPercentage,
		private int $minSavingPercent,
		private DateTimeImmutable $fetchedAt
	) {
	}

	/**
	 * Return the Amazon SearchIndex.
	 */
	public function searchIndex(): string {
		return $this->searchIndex;
	}

	/**
	 * Return the localized category label.
	 */
	public function categoryLabel(): string {
		$brand = AmazonDiscountBrand::fromStorageKey( $this->searchIndex );
		if ( $brand !== null ) {
			return $brand;
		}
		return AmazonDiscountCategory::label( $this->searchIndex );
	}

	/**
	 * Return the upstream result position.
	 */
	public function position(): int {
		return $this->position;
	}

	/**
	 * Return the ASIN.
	 */
	public function asin(): string {
		return $this->asin;
	}

	/**
	 * Return the product title.
	 */
	public function title(): string {
		return $this->title;
	}

	/**
	 * Return the optional brand.
	 */
	public function brand(): ?string {
		return $this->brand;
	}

	/**
	 * Return the canonical detail URL.
	 */
	public function detailUrl(): string {
		return $this->detailUrl;
	}

	/**
	 * Return the affiliate URL.
	 */
	public function affiliateUrl(): string {
		return $this->affiliateUrl;
	}

	/**
	 * Return the optional primary image URL.
	 */
	public function imageUrl(): ?string {
		return $this->imageUrl;
	}

	/**
	 * Return the optional decimal price amount.
	 */
	public function priceAmount(): ?string {
		return $this->priceAmount;
	}

	/**
	 * Return the optional ISO currency code.
	 */
	public function priceCurrency(): ?string {
		return $this->priceCurrency;
	}

	/**
	 * Return the optional formatted price.
	 */
	public function priceLabel(): ?string {
		return $this->priceLabel;
	}

	/**
	 * Return the selected listing saving percentage.
	 */
	public function savingsPercentage(): ?int {
		return $this->savingsPercentage;
	}

	/**
	 * Return the minimum saving threshold used for discovery.
	 */
	public function minSavingPercent(): int {
		return $this->minSavingPercent;
	}

	/**
	 * Return the snapshot timestamp.
	 */
	public function fetchedAt(): DateTimeImmutable {
		return $this->fetchedAt;
	}
}
