import { parse, stringify } from 'csv/dist/esm/sync';
import jschardet from 'jschardet';
import { uploadAssets } from 'utils/upload';
import http from 'utils/fetch';
import { api } from 'constants/config';

export type DataSourceType = {
  baseURL: string;
  description: string;
  id: string;
  name: string;
  type: string;
  updatedAt: string;
  encode: 'gbk' | 'utf-8' | 'auto';
};

export function fetchAndDecode(file) {
  return new Promise((resolve, reject) => {
    fetch(file, { method: 'GET', headers: { responseType: 'arraybuffer' } })
      .then((result) => {
        if (result.status === 200) {
          return result.arrayBuffer();
        } else if (result.status === 404) {
          resolve({ success: false, message: '文件不存在' });
        } else {
          resolve({ success: false, message: `${result.statusText}` });
        }
      })
      .then((result: ArrayBuffer) => {
        const reader = new FileReader();
        reader.onloadend = function (e: any) {
          const csvResult = e.target.result.split(/\r|\n|\r\n/);
          const encoding = jschardet.detect(csvResult.toString()).encoding;
          try {
            const dataView = new DataView(result);
            const decoder = new TextDecoder(encoding);
            const decodedString = decoder.decode(dataView);
            const parseData = parse(decodedString, { bom: true, relax_column_count_more: true });
            resolve({ success: true, data: parseData });
          } catch (error) {
            resolve({ success: false, message: `不支持解析${encoding}编码格式` });
          }
        };
        const blob = new Blob([result]);
        reader.readAsBinaryString(blob);
      })
      .catch((e) => {
        reject({ success: false, message: 'csv数据获取失败' });
      });
  });
}

export const uploadCsv = (
  data: any,
  path: string,
  baseInfo: Omit<DataSourceType, 'updatedAt' | 'encode' | 'type'>,
) => {
  const { id, description, name } = baseInfo;
  return new Promise<{ success: boolean; message: string }>((resolve, reject) => {
    const res = stringify(data, { bom: true });
    const blob = new Blob([res]);
    uploadAssets({ path, file: blob })
      .then(async (res) => {
        if (!res) {
          resolve({ success: false, message: '保存失败' });
        } else {
          const result = await http.post(api.sourceUpdate, {
            filePath: res,
            id,
            description,
            encode: 'auto',
            name,
            type: 'csv',
          });
          if (result) {
            resolve({ success: true, message: '保存成功' });
          } else {
            resolve({ success: false, message: '更新文件路径失败' });
          }
        }
      })
      .catch((e) => reject({ success: false, message: e }));
  });
};

export const mergeData: (data: Array<Array<string>>) => any[] = (data) => {
  return [
    {
      name: 'sheet1',
      freeze: 'A1',
      styles: [
        {
          color: '#fff',
          bgcolor: '#181A24',
          font: {
            italic: false,
            size: 9,
            bold: false,
          },
          textwrap: false,
          underline: false,
          valign: 'middle',
          align: 'center',
          border: {
            bottom: ['thin', '#34363F'],
            top: ['thin', '#34363F'],
            left: ['thin', '#34363F'],
            right: ['thin', '#34363F'],
          },
        },
      ],
      cols: { len: 100 },
      validations: [],
      autofilter: {},
      rows: data.reduce((pre, cur, index) => {
        return {
          ...pre,
          [index]: {
            cells: cur.reduce((p, c, i) => ({ ...p, [i]: { style: 0, text: c } }), {}),
          },
        };
      }, {}),
    },
  ];
};

/**
 * @description 将组件默认数据转化成excel可以处理的数据
 * @returns
 */
export const initDataToExcelData = (data: any) => {
  if (Array.isArray(data) && data.length) {
    const keys = Object.keys(data[0] || {});
    return data.reduce(
      (pre, cur) => {
        return [
          ...pre,
          keys.map((i) => {
            return cur[`${i}`];
          }),
        ];
      },
      [keys],
    );
  }
  return [];
};

/**
 * @description 将excel数据转化成组件可以接收的json数据格式
 * @param data
 */
export const excelDataToJson = (data: any) => {
  if (Array.isArray(data) && data.length) {
    const keys = data.slice(0, 1)[0];
    const values = data.slice(1, data.length);
    return values.map((item, index) => {
      // TODO 这里遍历的顺序时正常的生成object的时候，顺序不一样，注意修改
      return item.reduce((pre, cur, index) => {
        const k = keys[index];
        return { ...pre, [k]: cur };
      }, {});
    });
  }
  return [];
};

// 清除空列
export const filterExcelDataIsEmptyColumn = (data: Array<Array<string>>) => {
  if (Array.isArray(data) && data.length && Array.isArray(data[0])) {
    let gui = [];
    for (var i = 0; i < data[0].length; i++) {
      if (data[0][i]?.trim() === '') {
        for (var j = 1; j < data.length; j++) {
          if (data[0][i] != data[j][i]) {
            break;
          }
        }
        if (j === data.length) {
          gui.push(i);
        }
      }
    }
    const _data = data.reduce((pre, cur) => {
      return [...pre, cur.filter((d, i) => !gui.includes(i))];
    }, []);
    return _data;
  }
  return [];
};
