<?php
/**
 * Payment Gateway Manager
 *
 * Singleton class to manage all payment gateways.
 *
 * @package GGM_Commerce
 */

// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class GGM_Commerce_Payment_Gateway_Manager
 *
 * Manages registration and retrieval of payment gateways.
 */
class GGM_Commerce_Payment_Gateway_Manager {

	/**
	 * Single instance of the class.
	 *
	 * @var GGM_Commerce_Payment_Gateway_Manager|null
	 */
	private static $instance = null;

	/**
	 * Registered payment gateways.
	 *
	 * @var array
	 */
	private $gateways = array();

	/**
	 * Whether gateways have been initialized.
	 *
	 * @var bool
	 */
	private $initialized = false;

	/**
	 * Private constructor to prevent direct instantiation.
	 */
	private function __construct() {
		$this->init();
	}

	/**
	 * Get single instance of the class.
	 *
	 * @return GGM_Commerce_Payment_Gateway_Manager
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Initialize the gateway manager.
	 *
	 * @return void
	 */
	private function init() {
		if ( $this->initialized ) {
			return;
		}

		$this->load_gateways();
		$this->initialized = true;
	}

	/**
	 * Load all available gateway classes.
	 *
	 * @return void
	 */
	private function load_gateways() {
		$gateway_dir = plugin_dir_path( __FILE__ );

		// Load Stripe gateway.
		$stripe_file = $gateway_dir . 'stripe/class-gateway-stripe.php';
		if ( file_exists( $stripe_file ) ) {
			require_once $stripe_file;
			if ( class_exists( 'GGM_Commerce_Gateway_Stripe' ) ) {
				$this->register_gateway( new GGM_Commerce_Gateway_Stripe() );
			}
		}

		// Load PayPal gateway.
		$paypal_file = $gateway_dir . 'paypal/class-gateway-paypal.php';
		if ( file_exists( $paypal_file ) ) {
			require_once $paypal_file;
			if ( class_exists( 'GGM_Commerce_Gateway_PayPal' ) ) {
				$this->register_gateway( new GGM_Commerce_Gateway_PayPal() );
			}
		}

		/**
		 * Allow third-party gateways to register themselves.
		 *
		 * @param GGM_Commerce_Payment_Gateway_Manager $manager The gateway manager instance.
		 */
		do_action( 'ggm_commerce_register_payment_gateways', $this );
	}

	/**
	 * Register a payment gateway.
	 *
	 * @param GGM_Commerce_Payment_Gateway $gateway Gateway instance.
	 * @return void
	 */
	public function register_gateway( GGM_Commerce_Payment_Gateway $gateway ) {
		$this->gateways[ $gateway->get_id() ] = $gateway;
	}

	/**
	 * Unregister a payment gateway.
	 *
	 * @param string $gateway_id Gateway ID.
	 * @return void
	 */
	public function unregister_gateway( $gateway_id ) {
		if ( isset( $this->gateways[ $gateway_id ] ) ) {
			unset( $this->gateways[ $gateway_id ] );
		}
	}

	/**
	 * Get a specific gateway by ID.
	 *
	 * @param string $gateway_id Gateway ID.
	 * @return GGM_Commerce_Payment_Gateway|null
	 */
	public function get_gateway( $gateway_id ) {
		return isset( $this->gateways[ $gateway_id ] ) ? $this->gateways[ $gateway_id ] : null;
	}

	/**
	 * Get all registered gateways.
	 *
	 * @return array
	 */
	public function get_all_gateways() {
		return $this->gateways;
	}

	/**
	 * Get all available gateways (licensed, configured, and enabled).
	 *
	 * @return array
	 */
	public function get_available_gateways() {
		$available = array();

		foreach ( $this->gateways as $id => $gateway ) {
			if ( $gateway->is_available() ) {
				$available[ $id ] = $gateway;
			}
		}

		return $available;
	}

	/**
	 * Get gateways that are activated (premium license active).
	 *
	 * @return array
	 */
	public function get_activated_gateways() {
		$activated = array();

		foreach ( $this->gateways as $id => $gateway ) {
			if ( $gateway->is_premium_activated() ) {
				$activated[ $id ] = $gateway;
			}
		}

		return $activated;
	}

	/**
	 * Get gateways that are enabled in settings.
	 *
	 * @return array
	 */
	public function get_enabled_gateways() {
		$enabled = array();

		foreach ( $this->gateways as $id => $gateway ) {
			if ( $gateway->is_enabled() ) {
				$enabled[ $id ] = $gateway;
			}
		}

		return $enabled;
	}

	/**
	 * Check if any payment gateway is available.
	 *
	 * @return bool
	 */
	public function has_available_gateways() {
		return ! empty( $this->get_available_gateways() );
	}

	/**
	 * Process payment through a specific gateway.
	 *
	 * @param string $gateway_id   Gateway ID.
	 * @param int    $order_id     Order ID.
	 * @param array  $payment_data Payment data.
	 * @return array Result array with success/error status.
	 */
	public function process_payment( $gateway_id, $order_id, $payment_data ) {
		$gateway = $this->get_gateway( $gateway_id );

		if ( ! $gateway ) {
			return array(
				'success' => false,
				'error'   => array(
					'message' => __( 'Invalid payment gateway.', 'ggm-commerce' ),
					'code'    => 'invalid_gateway',
				),
			);
		}

		if ( ! $gateway->is_available() ) {
			return array(
				'success' => false,
				'error'   => array(
					'message' => __( 'Payment gateway is not available.', 'ggm-commerce' ),
					'code'    => 'gateway_unavailable',
				),
			);
		}

		return $gateway->process_payment( $order_id, $payment_data );
	}

	/**
	 * Get gateway scripts for checkout.
	 *
	 * @return array
	 */
	public function get_checkout_scripts() {
		$scripts = array();

		foreach ( $this->get_available_gateways() as $gateway ) {
			$gateway_scripts = $gateway->get_scripts();
			if ( ! empty( $gateway_scripts ) ) {
				$scripts[ $gateway->get_id() ] = $gateway_scripts;
			}
		}

		return $scripts;
	}

	/**
	 * Render payment fields for all available gateways.
	 *
	 * @return void
	 */
	public function render_payment_methods() {
		$available_gateways = $this->get_available_gateways();

		if ( empty( $available_gateways ) ) {
			echo '<p class="ggmc-no-payment-methods">';
			esc_html_e( 'No payment methods are currently available.', 'ggm-commerce' );
			echo '</p>';
			return;
		}

		$first = true;
		foreach ( $available_gateways as $gateway ) {
			?>
			<div class="ggmc-payment-method" data-gateway="<?php echo esc_attr( $gateway->get_id() ); ?>">
				<label class="ggmc-payment-method-label">
					<input type="radio"
						   name="payment_method"
						   value="<?php echo esc_attr( $gateway->get_id() ); ?>"
						   <?php checked( $first ); ?>>
					<span class="ggmc-payment-method-info">
						<img src="<?php echo esc_url( $gateway->get_icon() ); ?>"
							 alt="<?php echo esc_attr( $gateway->get_title() ); ?>"
							 class="ggmc-payment-method-icon">
						<span class="ggmc-payment-method-title">
							<?php echo esc_html( $gateway->get_title() ); ?>
						</span>
					</span>
				</label>
				<div class="ggmc-payment-method-fields" style="<?php echo $first ? '' : 'display: none;'; ?>">
					<?php $gateway->render_payment_fields(); ?>
				</div>
			</div>
			<?php
			$first = false;
		}
	}

	/**
	 * Get gateway settings for JavaScript.
	 *
	 * @return array
	 */
	public function get_js_settings() {
		$settings = array(
			'gateways' => array(),
			'nonce'    => wp_create_nonce( 'ggm_commerce_payment' ),
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'rest_url' => rest_url( 'ggm-commerce/v1/' ),
		);

		foreach ( $this->get_available_gateways() as $gateway ) {
			$settings['gateways'][ $gateway->get_id() ] = array(
				'id'          => $gateway->get_id(),
				'title'       => $gateway->get_title(),
				'description' => $gateway->get_description(),
				'test_mode'   => $gateway->is_test_mode(),
			);
		}

		return $settings;
	}
}

/**
 * Helper function to get the Payment Gateway Manager instance.
 *
 * @return GGM_Commerce_Payment_Gateway_Manager
 */
function ggm_commerce_gateways() {
	return GGM_Commerce_Payment_Gateway_Manager::instance();
}
