import React, { useContext, useEffect, createContext, useMemo, useState, useCallback } from "react";
import api from "./api";
import useIsMounted from "../../../hooks/useIsMounted";
import useEnv from "../../../hooks/useEnv";
const initialState = {
    isLoading: false,
    value: null,
    error: null,
};
const initialProvider = "production";
const initialParams = {
    branches: ["stable", "soon"],
};
export const liveAppContext = createContext({
    state: initialState,
    provider: initialProvider,
    setProvider: () => { },
    updateManifests: () => Promise.resolve(),
});
export function useRemoteLiveAppManifest(appId) {
    const liveAppRegistry = useContext(liveAppContext).state;
    if (!liveAppRegistry.value || !appId) {
        return undefined;
    }
    return (liveAppRegistry.value.liveAppFilteredById[appId] || liveAppRegistry.value.liveAppById[appId]);
}
export function useRemoteLiveAppContext() {
    return useContext(liveAppContext);
}
export function useManifests(options = {}) {
    const ctx = useRemoteLiveAppContext();
    return useMemo(() => {
        const liveAppFiltered = ctx.state?.value?.liveAppFiltered ?? [];
        if (Object.keys(options).length === 0) {
            return liveAppFiltered;
        }
        return liveAppFiltered.filter(manifest => Object.entries(options).some(([key, val]) => {
            switch (key) {
                case "visibility":
                    return val.includes(manifest[key]);
                default:
                    return manifest[key] === val;
            }
        }));
    }, [options, ctx]);
}
export function RemoteLiveAppProvider({ children, parameters, updateFrequency, }) {
    const isMounted = useIsMounted();
    const [state, setState] = useState(initialState);
    const [provider, setProvider] = useState(initialProvider);
    const { allowExperimentalApps, allowDebugApps, apiVersions, platform, llVersion, lang } = parameters;
    // apiVersion renamed without (s) because param
    const apiVersion = apiVersions ? apiVersions : ["1.0.0", "2.0.0"];
    const envProviderURL = useEnv("PLATFORM_MANIFEST_API_URL");
    const providerURL = provider === "production" ? envProviderURL : provider;
    const updateManifests = useCallback(async () => {
        setState(currentState => ({
            ...currentState,
            isLoading: true,
            error: null,
        }));
        const branches = [...(initialParams.branches || [])];
        allowExperimentalApps && branches.push("experimental");
        allowDebugApps && branches.push("debug");
        try {
            const allManifests = await api.fetchLiveAppManifests(providerURL);
            const catalogManifests = await api.fetchLiveAppManifests(providerURL, {
                apiVersion,
                branches,
                platform,
                private: false,
                llVersion,
                lang: lang ? lang : "en",
            });
            if (!isMounted())
                return;
            setState(() => ({
                isLoading: false,
                value: {
                    liveAppByIndex: allManifests,
                    liveAppFiltered: catalogManifests,
                    liveAppFilteredById: catalogManifests.reduce((acc, liveAppManifest) => {
                        acc[liveAppManifest.id] = liveAppManifest;
                        return acc;
                    }, {}),
                    liveAppById: allManifests.reduce((acc, liveAppManifest) => {
                        acc[liveAppManifest.id] = liveAppManifest;
                        return acc;
                    }, {}),
                },
                error: null,
            }));
        }
        catch (error) {
            if (!isMounted())
                return;
            setState(currentState => ({
                ...currentState,
                isLoading: false,
                error,
            }));
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [allowDebugApps, allowExperimentalApps, providerURL, lang, isMounted]);
    const value = useMemo(() => ({
        state,
        provider,
        setProvider,
        updateManifests,
    }), [state, provider, setProvider, updateManifests]);
    useEffect(() => {
        const interval = setInterval(() => {
            updateManifests();
        }, updateFrequency);
        updateManifests();
        return () => {
            clearInterval(interval);
        };
    }, [updateFrequency, updateManifests]);
    return React.createElement(liveAppContext.Provider, { value: value }, children);
}
//# sourceMappingURL=index.js.map