const unit8ArrayToChar = (array: Uint8Array) => {
  const len = array.length;
  let result = "";
  let i = 0;
  let char2;
  let char3;
  while (i < len) {
    const c = array[i++];
    /* eslint-disable no-bitwise */
    switch (c >> 4) {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
      case 7:
        result += String.fromCharCode(c);
        break;
      case 12:
      case 13:
        char2 = array[i++];
        result += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
        break;
      case 14:
        char2 = array[i++];
        char3 = array[i++];
        result += String.fromCharCode(
          ((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
          /* eslint-enable */
        );
        break;
      default:
        break;
    }
  }

  return result;
};

export default class CSVFormatter {
  /**
   * _csv csv 内容
   */
  private _csv: string = "";
  /**
   * _wordArray 文件中每一个单词的存储, row[column]
   */
  private _wordArray: string[][] = [[]];
  /**
   * _rowNum 当前行数 - 1
   */
  private _rowNum: number = 0;
  /**
   * _subStr 当前读入子字符
   */
  private _subStr: string = "";

  constructor() {}

  async loadFile(file?: any) {
    if (!file) throw new Error("CSVFormatter: file not exist.");
    const { value } = await file.stream().getReader().read();
    1;
    this._csv = unit8ArrayToChar(value);
  }

  async analyse(
    validator: (
      label: string,
      value: string,
      position: { row: number; column: number }
    ) => Promise<string>
  ): Promise<{ [key: string]: string }[]> {
    let result: { [key: string]: string }[] = [];
    // 去除空格, 并根据换行符和逗号分隔字符串
    for (const str of this._csv) {
      if (str === "\n") {
        this._wordArray[this._rowNum].push(this._subStr);
        this._subStr = "";
        this._wordArray.push([]);
        this._rowNum += 1;
        continue;
      } else {
        switch (str.trim()) {
          case ",":
            this._wordArray[this._rowNum].push(this._subStr);
            this._subStr = "";
            break;
          case "":
            break;
          default:
            this._subStr += str;
            break;
        }
      }
    }
    // 最后一段数据有可能没有换行符
    if (this._subStr) {
      this._wordArray[this._rowNum].push(this._subStr);
      this._subStr = "";
    }
    if (this._wordArray[this._rowNum].length === 0) {
      this._wordArray.pop();
    }
    for (let i = 1; i < this._wordArray.length; i++) {
      const row = this._wordArray[i];
      result.push({});

      for (let index = 0; index < row.length; index++) {
        const key = this._wordArray[0][index].trim();
        const validateRes = await validator(key, row[index], {
          row: i + 1,
          column: index + 1,
        });
        if (validateRes) {
          // 如果字符串不为空, 有错误信息, 抛出
          return Promise.reject(new Error(validateRes));
        }
        result[i - 1][key] = row[index];
      }
    }

    // 对内容做判断
    if (result.length === 0) {
      return Promise.reject(new Error("文件为空"));
    }

    return Promise.resolve(result);
  }
}
