import { sourceRegistry } from '../core/registry.js';
import { ISource, SearchResult } from '../types/source.js';
import { loadSettings } from './settingsManager.js';
import { enrichSearchResults } from './tmdbEnricher.js';
import { CONFIG } from './config.js';

export interface GlobalState {
    currentTitleId: string | null;
    currentTitleName: string | null;
    currentIdentifier: string | null; // hrefPath du contenu sélectionné (source-agnostic)
    currentSelectionSource: string | null; // Nom de la source ayant fourni le contenu sélectionné
    currentLiens: any[];
    directUrlMap: Record<string, string>;
    isSeries: boolean;
    activeSources: string[]; // Liste des sources actives
    isSiteOffline: boolean;
    siteOfflineMessage: string;
    isCheckingStatus: boolean;
    trendingFilms: SearchResult[];
    trendingSeries: SearchResult[];
    recentItems: SearchResult[];
}

export const globalState: GlobalState = {
    currentTitleId: null,
    currentTitleName: null,
    currentIdentifier: null,
    currentSelectionSource: null,
    currentLiens: [],
    directUrlMap: {},
    isSeries: false,
    activeSources: [],
    isSiteOffline: true,
    siteOfflineMessage: "Vérification du statut du site en cours...",
    isCheckingStatus: false,
    trendingFilms: [],
    trendingSeries: [],
    recentItems: [],
};

/**
 * Retourne les instances des sources actives via le registry.
 */
export function getActiveSources(): ISource[] {
    return globalState.activeSources
        .map(name => sourceRegistry.get(name))
        .filter((source): source is ISource => source !== null);
}

/**
 * Met à jour le statut du site (offline/online) et charge les tendances de toutes les sources actives.
 */
export async function checkSiteStatus() {
    if (globalState.isCheckingStatus) return;
    globalState.isCheckingStatus = true;

    const sources = getActiveSources();
    if (sources.length === 0) {
        globalState.isSiteOffline = true;
        globalState.siteOfflineMessage = "Aucune source configurée.";
        globalState.trendingFilms = [];
        globalState.trendingSeries = [];
        globalState.recentItems = [];
        globalState.isCheckingStatus = false;
        return;
    }

    console.log(`[Vérification] Test de ${sources.length} sources actives...`);

    let allFilms: SearchResult[] = [];
    let allSeries: SearchResult[] = [];
    let allRecent: SearchResult[] = [];
    let onlineSourcesCount = 0;

    try {
        const results = await Promise.allSettled(sources.map(async (source) => {
            const limit = CONFIG.MAX_RESULTS_PER_SOURCE;
            const films = (await source.getTrending('movie')).slice(0, limit);
            const series = (await source.getTrending('series')).slice(0, limit);
            const recent = (source.getRecent ? await source.getRecent() : []).slice(0, limit);
            return { source, films, series, recent };
        }));

        for (const result of results) {
            if (result.status === 'fulfilled') {
                const { source, films, series, recent } = result.value;
                onlineSourcesCount++;
                
                // Mettre en cache les tendances de cette source
                sourceTrendsCache.set(source.name, { films: films || [], series: series || [], recent: recent || [] });
                
                if (films && films.length > 0) allFilms = allFilms.concat(films);
                if (series && series.length > 0) allSeries = allSeries.concat(series);
                if (recent && recent.length > 0) allRecent = allRecent.concat(recent);
                
                console.log(`[${source.name.toUpperCase()}] ${films?.length || 0} films, ${series?.length || 0} séries, ${recent?.length || 0} récents.`);
            } else if (result.status === 'rejected') {
                console.error(`[Erreur] Source indisponible: ${result.reason}`);
            }
        }

        // Déduplication par titre pour éviter les doublons entre les sources
        const deduplicate = (items: SearchResult[]) => {
            const seen = new Set<string>();
            const unique: SearchResult[] = [];
            for (const item of items) {
                if (!item.title) continue;
                const key = item.title.toLowerCase().replace(/[^a-z0-9]/g, '');
                if (!seen.has(key)) {
                    seen.add(key);
                    unique.push(item);
                }
            }
            return unique;
        };

        globalState.trendingFilms = await enrichSearchResults(deduplicate(allFilms));
        globalState.trendingSeries = await enrichSearchResults(deduplicate(allSeries));
        globalState.recentItems = await enrichSearchResults(deduplicate(allRecent));

        if (onlineSourcesCount > 0) {
            globalState.isSiteOffline = false;
            globalState.siteOfflineMessage = "";
        } else {
            globalState.isSiteOffline = true;
            globalState.siteOfflineMessage = "Toutes les sources actives sont indisponibles.";
        }
    } catch (error: any) {
        console.error(`[ERREUR FATALE] ${error.message}`);
        globalState.isSiteOffline = true;
        globalState.siteOfflineMessage = "Erreur lors de la vérification des sources.";
    } finally {
        globalState.isCheckingStatus = false;
        console.log("[Vérification] Terminée.");
    }
}

/**
 * Cache interne pour stocker les tendances de chaque source réussie.
 */
const sourceTrendsCache = new Map<string, { films: SearchResult[], series: SearchResult[], recent: SearchResult[] }>();

/**
 * Reconstruit globalState.trendingFilms, trendingSeries et recentItems à partir du cache
 * en respectant l'ordre de priorité défini dans globalState.activeSources.
 */
export async function rebuildTrendingFromCache() {
    let allFilms: SearchResult[] = [];
    let allSeries: SearchResult[] = [];
    let allRecent: SearchResult[] = [];

    const sources = getActiveSources();
    for (const source of sources) {
        const cached = sourceTrendsCache.get(source.name);
        if (cached) {
            if (cached.films && cached.films.length > 0) allFilms = allFilms.concat(cached.films);
            if (cached.series && cached.series.length > 0) allSeries = allSeries.concat(cached.series);
            if (cached.recent && cached.recent.length > 0) allRecent = allRecent.concat(cached.recent);
        }
    }

    const deduplicate = (items: SearchResult[]) => {
        const seen = new Set<string>();
        const unique: SearchResult[] = [];
        for (const item of items) {
            if (!item.title) continue;
            const key = item.title.toLowerCase().replace(/[^a-z0-9]/g, '');
            if (!seen.has(key)) {
                seen.add(key);
                unique.push(item);
            }
        }
        return unique;
    };

    globalState.trendingFilms = await enrichSearchResults(deduplicate(allFilms));
    globalState.trendingSeries = await enrichSearchResults(deduplicate(allSeries));
    globalState.recentItems = await enrichSearchResults(deduplicate(allRecent));
    console.log(`[Cache] Tendances reconstruites en mémoire pour ${sources.length} sources actives.`);
}
