<?php
/**
 * FedEx carrier strategy REST controller.
 *
 * @package Automattic\WCShipping\Carrier\FedEx
 */

namespace Automattic\WCShipping\Carrier\FedEx;

use Automattic\WCShipping\Exceptions\RESTRequestException;
use Automattic\WCShipping\WCShippingRESTController;
use WP_REST_Server;

/**
 * REST controller for FedEx carrier strategy operations.
 */
class FedExCarrierStrategyRESTController extends WCShippingRESTController {

	/**
	 * Route base.
	 *
	 * @var string
	 */
	protected $rest_base = 'carrier-strategy/fedex';

	/**
	 * FedEx carrier strategy service.
	 *
	 * @var FedExCarrierStrategyService
	 */
	private $fedex_carrier_service;

	/**
	 * Constructor.
	 *
	 * @param FedExCarrierStrategyService $fedex_carrier_service FedEx carrier strategy service.
	 */
	public function __construct( FedExCarrierStrategyService $fedex_carrier_service ) {
		$this->fedex_carrier_service = $fedex_carrier_service;
	}

	/**
	 * Register routes.
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base,
			array(
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update' ),
					'permission_callback' => array( $this, 'ensure_rest_permission' ),
				),
			)
		);
	}

	/**
	 * Error codes that indicate client validation errors (HTTP 400).
	 */
	private const CLIENT_ERROR_CODES = array(
		'invalid_user_email',
	);

	/**
	 * Handle TOS acceptance update.
	 *
	 * @param \WP_REST_Request $request Full details about the request.
	 * @return \WP_REST_Response
	 */
	public function update( $request ) {
		try {
			[ $confirmed ] = $this->get_and_check_request_params( $request, array( 'confirmed' ) );
		} catch ( RESTRequestException $error ) {
			return rest_ensure_response( $error->get_error_response() );
		}

		$confirmed = rest_sanitize_boolean( $confirmed );

		if ( ! $confirmed ) {
			return new \WP_REST_Response(
				array(
					'success' => false,
					'message' => __( 'You must accept the FedEx Terms of Service.', 'woocommerce-shipping' ),
				),
				400
			);
		}

		$response = $this->fedex_carrier_service->accept_tos();

		if ( is_wp_error( $response ) ) {
			$error_code  = $response->get_error_code();
			$status_code = in_array( $error_code, self::CLIENT_ERROR_CODES, true ) ? 400 : 500;

			return new \WP_REST_Response(
				array(
					'success' => false,
					'code'    => $error_code,
					'message' => $response->get_error_message(),
				),
				$status_code
			);
		}

		return rest_ensure_response(
			array(
				'success'   => true,
				'confirmed' => true,
			)
		);
	}
}
