<?php
/**
 * Public REST endpoint the front-end widget calls for a price + buy-link.
 *
 * Prices are public, so the route is public. All API secrets stay server-side.
 *
 * @package BW_2Checkout_Pricing
 */

defined( 'ABSPATH' ) || exit;

class BW_2Checkout_Pricing_REST {

	const NAMESPACE = 'bw-2checkout-pricing/v1';

	public function __construct() {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	public function register_routes() {
		register_rest_route(
			self::NAMESPACE,
			'/price',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'permission_callback' => '__return_true',
				'callback'            => array( $this, 'get_price' ),
				'args'                => array(
					'product'  => array(
						'type'     => 'string',
						'required' => true,
					),
					'currency' => array(
						'type'     => 'string',
						'required' => false,
					),
					'options'  => array(
						'type'        => 'string',
						'required'    => false,
						'description' => 'JSON object of option-group code => selected value.',
					),
					'tpl'      => array(
						'type'     => 'string',
						'required' => false,
					),
				),
			)
		);
	}

	/**
	 * @param WP_REST_Request $request Request.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_price( WP_REST_Request $request ) {
		$product  = sanitize_text_field( (string) $request->get_param( 'product' ) );
		$currency = sanitize_text_field( (string) $request->get_param( 'currency' ) );

		$options_raw = (string) $request->get_param( 'options' );
		$options     = array();
		if ( '' !== $options_raw ) {
			$decoded = json_decode( $options_raw, true );
			if ( is_array( $decoded ) ) {
				foreach ( $decoded as $group => $value ) {
					if ( is_scalar( $value ) ) {
						$options[ sanitize_text_field( (string) $group ) ] = sanitize_text_field( (string) $value );
					}
				}
			}
		}

		$pricing = new BW_2Checkout_Pricing_Pricing();
		$price   = $pricing->get_price( $product, $options, $currency );

		if ( is_wp_error( $price ) ) {
			return new WP_Error(
				$price->get_error_code(),
				$price->get_error_message(),
				array( 'status' => 400 )
			);
		}

		$tpl               = sanitize_text_field( (string) $request->get_param( 'tpl' ) );
		$price['buy_link'] = $pricing->build_buy_link( $product, $options, $price['currency'], $tpl );

		return rest_ensure_response( $price );
	}
}
