<?php
/**
 * Recommendations Products
 *
 * @package   EDD\Pro\Recommendations
 * @copyright Copyright (c) 2025, Sandhills Development, LLC
 * @license   https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since     3.6.2
 */

namespace EDD\Pro\Recommendations;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

/**
 * Recommendations Products class
 *
 * @since 3.6.2
 */
class Products {

	/**
	 * Format a download for the recommendations service.
	 *
	 * @since 3.6.2
	 * @param int|EDD_Download $download The download to format.
	 * @return array|false The formatted download.
	 */
	public static function format( $download ) {
		if ( is_numeric( $download ) ) {
			$download = edd_get_download( $download );
		}

		if ( ! $download instanceof \EDD_Download || ! $download->can_purchase() ) {
			return false;
		}

		$product = array(
			'id'          => (string) $download->ID,
			'title'       => $download->post_title,
			'description' => self::clean_description( $download->post_content ),
			'category'    => self::get_primary_category( $download->ID ),
			'price'       => self::get_display_price( $download->ID ),
		);

		// Add custom fields.
		$custom_fields = self::get_custom_fields( $download->ID );
		if ( ! empty( $custom_fields ) ) {
			$product['custom_fields'] = $custom_fields;
		}

		return $product;
	}

	/**
	 * Format an array of downloads for the recommendations service.
	 *
	 * @since 3.6.2
	 * @param array $downloads The downloads to format.
	 * @return array The formatted downloads.
	 */
	public static function format_downloads( array $downloads ) {
		return array_filter(
			array_map(
				array( __CLASS__, 'format' ),
				$downloads
			)
		);
	}

	/**
	 * Get all download IDs.
	 *
	 * @since 3.6.2
	 * @param array $args Query arguments.
	 * @return array The download IDs.
	 */
	public static function get_all_download_ids( $args = array() ) {
		$args = wp_parse_args(
			$args,
			array(
				'post_type'      => 'download',
				'post_status'    => 'publish',
				'posts_per_page' => -1,
				'fields'         => 'ids',
				'orderby'        => 'ID',
				'order'          => 'ASC',
			)
		);

		/**
		 * Filters the query arguments for retrieving downloads to sync.
		 *
		 * @since 3.6.2
		 * @param array $args Query arguments.
		 */
		$args = apply_filters( 'edd_recommendations_sync_query_args', $args );

		$query = new \WP_Query( $args );

		return $query->posts;
	}

	/**
	 * Clean and truncate description for embedding.
	 *
	 * @since 3.6.2
	 * @param string $content Post content.
	 * @return string Cleaned description.
	 */
	private static function clean_description( $content ) {
		// Strip shortcodes.
		$content = strip_shortcodes( $content );

		// Strip HTML tags.
		$content = wp_strip_all_tags( $content );

		// Normalize whitespace.
		$content = preg_replace( '/\s+/', ' ', $content );

		// Truncate to reasonable length (services truncates to 500 chars).
		return mb_substr( trim( $content ), 0, 500 );
	}

	/**
	 * Get the primary category for a download.
	 *
	 * @since 3.6.2
	 * @param int $download_id Download ID.
	 * @return string Category name or empty string.
	 */
	private static function get_primary_category( $download_id ) {
		$categories = get_the_terms( $download_id, 'download_category' );

		if ( empty( $categories ) || is_wp_error( $categories ) ) {
			return '';
		}

		// Return the first category.
		$category = reset( $categories );

		return $category->name;
	}

	/**
	 * Get display price for a download.
	 *
	 * Returns the lowest price for variable pricing, or the single price.
	 *
	 * @since 3.6.2
	 * @param int $download_id Download ID.
	 * @return float Price as float.
	 */
	private static function get_display_price( $download_id ) {
		if ( edd_has_variable_prices( $download_id ) ) {
			$prices = edd_get_variable_prices( $download_id );

			if ( empty( $prices ) ) {
				return 0.00;
			}

			// Get the lowest price.
			$lowest = min( wp_list_pluck( $prices, 'amount' ) );

			return (float) $lowest;
		}

		return (float) edd_get_download_price( $download_id );
	}

	/**
	 * Get custom fields for enhanced recommendations.
	 *
	 * Add any custom meta fields that should influence recommendations.
	 * Examples: difficulty level, file type, version, etc.
	 *
	 * @since 3.6.2
	 * @param int $download_id Download ID.
	 * @return array Custom fields array.
	 */
	private static function get_custom_fields( $download_id ) {
		/**
		 * Filters custom fields to include in recommendation data.
		 *
		 * Use this filter to add store-specific metadata that should influence
		 * recommendations. Examples:
		 * - Difficulty level (beginner, intermediate, advanced)
		 * - File types (PDF, video, software)
		 * - Version numbers
		 * - Author names
		 * - Any other semantic metadata
		 *
		 * @since 3.6.2
		 * @param array $custom_fields Custom fields array.
		 * @param int   $download_id   Download ID.
		 */
		return apply_filters( 'edd_recommendations_custom_fields', array(), $download_id );
	}
}
