<?php
/**
 * Importer Registry.
 *
 * @since 1.0.0
 *
 * @package NimblyMail\SMTP
 */

namespace NimblyMail\SMTP\Import;

defined( 'ABSPATH' ) || exit;

/**
 * Class ImporterRegistry
 *
 * Registry of all available settings importers.
 * Provides methods to list, find, and filter importers.
 *
 * @since 1.0.0
 */
class ImporterRegistry {

    /**
     * Singleton instance.
     *
     * @since 1.0.0
     *
     * @var self|null
     */
    private static ?self $instance = null;

    /**
     * Registered importer instances.
     *
     * @since 1.0.0
     *
     * @var array<AbstractImporter>
     */
    private array $importers = array();

    /**
     * Get the singleton instance.
     *
     * @since 1.0.0
     *
     * @return self
     */
    public static function init(): self {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor.
     *
     * Registers all known importers.
     *
     * @since 1.0.0
     */
    private function __construct() {
        $this->importers = array(
            new EasyWpSmtpImporter(),
            new FluentSmtpImporter(),
            new WpMailSmtpImporter(),
        );
    }

    /**
     * Get all registered importers.
     *
     * @since 1.0.0
     *
     * @return array<AbstractImporter>
     */
    public function get_importers(): array {
        return $this->importers;
    }

    /**
     * Get a specific importer by slug.
     *
     * @since 1.0.0
     *
     * @param string $slug The importer slug identifier.
     *
     * @return AbstractImporter|null The importer instance, or null if not found.
     */
    public function get_importer( string $slug ): ?AbstractImporter {
        foreach ( $this->importers as $importer ) {
            if ( $importer->get_slug() === $slug ) {
                return $importer;
            }
        }

        return null;
    }

    /**
     * Get only importers that have data available to import.
     *
     * @since 1.0.0
     *
     * @return array<AbstractImporter>
     */
    public function get_available(): array {
        return array_values(
            array_filter(
                $this->importers,
                function ( AbstractImporter $importer ) {
                    return $importer->is_available();
                }
            )
        );
    }

    /**
     * Reset the singleton instance.
     *
     * @since 1.0.0
     */
    public static function reset(): void {
        self::$instance = null;
    }
}
