<?php
/**
 * affilun Cloud campaign suggestion.
 *
 * @package Affilun\Application\Cloud
 */

declare(strict_types=1);

namespace Affilun\Application\Cloud;

/**
 * One provider campaign/microcopy suggestion from affilun Cloud.
 */
final class CloudCampaignSuggestion {

	/**
	 * @param string              $provider       Provider.
	 * @param string              $label          Label.
	 * @param string              $microcopy      Microcopy.
	 * @param string              $startAt        Start date.
	 * @param string              $endAt          End date.
	 * @param string              $providerItemId Provider item id.
	 * @param string              $source         Suggestion source.
	 * @param array<string,mixed> $offer          Provider offer details.
	 * @param string              $title          Product title, when available.
	 * @param string              $detailUrl      Product detail URL, when available.
	 * @param string              $affiliateUrl   Affiliate URL, when available.
	 * @param array<string,mixed> $metadata       Source metadata.
	 */
	public function __construct(
		private string $provider,
		private string $label,
		private string $microcopy,
		private string $startAt,
		private string $endAt,
		private string $providerItemId = '',
		private string $source = '',
		private array $offer = array(),
		private string $title = '',
		private string $detailUrl = '',
		private string $affiliateUrl = '',
		private array $metadata = array()
	) {}

	/**
	 * Build from response data.
	 *
	 * @param array<string,mixed> $data Data.
	 */
	public static function fromArray( array $data ): self {
		return new self(
			is_scalar( $data['provider'] ?? null ) ? (string) $data['provider'] : '',
			is_scalar( $data['label'] ?? null ) ? (string) $data['label'] : '',
			is_scalar( $data['microcopy'] ?? null ) ? (string) $data['microcopy'] : '',
			is_scalar( $data['start_at'] ?? null ) ? (string) $data['start_at'] : '',
			is_scalar( $data['end_at'] ?? null ) ? (string) $data['end_at'] : '',
			is_scalar( $data['provider_item_id'] ?? null ) ? (string) $data['provider_item_id'] : '',
			is_scalar( $data['source'] ?? null ) ? (string) $data['source'] : '',
			is_array( $data['offer'] ?? null ) ? $data['offer'] : array(),
			is_scalar( $data['title'] ?? null ) ? (string) $data['title'] : '',
			is_scalar( $data['detail_url'] ?? null ) ? (string) $data['detail_url'] : '',
			is_scalar( $data['affiliate_url'] ?? null ) ? (string) $data['affiliate_url'] : '',
			is_array( $data['metadata'] ?? null ) ? $data['metadata'] : array()
		);
	}

	/** Provider. */
	public function provider(): string {
		return $this->provider;
	}

	/** Label. */
	public function label(): string {
		return $this->label;
	}

	/** Microcopy. */
	public function microcopy(): string {
		return $this->microcopy;
	}

	/** Start date. */
	public function startAt(): string {
		return $this->startAt;
	}

	/** End date. */
	public function endAt(): string {
		return $this->endAt;
	}

	/** Provider item id, when this suggestion is tied to one saved product. */
	public function providerItemId(): string {
		return $this->providerItemId;
	}

	/** Suggestion source. */
	public function source(): string {
		return $this->source;
	}

	/**
	 * Provider offer details.
	 *
	 * @return array<string,mixed>
	 */
	public function offer(): array {
		return $this->offer;
	}

	/** Product title, when available. */
	public function title(): string {
		return $this->title;
	}

	/** Product detail URL, when available. */
	public function detailUrl(): string {
		return $this->detailUrl;
	}

	/** Affiliate URL, when available. */
	public function affiliateUrl(): string {
		return $this->affiliateUrl;
	}

	/**
	 * Source metadata.
	 *
	 * @return array<string,mixed>
	 */
	public function metadata(): array {
		return $this->metadata;
	}

	/** Local saved product id, when Cloud echoes plugin metadata. */
	public function wpProductId(): ?int {
		$value = $this->metadata['wp_product_id'] ?? null;
		if ( is_int( $value ) && $value > 0 ) {
			return $value;
		}
		if ( is_string( $value ) && ctype_digit( $value ) && (int) $value > 0 ) {
			return (int) $value;
		}

		return null;
	}

	/** Whether this suggestion targets one saved product. */
	public function isProductOpportunity(): bool {
		return $this->providerItemId !== '' || $this->offer !== array();
	}

	/** Whether this suggestion has enough data to be saved locally. */
	public function isAddableProduct(): bool {
		return $this->provider !== ''
			&& $this->providerItemId !== ''
			&& $this->title !== ''
			&& $this->detailUrl !== ''
			&& $this->wpProductId() === null;
	}
}
