import { ElMessage } from "element-plus";
import { utils, writeFile } from "xlsx";
import { httpExport, httpExportNoAdmin } from "/@/api/export";

type Options<T> = {
  //导出方式 http(网络请求) front(纯前端导出)
  type: "front" | "http";
  //type为http时需要url作为请求url
  url?: string;
  //type未http时请求的参数
  params?: any;
  //type为front时 需要传入导出的数据
  data?: T[];
  //ttpe为front时 需要传入导出的列
  columns: any[];
  //导出文件名
  name?: string;
  onSuccess?: () => void;
  onStart?: () => void;
  onFail?: () => void;
  admin: boolean
};

//要排除的列
const EXCLUDE_COLUMNS = ["序号", "操作"];

//纯前端导出
function frontEndExport<T>(
  _options: Pick<Options<T>, "data" | "columns" | "name">
) {
  const { data, columns, name } = _options;

  if (!data || !columns) return;
  if (data.length === 0) return ElMessage.warning("请打开勾选列并勾选导出数据");

  //生成表数据
  const result = generatorResult({ data, columns });
  const titleColumns: string[] = columns
    .map(({ label }) => label)
    .filter(label => label && !EXCLUDE_COLUMNS.includes(label));
  result.unshift(titleColumns);

  //生成表
  const workBook = utils.book_new();
  const workSheet = utils.aoa_to_sheet(result);

  utils.book_append_sheet(workBook, workSheet, "sheet1");

  //导出
  writeFile(workBook, name);
}

//配合后端文件流导出
export async function httpRequsetExport<T>(
  _options: Pick<
    Options<T>,
    "url" | "name" | "params" | "onSuccess" | "onStart" | "onFail" | 'admin'
  >
) {
  if (!_options.url) return;
  _options.onStart && _options.onStart();




  const api = _options.admin === false ? httpExportNoAdmin : httpExport
  const response = await api(_options.url, {
    ..._options.params
  }).catch(() => _options.onFail && _options.onFail());

  const { code } = response;

  if (Number(code) !== 0) {
    _options.onFail && _options.onFail();
  }

  if (response.type === "application/json") {
    ElMessage.warning("未找到数据");
    return;
  }

  ElMessage.warning("下载中,请稍等");
  if (code && Number(code) !== 0) {
    ElMessage.warning(response.message);
    return;
  }

  function handler() {
    const blob = new Blob([response], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    });
    const url = window.URL.createObjectURL(blob);
    //创建a标签 执行下载
    const link = document.createElement("a");
    link.style.display = "none";
    link.href = url;
    link.setAttribute("download", _options.name);
    //删除a标签 释放url
    document.body.appendChild(link);
    link.click();
    window.URL.revokeObjectURL(url);
    ElMessage.success("下载完成");
    _options.onSuccess && _options.onSuccess();
  }
  handler();
}

function generatorResult<T>({
  data,
  columns
}: Pick<Options<T>, "data" | "columns">): string[][] {
  return data.map(item => {
    const row: string[] = [];

    for (let i = 0; i < columns.length; i++) {
      const { prop, transform } = columns[i];
      if (!prop) continue;
      //存在transform时执行转换数据
      const colData = transform ? transform(item[prop]) : item[prop];
      row.push(colData);
    }
    return row;
  });
}

export function exportPageContent<T = any>({
  type,
  url,
  columns,
  data,
  name: _name
}: Options<T>) {
  const name = _name ? _name : "导出数据.xlsx";
  switch (type) {
    case "front":
      frontEndExport({ data, columns, name });
      break;
    case "http":
      httpRequsetExport({ url, name });
      break;
  }
}
