import { i18n } from "@/assets/lang";
import { iAsset } from "@/types/trade";
import { deCode } from "./prototype";
import { parseTransferNote } from "@33cn/chain33-transaction-parser";
import { yccDifferenceBlockRewardHeight } from "@/constant";

/**
 * 格式化时间
 *
 * @param {date} date
 * @param {string} format
 * @returns
 */
const formatTime = (date: any, format = "yyyy-MM-dd hh:mm:ss") => {
  if (!date) return "";
  if (typeof date === "number") {
    if (Math.floor(date / 1e9) > 0 && Math.floor(date / 1e9) < 10) {
      date = date * 1000;
    }
    date = new Date(date);
  } else if (typeof date === "string") {
    // timestamp in secounds
    if (/^\d{10}$/.test(date)) {
      date = new Date(Number(date) * 1000);
    } else {
      // ios 中使用 new Date( yyyy-MM-dd hh:mm:ss:SS ) 时间格式字符串不能精确到 小时以后
      const dateArr = date.split(/[- :]/);
      const now = new Date();
      date = new Date(
        Number(dateArr[0]) || now.getFullYear(),
        dateArr[1] && parseInt(dateArr[1])
          ? parseInt(dateArr[1]) - 1
          : now.getMonth() - 1,
        Number(dateArr[2]) || 1,
        Number(dateArr[3]) || 0,
        Number(dateArr[4]) || 0,
        Number(dateArr[5]) || 0
      );
    }
  } else {
    /* eslint-disable-next-line */
    console.error("wrong format", date);
    return "";
  }

  if (format === "timestamp") return +date;

  const map = {
    M: date.getMonth() + 1, // 月份
    d: date.getDate(), // 日
    h: date.getHours(), // 小时
    m: date.getMinutes(), // 分
    s: date.getSeconds(), // 秒
    q: Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
    W: "星期" + ["日", "一", "二", "三", "四", "五", "六"][date.getDay()], // 星期
  } as any;
  format = format.replace(/([yMdhmsqSW])+/g, function(all, t) {
    let v = map[t];
    if (v !== undefined) {
      if (all.length > 1) {
        v = "0" + v;
        v = v.substr(v.length - 2);
      }
      return v;
    } else if (t === "y") {
      return (date.getFullYear() + "").substr(4 - all.length);
    }
    return all;
  });
  return format;
};

const decodeTransferNote = (tx: any = {}) => {
  let payload: any = "";
  if (tx.execer === "user.p.xunku.storage") {
    return JSON.parse(`${deCode(tx.rawPayload)}`);
  }
  if (!tx.payload) return tx.rawPayload;
  else {
    payload = tx.payload;
  }
  const keys = ["transfer", "withdraw", "transferToExec"];
  const key = keys.find((item) => payload[item]);
  // console.log(tx.hash==='0x3589f747b41114854fa86953b22d840c1f41606960c79bc3640d4adaf7a5f96a')
  if (key && payload[key].note) {
    payload[key].note = parseTransferNote(payload[key].note);
  }
  // 基金会hash特殊处理
  if (
    tx.hash ===
      "0x3589f747b41114854fa86953b22d840c1f41606960c79bc3640d4adaf7a5f96a" &&
    key
  )
    payload[key].note = undefined;
  return payload;
};

//截断哈希
export default {
  filterHash: (str = "", num = 8): string => {
    return str.substring(0, num) + "..." + str.substring(str.length - 4);
  },
  filterMoney: (n: number): number => {
    return Number((n / 1e8).toFixed(2));
  },
  filterAmount: (n: number): number => {
    return n / 1e8;
  },
  /**
   * 获取交易中的价值
   * 强制非科学计数法
   * @param {object} tradeInfo
   */
  filterTradeValue: (tradeInfo: {
    amount: number;
    assets: iAsset[];
    actionName: string;
    tx: {
      execer: string;
    };
  }): string => {
    if (!tradeInfo.amount && !tradeInfo.assets) return `0 YCC`;
    // 燃烧或增发交易
    if (
      tradeInfo.actionName === "tokenBurn" ||
      tradeInfo.actionName === "tokenMint"
    )
      return "0 YCC";
    let res = `${tradeInfo.amount / 100000000} YCC`;
    if (
      tradeInfo.assets &&
      tradeInfo.assets.length !== 0 &&
      tradeInfo.assets[0].symbol
    ) {
      const amount = (tradeInfo.assets[0].amount || 0) / 100000000;
      const cointoken = tradeInfo.assets[0].symbol;
      if (
        cointoken === "ycc" ||
        (cointoken === "YCC" &&
          /^user\.p\.\w+\.coins$/.test(tradeInfo.assets[0].exec))
      )
        res = `${amount} para`;
      else res = `${amount} ${cointoken}`;
    }
    if (tradeInfo.tx && /^user\.p\.\w+\.coins$/.test(tradeInfo.tx.execer)) {
      let symbol = tradeInfo.tx.execer;
      const sLen = symbol.length - 13;
      symbol = symbol.substr(7, sLen);
      res = res + ` (${symbol})`;
    }
    return res;
  },
  filterNum: (num: number | string | null) => {
    if (!num || num === null || num === "") return;
    const n = String(num).split(".");
    const b = parseInt(n[0]).toString();
    const len = b.length;
    let result = "";
    if (len <= 3) {
      result = b;
    } else {
      const r = len % 3;
      result =
        r > 0
          ? b.slice(0, r) +
            "," +
            (b.slice(r, len).match(/\d{3}/g) || []).join(",")
          : (b.slice(r, len).match(/\d{3}/g) || []).join(",");
    }
    if (n[1]) {
      return result + `.${n[1]}`;
    } else {
      return result;
    }
  },
  filterBlockReward(num: string): string {
    return Number(num) > yccDifferenceBlockRewardHeight ? `15 YCC` : `30 YCC`;
  },
  filterVotePackReward(num: string): string {
    return Number(num) > yccDifferenceBlockRewardHeight
      ? `${i18n.t("lang.block.votingNode")} 5 +  ${i18n.t(
          "lang.block.packingNode"
        )} 3`
      : `${i18n.t("lang.block.votingNode")} 5 +  ${i18n.t(
          "lang.block.packingNode"
        )} 3`;
  },
  TradeValue: (tradeInfo: any): string => {
    if (!tradeInfo.amount && !tradeInfo.assets) return `0 YCC`;
    // 燃烧或增发交易
    if (
      tradeInfo.actionName === "tokenBurn" ||
      tradeInfo.actionName === "tokenMint"
    )
      return "0 YCC";
    let res = `${tradeInfo.amount / 100000000} YCC`;
    if (
      tradeInfo.assets &&
      tradeInfo.assets.length !== 0 &&
      tradeInfo.assets[0].symbol
    ) {
      const amount = (tradeInfo.assets[0].amount || 0) / 100000000;
      const cointoken = tradeInfo.assets[0].symbol;
      if (
        cointoken === "ycc" ||
        (cointoken === "YCC" &&
          /^user\.p\.\w+\.coins$/.test(tradeInfo.assets[0].exec))
      )
        res = `${amount} para`;
      else res = `${amount} ${cointoken}`;
    }
    if (tradeInfo.tx && /^user\.p\.\w+\.coins$/.test(tradeInfo.tx.execer)) {
      let symbol = tradeInfo.tx.execer;
      const sLen = symbol.length - 13;
      symbol = symbol.substr(7, sLen);
      res = res + ` (${symbol})`;
    }
    return res;
  },
  filterFee: (str: any) => {
    const token = process.env.VUE_APP_DEFAULT_COIN;
    if (token === undefined || token === "YCC") {
      return `${str / 100000000} YCC`;
    } else {
      return `${process.env.VUE_APP_FEE_TOTAL} ${token}`;
    }
  },
  formatTime,
  decodeTransferNote,
  caculateTime: (time: any) => {
    const Dt = new Date();
    const local = Dt.getTime();
    let dValue = parseInt(String(local / 1000 - time));
    const h = parseInt(String(dValue / 3600));
    dValue -= h * 3600;
    const m = parseInt(String(dValue / 60));
    dValue -= m * 60;
    const s = parseInt(String(dValue));
    if (parseInt(String(local / 1000 - time)) >= 86400) return formatTime(time);
    else if (parseInt(String(local / 1000 - time)) >= 3600)
      return `${h}${
        h == 1 ? i18n.t("components.hour") : i18n.t("components.hours")
      }${m}${
        m == 1 ? i18n.t("components.min") : i18n.t("components.mins")
      }${s}${s == 1 ? i18n.t("components.sec") : i18n.t("components.secs")}`;
    else if (parseInt(String(local / 1000 - time)) >= 60)
      return `${m}${
        m == 1 ? i18n.t("components.min") : i18n.t("components.mins")
      }${s}${s == 1 ? i18n.t("components.sec") : i18n.t("components.secs")}`;
    else
      return `${s}${
        s == 1 ? i18n.t("components.sec") : i18n.t("components.secs")
      }`;
  },
};
