<?php
/**
 * Recommendations API
 *
 * @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

use EDD\Pro\Utilities\Services\Request;

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

	const ENDPOINT = 'recommendations';

	/**
	 * Ingest products into the recommendations service.
	 *
	 * @since 3.6.2
	 * @param array $products The products to ingest.
	 * @return array|WP_Error The response data or error.
	 */
	public function ingest( array $products ) {
		$products = Products::format_downloads( $products );
		if ( empty( $products ) ) {
			return new \WP_Error(
				'recommendations_error',
				__( 'No products to ingest.', 'easy-digital-downloads' )
			);
		}

		return $this->make_request(
			'ingest',
			array(
				'body'    => wp_json_encode( array( 'products' => $products ) ),
				'method'  => 'POST',
				'timeout' => 30,
			)
		);
	}

	/**
	 * Get recommendations from the recommendations service.
	 *
	 * @since 3.6.2
	 * @param array $args The arguments.
	 * @return array|\WP_Error The recommendations or error.
	 */
	public function get_recommendations( array $args ) {

		$args = wp_parse_args(
			$args,
			array(
				'product_ids' => array(),
				'type'        => 'similar',
				'limit'       => 5,
				'exclude_ids' => array(),
				'filters'     => array(),
			)
		);

		if ( empty( $args['product_ids'] ) ) {
			return new \WP_Error(
				'recommendations_error',
				__( 'Product IDs are required to get recommendations.', 'easy-digital-downloads' )
			);
		}

		// Ensure product IDs are strings (Vectorize uses string IDs).
		$args['product_ids'] = array_map( 'strval', $args['product_ids'] );
		$args['exclude_ids'] = array_map( 'strval', $args['exclude_ids'] );

		return $this->make_request(
			'query',
			array(
				'body'   => wp_json_encode( $args ),
				'method' => 'POST',
			)
		);
	}

	/**
	 * Get vectorization status for the store.
	 *
	 * @since 3.6.2
	 * @return array|WP_Error Status data or error.
	 */
	public function get_status() {
		return $this->make_request( 'status' );
	}

	/**
	 * Clear the recommendations service.
	 *
	 * @since 3.6.2
	 * @param array $product_ids The product IDs to delete. Optional--passing none will delete all products.
	 * @return array|WP_Error The response data or error.
	 */
	public function delete( array $product_ids = array() ) {
		if ( ! current_user_can( 'manage_shop_settings' ) ) {
			return new \WP_Error(
				'recommendations_error',
				__( 'You do not have permission to clear recommendations.', 'easy-digital-downloads' )
			);
		}

		edd_delete_option( 'delete_recommendations_nonce' );

		if ( empty( $product_ids ) ) {
			$body = array(
				'delete_all' => true,
			);
		} else {
			$body = array(
				'product_ids' => $product_ids,
			);
		}

		return $this->make_request(
			'data',
			array(
				'method' => 'DELETE',
				'body'   => wp_json_encode( $body ),
			)
		);
	}

	/**
	 * Whether the API can make a request.
	 *
	 * @since 3.6.2
	 * @return bool
	 */
	public function can_make_request(): bool {
		return ! empty( edd_get_option( 'cart_recommendations', false ) ) && ! empty( $this->get_license_key() ) && ! empty( $this->get_store_url() );
	}

	/**
	 * Get the license key.
	 *
	 * @since 3.6.2
	 * @return string
	 */
	private function get_license_key(): string {
		return trim( get_site_option( 'edd_pro_license_key' ) );
	}

	/**
	 * Get the store URL.
	 *
	 * @since 3.6.2
	 * @return string
	 */
	private function get_store_url(): string {
		return wp_parse_url( home_url(), PHP_URL_HOST );
	}

	/**
	 * Make a request to the recommendations service.
	 *
	 * @since 3.6.2
	 * @param string $endpoint The endpoint to request.
	 * @param array  $args     The request arguments.
	 * @return array|\WP_Error The response data or error.
	 */
	private function make_request( string $endpoint, array $args = array() ) {
		if ( ! $this->can_make_request() ) {
			return new \WP_Error(
				'recommendations_unavailable',
				__( 'Recommendations service is not available. Please check your license.', 'easy-digital-downloads' )
			);
		}

		$args = wp_parse_args(
			$args,
			array(
				'headers' => array(
					'X-Store-URL' => $this->get_store_url(),
				),
				'method'  => 'GET',
			)
		);

		if ( ! empty( $args['body'] ) ) {
			$args['headers']['Content-Type'] = 'application/json';
		}

		$request = new Request(
			self::ENDPOINT . '/' . $endpoint,
			$args
		);

		$request->make_request();

		$response = $request->get_response();
		if ( is_wp_error( $response ) ) {
			edd_debug_log( $response->get_error_message() );

			return $response;
		}

		if ( 200 !== $response->response_code ) {
			return new \WP_Error(
				'recommendations_error',
				__( 'An error occurred while making the request.', 'easy-digital-downloads' ),
				array( 'status' => $response->response_code )
			);
		}

		return json_decode( $response->data, true );
	}
}
