import { generateSymbol, makeApiRequest, parseFullSymbol } from "./helpers";
const configurationData = {
    supported_resolutions: ["1D", "1W", "1M"],
    exchanges: [
        {
            value: "Bitfinex",
            name: "Bitfinex",
            desc: "Bitfinex",
        },
        {
            // `exchange` argument for the `searchSymbols` method, if a user selects this exchange
            value: "Kraken",
            // filter name
            name: "Kraken",
            // full exchange name displayed in the filter popup
            desc: "Kraken bitcoin exchange",
        },
    ],
    symbols_types: [
        {
            name: "crypto",
            // `symbolType` argument for the `searchSymbols` method, if a user selects this symbol type
            value: "crypto",
        },
        // ...
    ],
};
const getAllSymbols = async () => {
    const data = await makeApiRequest("data/v3/all/exchanges");
    let allSymbols = [];
    for (const exchange of configurationData.exchanges) {
        const pairs = data.Data[exchange.value].pairs;
        for (const leftPairPart of Object.keys(pairs)) {
            const symbols = pairs[leftPairPart].map((rightPairPart) => {
                const symbol = generateSymbol(exchange.value, leftPairPart, rightPairPart);
                return {
                    symbol: symbol.short,
                    full_name: symbol.full,
                    description: symbol.short,
                    exchange: exchange.value,
                    type: "crypto",
                };
            });
            allSymbols = [...allSymbols, ...symbols];
        }
    }
    return allSymbols;
};
const Datafeed = {
    onReady: async (callback) => {
        console.log("[onReady]: Method call");
        await callback(configurationData);
    },
    searchSymbols: async (userInput, exchange, symbolType, onResultReadyCallback) => {
        console.log("[searchSymbols]: Method call");
        const symbols = await getAllSymbols();
        const newSymbols = symbols
            .filter((symbol) => {
            const isExchangeValid = exchange === "" || symbol.exchange === exchange;
            const isFullSymbolContainsInput = symbol.full_name.toLowerCase().indexOf(userInput.toLowerCase()) !==
                -1;
            return isExchangeValid && isFullSymbolContainsInput;
        })
            .map((s) => ({ ...s, ticker: s.full_name }));
        onResultReadyCallback(newSymbols);
    },
    resolveSymbol: async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
        console.log("[resolveSymbol]: Method call", symbolName);
        const symbols = await getAllSymbols();
        console.log({ symbols });
        const symbolItem = symbols.find(({ full_name }) => full_name === symbolName);
        if (!symbolItem) {
            console.log("[resolveSymbol]: Cannot resolve symbol", symbolName);
            onResolveErrorCallback("cannot resolve symbol");
            return;
        }
        const symbolInfo = {
            full_name: symbolItem.full_name,
            listed_exchange: symbolItem.exchange,
            format: "price",
            ticker: symbolItem.full_name,
            name: symbolItem.symbol,
            description: symbolItem.description,
            type: symbolItem.type,
            session: "24x7",
            timezone: "Etc/UTC",
            exchange: symbolItem.exchange,
            minmov: 1,
            pricescale: 100,
            has_intraday: false,
            has_no_volume: true,
            has_weekly_and_monthly: false,
            supported_resolutions: configurationData.supported_resolutions,
            volume_precision: 2,
            data_status: "streaming",
        };
        console.log("[resolveSymbol]: Symbol resolved", symbolName);
        onSymbolResolvedCallback(symbolInfo);
    },
    getBars: async (symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) => {
        const { from, to, firstDataRequest } = periodParams;
        console.log("[getBars]: Method call", symbolInfo, resolution, from, to);
        const parsedSymbol = parseFullSymbol(symbolInfo.full_name);
        if (!parsedSymbol) {
            throw new Error("Parsed symbol not found");
        }
        const urlParameters = {
            e: parsedSymbol.exchange,
            fsym: parsedSymbol.fromSymbol,
            tsym: parsedSymbol.toSymbol,
            toTs: to,
            limit: 2000,
        };
        const query = Object.keys(urlParameters)
            .map((name) => `${name}=${encodeURIComponent(urlParameters[name])}`)
            .join("&");
        try {
            const data = await makeApiRequest(`data/histoday?${query}`);
            if ((data.Response && data.Response === "Error") ||
                data.Data.length === 0) {
                // "noData" should be set if there is no data in the requested period.
                onHistoryCallback([], { noData: true });
                return;
            }
            let bars = [];
            data.Data.forEach((bar) => {
                if (bar.time >= from && bar.time < to) {
                    bars = [
                        ...bars,
                        {
                            time: bar.time * 1000,
                            low: bar.low,
                            high: bar.high,
                            open: bar.open,
                            close: bar.close,
                        },
                    ];
                }
            });
            console.log(`[getBars]: returned ${bars.length} bar(s)`);
            onHistoryCallback(bars, { noData: false });
        }
        catch (error) {
            if (error instanceof Error) {
                console.log("[getBars]: Get error", error);
                onErrorCallback(error.toString());
            }
        }
    },
    subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
        console.log("[subscribeBars]: Method call with subscribeUID:", subscribeUID);
    },
    // @ts-ignore
    unsubscribeBars: (subscriberUID) => {
        console.log("[unsubscribeBars]: Method call with subscriberUID:", subscriberUID);
    },
};
export default Datafeed;
//# sourceMappingURL=datafeed.js.map