<?php
/**
 * Intercepts FedEx TOS errors from the Connect Server.
 *
 * The live API client (in classes/) only passes through the UPS DAP TOS error code
 * (`missing_upsdap_terms_of_service_acceptance`). All other error codes get formatted
 * into a generic message that strips the code. This interceptor catches the HTTP
 * response before the API client processes it, and replaces the response body's
 * `code` field so the API client's existing passthrough logic handles FedEx TOS
 * errors correctly. The original FedEx code is preserved in the `data` property.
 *
 * @package Automattic\WCShipping\Carrier\FedEx
 */

namespace Automattic\WCShipping\Carrier\FedEx;

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

/**
 * FedEx TOS error interceptor.
 */
class FedExTosErrorInterceptor {

	private const FEDEX_TOS_CODE  = 'missing_fedex_terms_of_service_acceptance';
	private const UPSDAP_TOS_CODE = 'missing_upsdap_terms_of_service_acceptance';

	/**
	 * Register the HTTP response filter.
	 */
	public static function init() {
		add_filter( 'http_response', array( __CLASS__, 'intercept_fedex_tos_error' ), 10, 3 );
	}

	/**
	 * If the Connect Server responds with the FedEx TOS error, rewrite the
	 * response body `code` to `missing_upsdap_terms_of_service_acceptance` so
	 * the API client's existing TOS passthrough preserves it as a typed WP_Error.
	 * The real code is stored in `data.carrier_tos_code` for the frontend.
	 *
	 * @param array  $response    HTTP response.
	 * @param array  $parsed_args Request arguments.
	 * @param string $url         Request URL.
	 * @return array Modified response.
	 */
	public static function intercept_fedex_tos_error( $response, $parsed_args, $url ) {
		if ( ! defined( 'WOOCOMMERCE_CONNECT_SERVER_URL' ) ) {
			return $response;
		}

		$server_url = apply_filters( 'wcshipping_server_url', WOOCOMMERCE_CONNECT_SERVER_URL );
		if ( ! is_string( $server_url ) || '' === $server_url || 0 !== strpos( $url, $server_url ) ) {
			return $response;
		}

		if ( 403 !== wp_remote_retrieve_response_code( $response ) ) {
			return $response;
		}

		$body = wp_remote_retrieve_body( $response );
		if ( empty( $body ) ) {
			return $response;
		}

		$decoded = json_decode( $body );
		if ( ! is_object( $decoded ) || ! property_exists( $decoded, 'code' ) ) {
			return $response;
		}

		if ( self::FEDEX_TOS_CODE !== $decoded->code ) {
			return $response;
		}

		// Store the original code and swap in the UPS DAP code so the API
		// client's TOS passthrough (in classes/) returns a typed WP_Error
		// with the code intact instead of formatting it away.
		if ( ! isset( $decoded->data ) || ! is_object( $decoded->data ) ) {
			$decoded->data = new \stdClass();
		}
		$decoded->data->carrier_tos_code = self::FEDEX_TOS_CODE;
		$decoded->code                   = self::UPSDAP_TOS_CODE;

		$response['body'] = wp_json_encode( $decoded );

		return $response;
	}
}