<?php
/**
 * Amazon Restrictions Service
 *
 * This class handles checking for listing restrictions on Amazon
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/services/amazon
 * @author     miniOrange
 * @license    Expat
 * @link       https://miniorange.com
 */

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\Logger;
use MOMCS_Sync\Includes\Common\Utils\Marketplace_IDs;

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

/**
 * Class for handling Amazon listing restrictions.
 */
class Restrictions_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;

	/**
	 * Restrictions endpoint.
	 *
	 * @var string
	 */
	private $restrictions_endpoint = '/listings/2021-08-01/restrictions';

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

	/**
	 * Get dynamic base URL for Amazon API based on marketplace.
	 *
	 * @param string $marketplace_id Amazon marketplace ID.
	 * @return string Base URL.
	 */
	private function get_base_url( string $marketplace_id ): string {
		// Get dynamic URL based on marketplace.
		return Marketplace_IDs::get_api_base_url( $marketplace_id ) ?? 'https://sellingpartnerapi-eu.amazon.com';
	}

	/**
	 * Check listing restrictions for a product.
	 *
	 * @param string $channel_id     Channel UUID.
	 * @param string $asin           Amazon ASIN (optional for new products).
	 * @param string $seller_id      Seller ID.
	 * @param string $marketplace_id Amazon marketplace ID.
	 * @param string $condition_type Product condition (default: 'new_new').
	 * @param array  $log_context  Log context.
	 * @return array|WP_Error Restrictions data or WP_Error on failure.
	 */
	public function check_restrictions( $channel_id, $asin = '', $seller_id = 'ARFOUL5QD8W1L', $marketplace_id = '', $condition_type = 'new_new', $log_context = array() ) {
		$this->logger->debug(
			'Checking listing restrictions',
			array(
				'asin'           => $asin,
				'marketplace_id' => $marketplace_id,
				'condition_type' => $condition_type,
			)
		);

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

		// If seller ID is not provided, try to get it from options.
		if ( empty( $seller_id ) ) {
			$seller_id = get_option( 'momcs_sync_seller_id', '' );
			if ( empty( $seller_id ) ) {
				$this->logger->error( 'Seller ID is required but not provided' );
				return new \WP_Error( 'missing_seller_id', 'Seller ID is required but not provided.' );
			}
		}

		// Prepare query parameters.
		$query_params = array(
			'sellerId'       => $seller_id,
			'marketplaceIds' => $marketplace_id,
			'conditionType'  => $condition_type,
		);

		// Add ASIN if available.
		if ( ! empty( $asin ) ) {
			$query_params['asin'] = $asin;
		}

		// Build the URL with query parameters.
		$url = $this->get_base_url( $marketplace_id ) . $this->restrictions_endpoint . '?' . http_build_query( $query_params );

		// Make API request.
		$response = $this->api_handler->get(
			$url,
			array(
				'X-AMZ-Access-Token' => $access_token,
			),
			null,
			$log_context
		);

		// Check for errors.
		if ( is_wp_error( $response ) ) {
			$this->logger->error(
				'Error checking restrictions',
				array(
					'error' => $response->get_error_message(),
				)
			);
			return $response;
		}

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

		// Log the response.
		$this->logger->debug(
			'Restrictions API response',
			array(
				'status_code' => $status_code,
				'body'        => $body,
			)
		);

		// Handle 404 for new products (no ASIN).
		if ( 404 === $status_code && empty( $asin ) ) {
			$this->logger->debug( 'No restrictions found for new product (expected for new products)' );
			return array(
				'has_restrictions' => false,
				'restrictions'     => array(),
			);
		}

		// Process restrictions.
		$has_restrictions = false;
		$restrictions     = array();

		if ( isset( $body['restrictions'] ) && is_array( $body['restrictions'] ) ) {
			foreach ( $body['restrictions'] as $restriction ) {
				if ( isset( $restriction['reasons'] ) && ! empty( $restriction['reasons'] ) ) {
					$has_restrictions = true;
					$restrictions[]   = $restriction;
				}
			}
		}

		return array(
			'has_restrictions' => $has_restrictions,
			'restrictions'     => $restrictions,
		);
	}

	/**
	 * Format restrictions for display.
	 *
	 * @param array $restrictions Restrictions data from check_restrictions().
	 * @return array Formatted restrictions with messages.
	 */
	public function format_restrictions( $restrictions ) {
		if ( ! isset( $restrictions['restrictions'] ) || empty( $restrictions['restrictions'] ) ) {
			return array(
				'has_restrictions' => false,
				'messages'         => array(),
			);
		}

		$formatted = array(
			'has_restrictions' => $restrictions['has_restrictions'],
			'messages'         => array(),
		);

		foreach ( $restrictions['restrictions'] as $restriction ) {
			if ( isset( $restriction['reasons'] ) ) {
				foreach ( $restriction['reasons'] as $reason ) {
					$message = isset( $reason['message'] ) ? $reason['message'] : '';
					$code    = isset( $reason['reasonCode'] ) ? $reason['reasonCode'] : '';

					$formatted['messages'][] = array(
						'message'        => $message,
						'code'           => $code,
						'marketplace_id' => isset( $restriction['marketplaceId'] ) ? $restriction['marketplaceId'] : '',
					);

					// Add link to Seller Central for approval if needed.
					if ( 'approval_required' === $code ) {
						$formatted['approval_required']  = true;
						$formatted['seller_central_url'] = Marketplace_IDs::get_seller_central_url( $restriction['marketplaceId'] ?? '' );
					}
				}
			}
		}

		return $formatted;
	}
}
