// @ts-ignore
// @ts-ignore
/**工具 */
export const UtilsTool = {
  /**
   * 数字取整
   * @param num
   * @returns
   */
  numToInteger(num: number): number {
    return parseInt(String(num));
  },
  /**
   * 获取随机数
   * @param max 随机值
   * @param min 最小值
   * @returns
   */
  getRandNum(max: number, min = 0): number {
    return Number(Math.floor(Math.random() * max) + min);
  },
  /**
   * 获取一个正负随机数
   * @param num 随机值
   * @param min 最小值
   * @returns
   */
  getPlusOrMinusRandNum(num: number, min?: number): number {
    const arr = [1, -1];
    return Number(this.getRandNum(num, min) * arr[this.getRandNum(arr.length)]);
  },
  /**
   * 浅拷贝对象
   * @param data
   * @returns
   */
  shallowCloneObj(data: any) {
    if (Array.isArray(data)) {
      // @ts-ignore
      return [].concat(data);
    } else if (typeof data === 'object') {
      const _o = {};
      for (const key in data) {
        if (data[key]) {
          _o[key] = this.shallowCloneObj(data[key]);
        } else {
          _o[key] = data[key];
        }
      }
      return _o;
    } else {
      return data;
    }
  },
  /**
   * 获取第一个对象
   * @param data
   * @returns
   */
  getObjectFrist(data: any) {
    for (const e in data) {
      return data[e];
    }
  },
  /**转换装备信息 */
  coverEquipInfo(id: number) {
    return {
      type: UtilsTool.coverIDToSlice(id, 7) % 10,
      id: UtilsTool.coverIDToSlice(id, 5) % 100,
      star: UtilsTool.coverIDToSlice(id, 3) % 100,
      level: id % 1000,
    };
  },
  /**转换角色信息 */
  coverRoleInfo(id: number) {
    return {
      type: UtilsTool.coverIDToSlice(id, 8) % 100,
      evolution: UtilsTool.coverIDToSlice(id, 4) % 1000,
      level: UtilsTool.coverIDToSlice(id, 1) % 1000,
      break: id % 10,
    };
  },
  /**装备或者角色ID截取 */
  coverIDToSlice(id: number, len: number) {
    return Number(String(id).slice(0, String(id).length - len));
  },
  /**
   * 单位换算
   * @param num
   * @returns
   */
  unitConversion(num: number): string {
    const unitArr = ['K', 'M', 'B', 'T'];
    const coin = this.numToInteger(num).toString();
    let part = this.numToInteger((coin.length - 1) / 3);
    if (part > 0) {
      if (part > unitArr.length) {
        part = unitArr.length;
      }
      const result = Number(coin) / Math.pow(1000, part);
      const integerLen = this.numToInteger(result).toString().length;
      return result.toString().slice(0, integerLen + 3) + unitArr[part - 1];
    } else {
      return coin;
    }
  },
  /**
   * 获取一段随机字符串
   * @param len 长度
   * @returns
   */
  randomGetStr(len = 5): string {
    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    let txt = '';
    for (let i = 0; i < len; i++) {
      txt += chars.charAt(this.getRandNum(chars.length));
    }
    return txt;
  },
  /**
   * 获取对象长度
   * @param data
   * @returns
   */
  getObjectKey(data: {}): Array<any> {
    return Object.keys(data);
  },
  /**
   * 根据数字转成数组[0,n]
   * @param n
   * @returns
   */
  getNumArr(n: number): Array<number> {
    return Array.from(new Array(n).keys()).slice(-n);
  },
  /**
   * 数组转换为对象
   * @param arr
   * @param key 键值
   * @returns
   */
  coverArrToObject(arr: Array<any>, key: string): { [key: string]: any } {
    const data = {};
    if (arr) {
      arr.forEach((res: any) => {
        data[res[key]] = res;
      });
    }
    return data;
  },
  /**
   * 对象转换为数组
   * @param obj
   * @returns
   */
  coverObjToArr(obj: Object): any[] {
    const data = [];
    if (obj) {
      for (const e in obj) {
        // @ts-ignore
        data[data.length] = obj[e];
      }
    }
    return data;
  },
  /**
   * 数组转换为对象自定义参数
   * @param arr
   * @param call
   * @returns
   */
  coverArrToObjectCustom(arr: Array<any>, call: Function): { [key: string]: any } {
    const data = {};
    if (arr) {
      arr.forEach((msg: any) => {
        call(data, msg);
      });
    }
    return data;
  },
  /**
   * 对象过滤
   * @param data
   * @param call
   * @returns
   */
  filterToObject(data: { [key: string]: any }, call: Function): boolean {
    const arr = UtilsTool.getObjectKey(data);
    for (let i = 0; i < arr.length; i++) {
      if (call(data[arr[i]])) {
        return true;
      }
    }
    return false;
  },
  /**
   * 获取权重
   * @param arr
   * @param key 键值
   * @returns
   */
  getWeight(arr: any[], key: string): number {
    let num = 0;
    arr.forEach((msg: any) => {
      num += msg[key];
    });
    return num;
  },
  /**
   * 获取概率索引
   * @param arr
   * @param key 键值
   * @param num 权重
   * @returns
   */
  getRandIdx(arr: any[], key: string, num: number): number | void {
    let weight = 0;
    for (let i = 0; i < arr.length; i++) {
      weight += arr[i][key];
      if (num <= weight) return i;
    }
  },
  /**
   * 数组乱序
   * @param arr
   * @returns
   */
  randomSort(arr: any[]): Array<any> {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    arr.sort((_a: any, _b: any) => {
      return Math.random() > 0.5 ? -1 : 1;
    });
    return arr;
  },
  /**
   * 对比两个数组是否相等
   * @param arr1 数组1
   * @param arr2 数组2
   * @returns   是否相等
   */
  booleanEquals(arr1: any[], arr2: any[]): boolean {
    if (arr1.length == arr2.length) {
      for (let i = 0; i < arr1.length; i++) {
        if (arr1[i] != arr2[i]) {
          return false;
        }
      }
      return true;
    }
    return false;
  },
  /**
   * 限制长度
   * @param name
   * @param len
   * @returns
   */
  limitStrLen(name: string, len = 10): string {
    if (Boolean(name) && name.length > len) {
      return name.substring(0, len) + '...';
    } else {
      return name;
    }
  },
  /**
   * 字符串转流
   * @param str
   * @returns
   */
  stringToByte(str: any): ArrayBuffer {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i++) {
      bufView[i] = str.charCodeAt(i);
    }
    return buf;
  },
  /**
   * 流转字符串
   * @param buf
   * @returns
   */
  byteToString(buf: any): string {
    // @ts-ignore
    return String.fromCharCode.apply(null, new Uint8Array(buf));
  },
  /**
   * 字符串转码
   * @param data
   * @returns
   */
  decodeToStr(data: any): string {
    return decodeURIComponent(data);
  },
  /**
   * 获取当前时间戳到毫秒
   * @returns
   */
  getTimeToMsec(): number {
    return Date.now();
  },
  /**
   * 获取当前时间戳到秒
   * @returns
   */
  getTimeToSecond(): number {
    return Date.parse(String(new Date())) / 1000;
  },
  /**
   * 时间戳转周几
   * @param seconds 秒
   * @returns
   */
  coverTimeToWeek(seconds: number): number {
    const num = new Date(seconds * 1000).getDay();
    return num == 0 ? 7 : num;
  },
  /**
   * 时间戳转周几
   * @param seconds 秒
   * @returns
   */
  coverTimeToBigWeek(seconds: number): string | void {
    const num = new Date(seconds * 1000).getDay();
    switch (num) {
      case 1:
        return '星期一';
      case 2:
        return '星期二';
      case 3:
        return '星期三';
      case 4:
        return '星期四';
      case 5:
        return '星期五';
      case 6:
        return '星期六';
      case 7:
        return '星期日';
      default:
        break;
    }
  },
  /**
   * 转换时间显示
   * @param seconds 秒
   * @param showType "时" | "分" | "天" | "天时" | "-"
   * @returns
   */
  coverTimeToFormat(
    seconds: number,
    showType: '时' | '分' | '天' | '天时' | '-' = '时'
  ): string | void {
    const MathFloor = Math.floor;
    const day = MathFloor(seconds / 86400);
    const hour = MathFloor((seconds - day * 86400) / 3600);
    const min = MathFloor(seconds / 60) % 60;
    const sec = MathFloor(seconds % 60);
    switch (showType) {
      case '时':
        return this.coverTime(hour) + ':' + this.coverTime(min) + ':' + this.coverTime(sec);
      case '天时':
        return day + '天' + this.coverTime(hour) + '时';
      case '分':
        return this.coverTime(min) + ':' + this.coverTime(sec);
      case '天':
        return (
          day +
          '天' +
          this.coverTime(hour) +
          '时' +
          this.coverTime(min) +
          '分' +
          this.coverTime(sec) +
          '秒'
        );
    }
  },
  /**
   * 时间转年月日时分秒
   * @param date 时间戳
   * @param showType '-'
   * @returns
   */
  coverTimeToDay(
    date: number,
    showType: '时' | '分' | '天' | '天时' | '年' | '完整' = '时'
  ): string {
    const data = new Date(date * 1000);
    const year = data.getFullYear();
    const month = data.getMonth() + 1;
    const day = data.getDate();
    const hour = this.coverTime(data.getHours());
    const min = this.coverTime(data.getMinutes());
    const sec = this.coverTime(data.getSeconds());
    switch (showType) {
      case '时':
        return (
          this.coverTime(Number(hour)) +
          ':' +
          this.coverTime(Number(min)) +
          ':' +
          this.coverTime(Number(sec))
        );
      case '天时':
        return day + '天' + this.coverTime(Number(hour)) + '时';
      case '分':
        // @ts-ignore
        return this.coverTime(min) + ':' + this.coverTime(sec);
      case '天':
        // @ts-ignore
        // @ts-ignore
        // @ts-ignore
        // @ts-ignore
        // @ts-ignore
        return (
          day +
          '天' +
          this.coverTime(Number(hour)) +
          '时' +
          this.coverTime(Number(min)) +
          '分' +
          this.coverTime(Number(sec)) +
          '秒'
        );
      case '年':
        return year + '年' + month + '月' + day + '日';
      case '完整':
        return (
          year +
          '年' +
          this.coverTime(month) +
          '月' +
          this.coverTime(day) +
          '日' +
          ' ' +
          hour +
          ':' +
          min +
          ':' +
          sec +
          this.coverTimeToBigWeek(date)
        );
    }
  },
  /**
   * 时间格式化
   * @param m
   * @returns
   */
  coverTime(m: number): string {
    return m < 10 ? '0' + m : String(m);
  },
};
