<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase, WordPress.Files.FileName.InvalidClassFileName
/**
 * Order Payment Data Service
 *
 * Resolves payment data for WooCommerce orders by delegating to the
 * appropriate payment gateway integration.
 *
 * Replaces the legacy autoship_get_order_payment_data() dispatcher
 * in src/payments.php.
 *
 * @package Autoship Cloud
 * @since 2.13.0
 */

namespace Autoship\Modules\Payments\Services;

use Autoship\Core\Plugin;
use Autoship\Domain\AbstractPaymentGateway;
use Autoship\Services\Logging\Logger;
use Exception;
use QPilotPaymentData;

/**
 * Service for resolving order payment data via the gateway registry.
 *
 * @package Autoship\Modules\Payments\Services
 * @since 2.13.0
 */
class OrderPaymentDataService {

	/**
	 * The payment gateway registry.
	 *
	 * @var PaymentGatewayRegistry
	 */
	private PaymentGatewayRegistry $registry;

	/**
	 * The payment method type registry.
	 *
	 * @var PaymentMethodTypeRegistry
	 */
	private PaymentMethodTypeRegistry $type_registry;

	/**
	 * Constructor.
	 *
	 * @param PaymentGatewayRegistry    $registry      The gateway registry.
	 * @param PaymentMethodTypeRegistry $type_registry The type registry.
	 */
	public function __construct( PaymentGatewayRegistry $registry, PaymentMethodTypeRegistry $type_registry ) {
		$this->registry      = $registry;
		$this->type_registry = $type_registry;
	}

	/**
	 * Get payment data for a WooCommerce order.
	 *
	 * Looks up the order's payment method, resolves the corresponding gateway
	 * integration, and delegates to its get_order_payment_data() method.
	 *
	 * Replaces autoship_get_order_payment_data().
	 *
	 * @param int $order_id The WC Order ID.
	 *
	 * @return QPilotPaymentData|null The payment data, or null if not resolvable.
	 */
	public function get_order_payment_data( int $order_id ): ?QPilotPaymentData {
		$order             = wc_get_order( $order_id );
		$payment_method_id = $order->get_payment_method();

		$valid_methods = $this->type_registry->get_valid_methods();

		$payment_data = null;

		if ( isset( $valid_methods[ $payment_method_id ] ) ) {
			$valid_name = $valid_methods[ $payment_method_id ];

			if ( Logger::is_tracing_enabled() ) {
				Logger::trace( 'Autoship Payment Methods Tracer', 'Using valid payment method for ' . $payment_method_id . ' the gateway is ' . $valid_name );
			}

			// Try the new integration class first.
			$gateway = $this->registry->get_gateway( $payment_method_id );

			if ( $gateway instanceof AbstractPaymentGateway ) {
				$payment_data = $gateway->get_order_payment_data( $order_id, $order );
			} else {
				// Fallback to legacy function naming convention for gateways
				// not yet promoted to AbstractPaymentGateway (e.g. FunnelKit, COD).
				$function = "autoship_get_{$valid_name}_order_payment_data";

				if ( function_exists( $function ) ) {
					$payment_data = $function( $order_id, $order );
				} elseif ( Logger::is_tracing_enabled() ) {
					Logger::trace( 'Autoship Payment Methods Tracer', 'There is no processor with name ' . $function );
				}
			}
		} elseif ( Logger::is_tracing_enabled() ) {
			Logger::trace( 'Autoship Payment Methods Tracer', 'There is no processor for ' . $payment_method_id );
		}

		return apply_filters( 'autoship_order_payment_data', $payment_data, $order_id );
	}

	/**
	 * Static convenience method to get order payment data.
	 *
	 * Resolves the service from the container with error handling.
	 * Safe to call from legacy procedural code.
	 *
	 * @param int $order_id The WC Order ID.
	 *
	 * @return QPilotPaymentData|null The payment data, or null on failure.
	 */
	public static function get_for_order( int $order_id ): ?QPilotPaymentData {
		try {
			$container = Plugin::get_service_container();
			$service   = $container->get( self::class );

			return $service->get_order_payment_data( $order_id );
		} catch ( \Throwable $e ) {
			Logger::error( 'Autoship Payment Methods', 'Failed to resolve payment data for order ' . $order_id . ': ' . $e->getMessage() );

			return null;
		}
	}
}
