<?php

namespace SugarCalendarBookings\Integrations;

/**
 * Integration capability registry.
 *
 * Central registry that collects all integration capabilities by type.
 * Integrations register themselves during boot, and core services query
 * the registry by capability interface instead of importing concrete classes.
 *
 * Follows the same pattern as PaymentGatewayRegistry.
 *
 * @since 1.4.0
 */
class IntegrationCapabilityRegistry {

	/**
	 * Registered capabilities grouped by interface.
	 *
	 * @since 1.4.0
	 *
	 * @var array<string, IntegrationCapabilityInterface[]>
	 */
	private array $capabilities = [];

	/**
	 * Register an integration capability.
	 *
	 * Auto-detects which capability interfaces the instance implements
	 * and registers it under each one.
	 *
	 * @since 1.4.0
	 *
	 * @param IntegrationCapabilityInterface $capability The capability to register.
	 */
	public function register( IntegrationCapabilityInterface $capability ): void {

		$interfaces = class_implements( $capability );

		foreach ( $interfaces as $interface ) {
			if ( is_subclass_of( $interface, IntegrationCapabilityInterface::class ) ) {
				$this->capabilities[ $interface ][] = $capability;
			}
		}
	}

	/**
	 * Get all registered capabilities of a given type.
	 *
	 * @since 1.4.0
	 *
	 * @param string $interface The capability interface class name.
	 *
	 * @return IntegrationCapabilityInterface[]
	 */
	public function get( string $interface ): array {

		return $this->capabilities[ $interface ] ?? [];
	}

	/**
	 * Get only available (connected + enabled) capabilities of a type.
	 *
	 * @since 1.4.0
	 *
	 * @param string $interface The capability interface class name.
	 *
	 * @return IntegrationCapabilityInterface[]
	 */
	public function get_available( string $interface ): array {

		return array_filter(
			$this->get( $interface ),
			fn( IntegrationCapabilityInterface $cap ) => $cap->is_available()
		);
	}

	/**
	 * Find a specific provider by slug within a capability type.
	 *
	 * @since 1.4.0
	 *
	 * @param string $interface The capability interface class name.
	 * @param string $slug      The provider slug to find.
	 *
	 * @return IntegrationCapabilityInterface|null
	 */
	public function find( string $interface, string $slug ): ?IntegrationCapabilityInterface {

		foreach ( $this->get( $interface ) as $capability ) {
			if ( $capability->get_provider_slug() === $slug ) {
				return $capability;
			}
		}

		return null;
	}
}
