<?php
/**
 * Generator registry.
 *
 * @package Harbor_EU_EInvoicing_For_WooCommerce
 */

defined( 'ABSPATH' ) || exit;

class HEIN_Generator_Registry {

	private static array $generators = [];
	private static bool $registered  = false;

	public static function register( string $slug, string $class ): void {
		if ( ! is_subclass_of( $class, HEIN_Generator::class ) ) {
			return;
		}

		self::$generators[ $slug ] = $class;
	}

	public static function get( string $slug ): ?HEIN_Generator {
		self::ensure_registered();

		if ( ! isset( self::$generators[ $slug ] ) ) {
			return null;
		}

		$class = self::$generators[ $slug ];

		return new $class();
	}

	public static function all(): array {
		self::ensure_registered();

		$all = [];

		foreach ( self::$generators as $slug => $class ) {
			$all[ $slug ] = [
				'label' => $class::label(),
				'class' => $class,
			];
		}

		return $all;
	}

	/**
	 * Falls back to all() when no format is selected: a fresh install has never saved the option
	 * and must still show its Generate button
	 */
	public static function enabled(): array {
		$all      = self::all();
		$selected = HEIN_Admin_Settings::get( 'formats', [] );
		$slugs    = is_array( $selected ) && $selected
			? array_values( array_intersect( array_keys( $all ), $selected ) )
			: array_keys( $all );

		$slugs = (array) apply_filters( 'hein_generator_formats', $slugs );

		return array_intersect_key( $all, array_flip( $slugs ) );
	}

	public static function reset(): void {
		self::$generators = [];
		self::$registered = false;
	}

	/**
	 * Lazy by design: firing hein_register_generators during plugins_loaded would run it before
	 * any listener had attached, and the premium build would register zero paid formats
	 */
	private static function ensure_registered(): void {
		if ( self::$registered ) {
			return;
		}

		self::$registered = true;

		self::register( 'ubl', HEIN_UBL_Generator::class );

		do_action( 'hein_register_generators' );
	}
}
