import { ISource } from '../types/source.js';

/**
 * Les fichiers sources s'auto-enregistrent via `register()` au chargement du module
 * `initialize()` lance les health checks et ne garde que les sources fonctionnelles
 * Les routes et le state n'interagissent qu'avec les sources actives
 */
class SourceRegistry {
    private pending: ISource[] = [];
    private active = new Map<string, ISource>();
    private allRegistered = new Map<string, ISource>();

    /**
     * Enregistre une source dans la file d'attente.
     * Appelé automatiquement par chaque fichier source au chargement.
     */
    register(source: ISource) {
        this.pending.push(source);
        this.allRegistered.set(source.name, source);
    }

    /**
     * Retourne toutes les sources enregistrées (actives ou inactives).
     */
    getAllRegistered(): ISource[] {
        return Array.from(this.allRegistered.values());
    }

    /**
     * Lance les health checks sur toutes les sources enregistrées (en parallèle)
     * Seules les sources qui passent le check sont dites"active"
     */
    async initialize(): Promise<void> {
        const sourcesToTest = Array.from(this.allRegistered.values());
        console.log(`[Registry] Lancement des health checks sur ${sourcesToTest.length} source(s)...`);

        this.active.clear();
        this.pending = [];

        const results = await Promise.allSettled(
            sourcesToTest.map(async (source) => {
                const healthy = await source.healthCheck();
                return { source, healthy };
            })
        );

        for (const result of results) {
            if (result.status === 'fulfilled') {
                const { source, healthy } = result.value;
                if (healthy) {
                    this.active.set(source.name, source);
                    console.log(`[Registry] ✅ ${source.name.toUpperCase()} — opérationnelle`);
                    
                } else {
                    console.warn(`[Registry] ❌ ${source.name.toUpperCase()} — non disponible`);
                }
            } else {
                console.error(`[Registry] ❌ Health check crash:`, result.reason);
            }
        }

        const names = this.getAvailableNames();
        console.log(`[Registry] ${this.active.size} source(s) active(s): ${names.length ? names.map(n => n.toUpperCase()).join(', ') : 'Aucune'}`);
    }

    get(name: string): ISource | null {
        return this.active.get(name) || null;
    }

    getAll(): ISource[] {
        return Array.from(this.active.values());
    }

    getAvailableNames(): string[] {
        return Array.from(this.active.keys());
    }

    getDefault(): ISource | null {
        const first = this.active.values().next();
        return first.done ? null : first.value;
    }

    has(name: string): boolean {
        return this.active.has(name);
    }
}

export const sourceRegistry = new SourceRegistry();
