import { useCallback, useMemo } from "react";
import { useDispatch } from "react-redux";
import { makeRe } from "minimatch";
import { endpoints as calEndpoints } from "@ledgerhq/cryptoassets/cal-client/state-manager/api";
import { accountToPlatformAccount, currencyToPlatformCurrency } from "./converters";
import { filterPlatformAccounts } from "./filters";
import { isPlatformSupportedCurrency } from "./helpers";
import { getParentAccount } from "../account";
import { listSupportedCurrencies } from "../currencies";
/**
 * TODO: we might want to use "searchParams.append" instead of "searchParams.set"
 * to handle duplicated query params (example: "?foo=bar&foo=baz")
 *
 * We can also use the stringify method of qs (https://github.com/ljharb/qs#stringifying)
 */
export function usePlatformUrl(manifest, inputs) {
    return useMemo(() => {
        const url = new URL(manifest.url.toString());
        if (inputs) {
            for (const key in inputs) {
                const value = inputs[key];
                if (Object.prototype.hasOwnProperty.call(inputs, key) && value !== undefined) {
                    url.searchParams.set(key, value);
                }
            }
        }
        if (manifest.params) {
            url.searchParams.set("params", JSON.stringify(manifest.params));
        }
        return url;
    }, [manifest.url, manifest.params, inputs]);
}
export function usePlatformAccounts(walletState, accounts) {
    return useMemo(() => {
        return accounts.map(account => {
            const parentAccount = getParentAccount(account, accounts);
            return accountToPlatformAccount(walletState, account, parentAccount);
        });
    }, [walletState, accounts]);
}
export function useListPlatformAccounts(walletState, accounts) {
    const platformAccounts = usePlatformAccounts(walletState, accounts);
    return useCallback((filters = {}) => {
        return filterPlatformAccounts(platformAccounts, filters);
    }, [platformAccounts]);
}
export function useListPlatformCurrencies(deactivatedCurrencyIds) {
    const dispatch = useDispatch();
    return useCallback(async (filters) => {
        const filterCurrencyRegexes = filters?.currencies
            ? filters.currencies.map(filter => makeRe(filter))
            : null;
        // 1. Gather all supported parent currencies
        const allCurrencies = listSupportedCurrencies().reduce((acc, c) => {
            if (isPlatformSupportedCurrency(c) && !deactivatedCurrencyIds.has(c.id))
                acc.push(currencyToPlatformCurrency(c));
            return acc;
        }, []);
        // 2. Determine which currencies to include based on patterns
        let includedCurrencies = allCurrencies;
        if (filterCurrencyRegexes) {
            includedCurrencies = allCurrencies.filter(c => {
                if (filterCurrencyRegexes && !filterCurrencyRegexes.some(regex => c.id.match(regex))) {
                    return false;
                }
                return true;
            });
        }
        if (filters?.includeTokens === false) {
            return includedCurrencies;
        }
        // 3. Determine which token families to fetch (only if not already fetched as specific tokens)
        const familiesToFetch = new Set();
        includedCurrencies.forEach(c => {
            if (c.type === "CryptoCurrency")
                familiesToFetch.add(c.family);
        });
        // 4. Fetch tokens for relevant families
        const fetchAllPagesForFamily = async (family) => {
            const args = { networkFamily: family, pageSize: 1000 };
            let hasNextPage = true;
            let data;
            while (hasNextPage) {
                const querySub = dispatch(calEndpoints.getTokensData.initiate(args, data ? { direction: "forward" } : undefined));
                try {
                    const result = await querySub;
                    data = result.data;
                    hasNextPage = result.hasNextPage;
                    if (result.error)
                        throw result.error;
                }
                finally {
                    querySub.unsubscribe();
                }
            }
            return (data?.pages ?? []).flatMap(p => p.tokens);
        };
        const tokensByFamily = await Promise.all([...familiesToFetch].map(f => fetchAllPagesForFamily(f)));
        // 5. Combine all results
        return tokensByFamily.reduce((acc, tokens) => {
            return tokens.reduce((tAcc, t) => {
                const pc = currencyToPlatformCurrency(t);
                if (!filterCurrencyRegexes || filterCurrencyRegexes.some(r => pc.id.match(r))) {
                    tAcc.push(pc);
                }
                return tAcc;
            }, acc);
        }, includedCurrencies);
    }, [deactivatedCurrencyIds, dispatch]);
}
//# sourceMappingURL=react.js.map