<?php

namespace SugarCalendarBookings\Payments\Gateways;

use Exception;
use SugarCalendarBookings\Plugin;

/**
 * Payment gateway registry.
 *
 * @since 1.0.0
 */
class PaymentGatewayRegistry {

	/**
	 * Registered gateways.
	 *
	 * @since 1.0.0
	 *
	 * @var array<string, AbstractPaymentGateway>
	 */
	private $gateways = [];

	/**
	 * Register a payment gateway.
	 *
	 * @since 1.0.0
	 *
	 * @param array<class-string<AbstractPaymentGateway>> $gateway_classes List of gateway classes.
	 */
	public function register_gateways( $gateway_classes ) {

		foreach ( $gateway_classes as $gateway_class ) {
			if ( ! class_exists( $gateway_class ) ) {
				continue;
			}

			if ( ! is_subclass_of( $gateway_class, AbstractPaymentGateway::class ) ) {
				continue;
			}

			$this->gateways[ $gateway_class::get_id() ] = Plugin::get( $gateway_class );
		}
	}

	/**
	 * Retrieve a gateway instance.
	 *
	 * @since 1.0.0
	 *
	 * @param string $gateway_id Gateway ID.
	 *
	 * @return AbstractPaymentGateway
	 * @throws Exception If gateway is not registered.
	 */
	public function get( $gateway_id ) {

		if ( ! isset( $this->gateways[ $gateway_id ] ) ) {
			throw new Exception(
				sprintf(
					'Payment gateway "%s" is not registered.',
					esc_html( $gateway_id )
				)
			);
		}

		return $this->gateways[ $gateway_id ];
	}

	/**
	 * Get registered gateways.
	 *
	 * @since 1.0.0
	 *
	 * @return array<string, AbstractPaymentGateway>
	 */
	public function get_registered() {

		return $this->gateways;
	}

	/**
	 * Get configured gateways.
	 *
	 * @since 1.0.0
	 *
	 * @return array<string, AbstractPaymentGateway>
	 */
	public function get_configured() {

		return array_filter(
			$this->gateways,
			fn( $gateway ) => $gateway->is_configured()
		);
	}
}
