import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import { coinCodexBaseUrl, keplrCurrencies } from "./currency.constants";
import { fetchTokenHistory, fetchTokenInfo } from "./currency.utils";
export const findTokenFromDenom = denom => {
  if (!(denom !== null && denom !== void 0 && denom.length)) return;
  const denomLowerCased = denom === null || denom === void 0 ? void 0 : denom.toLowerCase();
  const token = keplrCurrencies[denomLowerCased];
  if (token) return token;
  const denomUpperCased = denom === null || denom === void 0 ? void 0 : denom.toUpperCase();
  const possibleToken = Object.values(keplrCurrencies).find(currency => currency.coinMinimalDenom === denom || currency.coinDenom === denom || currency.coinMinimalDenom === denomLowerCased || currency.coinDenom === denomLowerCased || currency.coinMinimalDenom === denomUpperCased || currency.coinDenom === denomUpperCased);
  return possibleToken;
};
export const findIbcTokenFromHash = (() => {
  const cache = {};
  return async (queryClient, ibcHash) => {
    var _response$denomTrace;
    if (!queryClient) throw new Error("Invalid query client");
    const hash = ibcHash.replace(/^ibc\//i, "");
    if (cache[hash]) return cache[hash];
    const response = await queryClient.ibc.applications.transfer.v1.denomTrace({
      hash
    });
    if (!((_response$denomTrace = response.denomTrace) !== null && _response$denomTrace !== void 0 && _response$denomTrace.baseDenom)) return;
    const token = findTokenFromDenom(response.denomTrace.baseDenom);
    const result = {
      ibc: _objectSpread(_objectSpread({}, response.denomTrace), {}, {
        hash
      }),
      token
    };
    cache[hash] = result;
    return result;
  };
})();
export const findIbcTokensFromHashes = async (queryClient, ibcHashes) => {
  if (!queryClient) throw new Error("Invalid query client");
  const requests = ibcHashes.map(ibcHash => findIbcTokenFromHash(queryClient, ibcHash));
  const responses = await Promise.allSettled(requests);
  const results = responses.map(response => {
    if (response.status !== "fulfilled") return;
    return response.value;
  });
  return results;
};

/**
 * LOCAL USE ONLY
 * Fetch a list of currencies as defined in keplr chain registry:
 * https://github.com/chainapsis/keplr-chain-registry/tree/main/cosmos
 */
// export const fetchAllCurrenciesInKeplrChainRegistry = async () => {
//   const fetchKeplrChainInfo = async (chainName: string) => {
//     try {
//       const url = `https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/cosmos/${chainName}.json`;
//       const response = await axios.get(url);
//       return response.data as KeplrChainInfo;
//     } catch (error) {
//       return {} as KeplrChainInfo;
//     }
//   };

//   const responses = await Promise.allSettled(
//     keplrChainNames.map((chainName) => fetchKeplrChainInfo(chainName))
//   );
//   let chainInfos = responses
//     .filter((x) => x.status === "fulfilled")
//     // @ts-ignore
//     .map((x) => x.value);
//   chainInfos = chainInfos.map(prepareKeplrChainInfoTokenAssets);
//   let currencies = chainInfos
//     .map((chainInfo: KeplrChainInfo): TokenAsset[] => chainInfo.currencies)
//     .flat();
//   return currencies.reduce((result, value) => {
//     if (!result[value.coinMinimalDenom])
//       return { ...result, [value.coinMinimalDenom]: value };
//     return {
//       ...result,
//       [value.coinMinimalDenom]: { ...result[value.coinMinimalDenom], ...value },
//     };
//   }, {});
// };

export const findTokenInfoFromDenom = (() => {
  const cache = {};
  return async (denom, cacheResult = true, baseUrl = coinCodexBaseUrl) => {
    var _cache$denom, _token$coinCodexId;
    if (!denom) return;
    const token = findTokenFromDenom(denom);
    if (cacheResult && (cache[denom] || cache[token === null || token === void 0 ? void 0 : token.coinCodexId])) return (_cache$denom = cache[denom]) !== null && _cache$denom !== void 0 ? _cache$denom : cache[token === null || token === void 0 ? void 0 : token.coinCodexId];
    let coinCodexTokenInfo = await fetchTokenInfo((_token$coinCodexId = token === null || token === void 0 ? void 0 : token.coinCodexId) !== null && _token$coinCodexId !== void 0 ? _token$coinCodexId : denom, baseUrl);
    if (!coinCodexTokenInfo) return;
    const result = {
      symbol: coinCodexTokenInfo.symbol,
      coinName: coinCodexTokenInfo.coin_name,
      shortname: coinCodexTokenInfo.shortname,
      slug: coinCodexTokenInfo.slug,
      displaySymbol: coinCodexTokenInfo.display_symbol,
      todayOpen: coinCodexTokenInfo.today_open,
      lastPriceUsd: coinCodexTokenInfo.last_price_usd,
      priceChangePercent: {
        "1H": coinCodexTokenInfo.price_change_1H_percent,
        "1D": coinCodexTokenInfo.price_change_1D_percent,
        "7D": coinCodexTokenInfo.price_change_7D_percent,
        "30D": coinCodexTokenInfo.price_change_30D_percent,
        "90D": coinCodexTokenInfo.price_change_90D_percent
      },
      lastUpdate: coinCodexTokenInfo.last_update,
      social: coinCodexTokenInfo.social
    };
    if (cacheResult) cache[denom] = result;
    return result;
  };
})();
export const findTokensInfoFromDenoms = async denoms => {
  const requests = denoms.map(d => findTokenInfoFromDenom(d));
  const responses = await Promise.allSettled(requests);
  const results = responses.map(response => {
    if (response.status !== "fulfilled") return;
    return response.value;
  });
  return results;
};
export const findTokenHistoryFromDenom = (() => {
  const cache = {};
  return async (denom, startDate, endDate, samples = 100, cacheResult = true, baseUrl = coinCodexBaseUrl) => {
    var _cache$denom2, _token$coinCodexId2, _, _Object$values;
    if (!denom) return;
    const token = findTokenFromDenom(denom);
    if (cacheResult && (cache[denom] || cache[token === null || token === void 0 ? void 0 : token.coinCodexId])) return (_cache$denom2 = cache[denom]) !== null && _cache$denom2 !== void 0 ? _cache$denom2 : cache[token === null || token === void 0 ? void 0 : token.coinCodexId];
    let coinCodexTokenHistory = await fetchTokenHistory((_token$coinCodexId2 = token === null || token === void 0 ? void 0 : token.coinCodexId) !== null && _token$coinCodexId2 !== void 0 ? _token$coinCodexId2 : denom, startDate, endDate, samples, baseUrl);
    if (!coinCodexTokenHistory) return;
    const result = (_ = ((_Object$values = Object.values(coinCodexTokenHistory)) !== null && _Object$values !== void 0 ? _Object$values : [[]])[0]) === null || _ === void 0 ? void 0 : _.map(v => ({
      timestamp: v[0],
      usdPrice: v[1],
      usdVolume24H: v[2]
    }));
    if (cacheResult) cache[denom] = result;
    return result;
  };
})();
export const findTokensHistoryFromDenoms = async (denoms, startDate, endDate, samples = 100, cacheResult = true) => {
  const requests = denoms.map(d => findTokenHistoryFromDenom(d, startDate, endDate, samples, cacheResult));
  const responses = await Promise.allSettled(requests);
  const results = responses.map(response => {
    if (response.status !== "fulfilled") return;
    return response.value;
  });
  return results;
};