export const generateId = (length = 12) => {
  var result = "";
  var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  var charactersLength = characters.length;
  for (var i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
};
export const getValueFromEvents = (res, event, attribute, filterFunc = s => s, logError, throwError, messageIndex = 0) => {
  try {
    let value;
    // from cosmos-sdk v0.50 onwards, rawLog is not available, events is separate
    if (res.events) {
      var _res$events$find, _res$events$find$attr;
      value = (_res$events$find = res.events.find(e => {
        var _e$attributes$find, _e$attributes$find2;
        // first check if type is correct
        const isType = e.type === event;
        if (!isType) return false;

        // then check if attributes contains correct msg_index
        const msgIndexAttribute = (_e$attributes$find = e.attributes.find(a => a.key === "msg_index")) === null || _e$attributes$find === void 0 ? void 0 : _e$attributes$find.value;
        if (msgIndexAttribute === undefined || msgIndexAttribute !== messageIndex.toString()) return false;

        // finally check if attribute is present
        const isAttribute = (_e$attributes$find2 = e.attributes.find(a => a.key === attribute)) === null || _e$attributes$find2 === void 0 ? void 0 : _e$attributes$find2.value;
        if (isAttribute === undefined) return false;
        return true;
      })) === null || _res$events$find === void 0 ? void 0 : (_res$events$find$attr = _res$events$find.attributes) === null || _res$events$find$attr === void 0 ? void 0 : _res$events$find$attr.find(a => a.key === attribute).value;

      // if no value it could be for chain pre v0.50 where events doesn't include msgIndex
      if (!value) {
        var _res$events$find2, _res$events$find2$att;
        value = (_res$events$find2 = res.events.find(e => {
          var _e$attributes$find3;
          // first check if type is correct
          const isType = e.type === event;
          if (!isType) return false;

          // finally check if attribute is present
          const isAttribute = (_e$attributes$find3 = e.attributes.find(a => a.key === attribute)) === null || _e$attributes$find3 === void 0 ? void 0 : _e$attributes$find3.value;
          if (isAttribute === undefined) return false;
          return true;
        })) === null || _res$events$find2 === void 0 ? void 0 : (_res$events$find2$att = _res$events$find2.attributes) === null || _res$events$find2$att === void 0 ? void 0 : _res$events$find2$att.find(a => a.key === attribute).value;
      }
    } else {
      var _JSON$parse$messageIn, _JSON$parse$messageIn2, _JSON$parse$messageIn3, _JSON$parse$messageIn4, _JSON$parse$messageIn5;
      value = (_JSON$parse$messageIn = JSON.parse(res.rawLog)[messageIndex]) === null || _JSON$parse$messageIn === void 0 ? void 0 : (_JSON$parse$messageIn2 = _JSON$parse$messageIn.events) === null || _JSON$parse$messageIn2 === void 0 ? void 0 : (_JSON$parse$messageIn3 = _JSON$parse$messageIn2.find(e => e.type === event)) === null || _JSON$parse$messageIn3 === void 0 ? void 0 : (_JSON$parse$messageIn4 = _JSON$parse$messageIn3.attributes) === null || _JSON$parse$messageIn4 === void 0 ? void 0 : (_JSON$parse$messageIn5 = _JSON$parse$messageIn4.find(e => e.key === attribute)) === null || _JSON$parse$messageIn5 === void 0 ? void 0 : _JSON$parse$messageIn5.value;
    }
    let filteredValue;
    try {
      filteredValue = filterFunc(JSON.parse(value));
    } catch (error) {
      filteredValue = filterFunc(value);
    }
    return filteredValue;
  } catch (error) {
    if (logError) console.error({
      error,
      res
    });
    if (throwError) throw error;
  }
};

// Iterator function to help run getValueFromEvents with multiple messages
export const getValuesFromEvents = (res, event, attribute, filterFunc = s => s, logError, throwError) => {
  try {
    return res.msgResponses.map((_, i) => getValueFromEvents(res, event, attribute, filterFunc, logError, throwError, i));
  } catch (error) {
    if (logError) console.log({
      error,
      res
    });
    if (throwError) throw error;
  }
};