<?php
/**
 * Amazon Shipment Service
 *
 * Handles shipment confirmation API calls to Amazon SP-API.
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/services/amazon
 * @author     miniOrange
 */

declare(strict_types=1);

namespace MOMCS_Sync\Includes\Common\Services\Amazon;

use MOMCS_Sync\Includes\Common\Services\Handlers\Api_Handler;
use MOMCS_Sync\Includes\Common\Utils\Marketplace_IDs;
use MOMCS_Sync\Includes\Common\Utils\Logger;

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

/**
 * Class for handling Amazon Shipment Confirmation API operations.
 */
class Shipment_Service {

	/**
	 * API Handler instance.
	 *
	 * @var Api_Handler
	 */
	private $api_handler;

	/**
	 * Token Service instance.
	 *
	 * @var Token_Service
	 */
	private $token_service;

	/**
	 * Logger instance.
	 *
	 * @var Logger
	 */
	private $logger;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->api_handler   = new Api_Handler();
		$this->token_service = new Token_Service();
		$this->logger        = new Logger( 'shipment-service' );
	}

	/**
	 * Confirm shipment for an Amazon order.
	 *
	 * @param string $channel_uuid      The channel UUID.
	 * @param string $amazon_order_id   The Amazon order ID.
	 * @param string $marketplace_id    The marketplace ID.
	 * @param array  $package_data      The package data including shipment details and items.
	 * @return array|WP_Error The API response or error.
	 */
	public function confirm_shipment( string $channel_uuid, string $amazon_order_id, string $marketplace_id, array $package_data ) {
		try {
			$this->logger->debug(
				sprintf(
					'Confirming shipment for order %s in marketplace %s',
					$amazon_order_id,
					$marketplace_id
				)
			);

			// Get access token.
			$access_token = $this->token_service->get_access_token( $channel_uuid );
			if ( is_wp_error( $access_token ) ) {
				$this->logger->error( 'Failed to get access token: ' . $access_token->get_error_message() );
				return $access_token;
			}

			// Get base URL for the marketplace.
			$base_url = Marketplace_IDs::get_api_base_url( $marketplace_id );
			if ( ! $base_url ) {
				$this->logger->error( 'Failed to get base URL for marketplace: ' . $marketplace_id );
				return new \WP_Error( 'invalid_marketplace', 'Invalid marketplace ID' );
			}

			// Build the API endpoint URL.
			$url = $base_url . '/orders/v0/orders/' . rawurlencode( $amazon_order_id ) . '/shipmentConfirmation';

			// Prepare the request payload.
			$payload = array(
				'marketplaceId'       => $marketplace_id,
				'codCollectionMethod' => $package_data['codCollectionMethod'] ?? '',
				'packageDetail'       => array(
					'packageReferenceId' => $package_data['packageReferenceId'],
					'carrierCode'        => $package_data['carrierCode'],
					'carrierName'        => $package_data['carrierName'],
					'shippingMethod'     => $package_data['shippingMethod'],
					'trackingNumber'     => $package_data['trackingNumber'],
					'shipDate'           => $package_data['shipDate'],
					'orderItems'         => $package_data['orderItems'],
				),
			);

			$this->logger->debug( 'Shipment confirmation payload: ' . wp_json_encode( $payload ) );

			// Set up headers.
			$headers = array(
				'X-AMZ-Access-Token' => $access_token,
				'Content-Type'       => 'application/json',
			);

			// Make API request.
			$response = $this->api_handler->post( $url, $payload, $headers );

			if ( is_wp_error( $response ) ) {
				$this->logger->error( 'Shipment confirmation failed: ' . $response->get_error_message() );
				return $response;
			}

			// Parse response.
			$body = json_decode( wp_remote_retrieve_body( $response ), true );

			$this->logger->debug( 'Shipment confirmation response: ' . wp_json_encode( $body ) );

			// Check for errors in the response.
			if ( isset( $body['errors'] ) && ! empty( $body['errors'] ) ) {
				$error_message = isset( $body['errors'][0]['message'] ) ? $body['errors'][0]['message'] : 'Unknown error';
				$this->logger->error( 'Amazon API error: ' . $error_message );
				return new \WP_Error( 'amazon_api_error', $error_message );
			}

			return $body;

		} catch ( \Exception $e ) {
			$this->logger->error( 'Exception in confirm_shipment: ' . $e->getMessage() );
			return new \WP_Error( 'shipment_confirmation_error', $e->getMessage() );
		}
	}
}
