<?php
/**
 * Member rewards service for computing and granting member rewards.
 *
 * @package RewardsWP
 */

namespace Awesomemotive\Rewardswp\Services;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Awesomemotive\Rewardswp\Interfaces\IntegrationInterface;
use Awesomemotive\Rewardswp\Interfaces\IntegrationWithCouponInterface;
use Awesomemotive\Rewardswp\Settings\Options\Referrals\RewardsOption;

class MemberRewardsService {
	/**
	 * Supported reward recipients.
	 *
	 * @since 1.0.0
	 *
	 * @var array
	 */
	const RECIPIENTS = RewardsOption::CONTEXTS;

	/**
	 * Integration instance.
	 *
	 * @since 1.0.0
	 *
	 * @var IntegrationInterface|IntegrationWithCouponInterface
	 */
	private IntegrationInterface $integration;

	/**
	 * Rewards option instance.
	 *
	 * @since 1.0.0
	 *
	 * @var RewardsOption
	 */
	private RewardsOption $rewards_option;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param IntegrationInterface $integration    The integration instance.
	 * @param RewardsOption        $rewards_option The rewards option instance.
	 */
	public function __construct( IntegrationInterface $integration, RewardsOption $rewards_option ) {
		$this->integration    = $integration;
		$this->rewards_option = $rewards_option;
	}

	/**
	 * Retrieve the list of products for a given recipient.
	 *
	 * @since 1.0.0
	 *
	 * @param string $recipient The recipient key to retrieve products for.
	 *
	 * @return array An array of product data (id and name) or an empty array if no products are found.
	 */
	public function get_reward_products_included( string $recipient ): array {
		if ( ! method_exists( $this->integration, 'get_product' ) ) {
			return [];
		}

		// Validate the recipient.
		if ( ! in_array( $recipient, self::RECIPIENTS, true ) ) {
			return [];
		}

		// Attempt to retrieve cached products.
		$cache_key       = "reward_products_included_{$recipient}";
		$cached_products = wp_cache_get( $cache_key, 'rewardswp' );

		if ( false !== $cached_products ) {
			return $cached_products; // Return cached products if available.
		}

		// Get products for the recipient (can be objects with {id, name} or just IDs for legacy data).
		$products_data = $this->rewards_option->get_value()[ $recipient ]['products_included'] ?? [];

		if ( ! is_array( $products_data ) || empty( $products_data ) ) {
			return [];
		}

		// Process products and filter valid results.
		$products = array_values(
			array_filter(
				array_map(
					function ( $product_item ) {
						// Handle both object format {id, name} and legacy integer ID format.
						$product_id = is_array( $product_item ) ? ( $product_item['id'] ?? null ) : $product_item;

						if ( empty( $product_id ) ) {
							return null;
						}

						// If we already have the name from saved data, use it.
						if ( is_array( $product_item ) && ! empty( $product_item['name'] ) ) {
							return [
								'id'   => absint( $product_item['id'] ),
								'name' => $product_item['name'],
							];
						}

						// Otherwise, fetch product details from integration.
						$product = $this->integration->get_product( $product_id );

						return $product ? [
							'id'   => $product['id'] ?? null,
							'name' => $product['name'] ?? null,
						] : null;
					},
					$products_data
				),
				function ( $product ) {
					return ! is_null( $product ) && ! empty( $product['id'] ) && ! empty( $product['name'] );
				}
			)
		);

		// Store the result in the cache.
		wp_cache_set( $cache_key, $products, 'runtime' );

		return $products;
	}
}
