<?php
defined( 'ABSPATH' ) || exit;

class WCP_Gateway_Manager {

	private static ?self $instance = null;

	/** @var WCP_Payment_Gateway_Interface[] */
	private array $gateways = [];

	private function __construct() {}

	public static function instance(): self {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function register( WCP_Payment_Gateway_Interface $gateway ): void {
		$this->gateways[ $gateway->get_id() ] = $gateway;
	}

	public function get( string $id ): ?WCP_Payment_Gateway_Interface {
		return $this->gateways[ $id ] ?? null;
	}

	/** All gateways that are both enabled (toggle on) and configured (credentials set). */
	public function get_available(): array {
		$is_pro = WCP_License::is_pro();
		return array_filter(
			$this->gateways,
			function ( $gw ) use ( $is_pro ) {
				if ( ! $gw->is_enabled() || ! $gw->is_configured() ) {
					return false;
				}
				// UPI is always available; API gateways require an active Pro license.
				if ( $gw->get_id() !== 'upi' && ! $is_pro ) {
					return false;
				}
				return true;
			}
		);
	}

	// -------------------------------------------------------------------------

	public static function init(): void {
		$m = self::instance();
		$m->register( new WCP_Gateway_UPI() );
		$m->register( new WCP_Gateway_Razorpay() );
		$m->register( new WCP_Gateway_Cashfree() );
		$m->register( new WCP_Gateway_Custom() );

		// WooCommerce API hooks for return redirects and server-side webhooks.
		add_action( 'woocommerce_api_woocom_pay_razorpay',         [ 'WCP_Gateway_Razorpay', 'handle_return'  ] );
		add_action( 'woocommerce_api_woocom_pay_razorpay_webhook', [ 'WCP_Gateway_Razorpay', 'handle_webhook' ] );
		add_action( 'woocommerce_api_woocom_pay_cashfree',         [ 'WCP_Gateway_Cashfree', 'handle_return'  ] );
		add_action( 'woocommerce_api_woocom_pay_cashfree_webhook', [ 'WCP_Gateway_Cashfree', 'handle_webhook' ] );
		add_action( 'woocommerce_api_woocom_pay_custom',           [ 'WCP_Gateway_Custom',   'handle_return'  ] );
		add_action( 'woocommerce_api_woocom_pay_custom_webhook',   [ 'WCP_Gateway_Custom',   'handle_webhook' ] );

		// AJAX: create balance payment link for API gateways.
		add_action( 'wp_ajax_wcp_create_balance_link',        [ __CLASS__, 'ajax_create_balance_link' ] );
		add_action( 'wp_ajax_nopriv_wcp_create_balance_link', [ __CLASS__, 'ajax_create_balance_link' ] );
	}

	// -------------------------------------------------------------------------
	// AJAX: create balance payment link (used by balance page for API gateways)
	// -------------------------------------------------------------------------

	public static function ajax_create_balance_link(): void {
		check_ajax_referer( 'wcp_create_balance_link', 'nonce' );

		$order_id  = (int) ( $_POST['order_id'] ?? 0 );
		$method    = sanitize_key( $_POST['gateway'] ?? '' );

		if ( ! $order_id || ! $method ) {
			wp_send_json_error( [ 'message' => __( 'Invalid request.', 'woocom-pay' ) ] );
		}

		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			wp_send_json_error( [ 'message' => __( 'Order not found.', 'woocom-pay' ) ] );
		}

		$balance = (float) $order->get_meta( '_wcp_balance_amount' );
		if ( $balance <= 0 ) {
			wp_send_json_error( [ 'message' => __( 'No balance is due for this order.', 'woocom-pay' ) ] );
		}

		$manager = self::instance();
		$gateway = $manager->get( $method );

		if ( ! $gateway || ! $gateway->is_enabled() || ! $gateway->is_configured() ) {
			wp_send_json_error( [ 'message' => __( 'Selected payment method is not available.', 'woocom-pay' ) ] );
		}

		$return_url = home_url( "/?wc-api=woocom_pay_{$method}&order_id={$order_id}&balance=1" );
		$url        = $gateway->create_payment( $order, $balance, $return_url );

		if ( is_wp_error( $url ) ) {
			wp_send_json_error( [ 'message' => $url->get_error_message() ] );
		}

		wp_send_json_success( [ 'redirect_url' => $url ] );
	}
}
