import { useState } from 'react';
import { Modal } from 'antd';
import { giveFilePostDataInfoForTrue } from '@/webPublic/one_stop_public/Base16';
import { queryOauthActionPath } from '@/webPublic/one_stop_public/utils/queryConfig';
import { getToken } from '@/webPublic/one_stop_public/utils/token';
import { deepCopy } from '@/webPublic/zyd_public/utils/utils';
import { getTransformApi } from '@/webPublic/one_stop_public/2022beidianke/localstorageTransform';
import moment from 'moment';
import {
  getSassApiHeader,
  getSysCode
} from '@/webPublic/one_stop_public/2023yunshangguizhou/utils';

const apiUrl = queryOauthActionPath();
const exportStyles = {
  header: {
    font: {
      bold: false,
      fontHeightInPoints: 12,
    },
    alignment: 'CENTER',
    borderLeft: 'THIN',
    borderTop: 'THIN',
    borderBottom: 'THIN',
    borderRight: 'THIN',
    verticalAlignment: 'CENTER', //TOP、CENTER、BOTTOM、JUSTIFY、DISTRIBUTED
    wrapText: true,
    rowHeights: 20,
    colWidths: 250,
  },
  head: {
    font: {
      bold: true,
    },
    alignment: 'CENTER',
  },
};

const uj = {
  t: 1,
  v: '序号',
  s: 'header',
  w: 20 //默认值是20像素
};
/**
 * 公共函数代码
 *
 * */

/**
 * 列表获取纵向合并数据
 * mergeKey : 需要合并的表头key
 * data : 列表数据
 * eliminateRow : 列需要忽略合并的数据
 * eliminateCol : 行需要忽略合并的数据
 *
 * 返回值
 * rowSpanData 列合并数据，colSpanData行合并数据
 * */
export function getSpanJson({
  mergeKey = [],
  data,
  eliminateRow = [],
  eliminateCol = [],
  mergePrimaryRow,
  mergeMappingRow = {} // 某一列的合并数据 复制 到任意其他列
}) {

  const dataList = deepCopy(data);
  let rowSpanData, colSpanData = null;
  try {
    rowSpanData = getRowSpanJson(mergeKey, dataList, eliminateRow, mergePrimaryRow);
  } catch (err) {
    console.table("rowSpanData", err);
  }
  try {
    colSpanData = getColSpanJson(mergeKey, dataList, eliminateCol);
  } catch (err) {
    console.table("colSpanData", err);
  }
  try {
    const newMergeMappingRow = Object.keys(mergeMappingRow).filter(item1 => mergeKey.some(item2 => item2 === item1));
    newMergeMappingRow.map((item) => {
      const mappingList = mergeMappingRow[item].filter(item1 => !mergeKey.some(item2 => item2 === item1));
      mappingList.map((mItem) => {
        rowSpanData[mItem] = rowSpanData[item];
      });
    });
  } catch (e) {
    console.table("mergeMappingRow", e);
  }
  return {
    rowSpanData,
    colSpanData,
  };
}

function getRowSpanJson(cloumnNames, data, eliminateStr = [], mergePrimaryRow) {
  data = deepCopy(data);
  //纵向合并
  // 获取列的 dataIndex 集合
  var rowSpanJson = {};
  //保存上一个name
  var beforeNameMap = {};
  //相同name出现的次数
  var countMap = {};
  //该name第一次出现的位置
  var startIndexMap = {};
  // 是否主键模式
  var isPrimary = false;
  for (var idx = 0; idx < data.length; idx++) { // 循环数据
    var dataItem = data[idx];
    var dataItemRowValue;
    var dataItemPreviousRowValue;
    if (mergePrimaryRow) {
      isPrimary = true;//开启主键模式
      dataItemRowValue = dataItem[mergePrimaryRow];
      dataItemPreviousRowValue = data[idx - 1 > 0 ? idx - 1 : 0][mergePrimaryRow];
    }
    for (var idj = 0; idj < cloumnNames.length; idj++) { // 循环表头
      var keyItem = cloumnNames[idj];
      var dataItemValue = dataItem[keyItem];
      if (idx === 0) {
        beforeNameMap[keyItem] = dataItemValue;
        countMap[keyItem] = 1;
        startIndexMap[keyItem] = 0;
        rowSpanJson[keyItem] = new Array(data.length);
        rowSpanJson[keyItem][0] = 1;
        continue;
      }
      if (
        (!isPrimary ? (dataItemValue === beforeNameMap[keyItem]) : (dataItemRowValue + dataItemValue === dataItemPreviousRowValue + beforeNameMap[keyItem])) // 与上一个值一致时
        && eliminateStr.indexOf(dataItemValue) === -1 // 排除特定的值合并
      ) {
        countMap[keyItem] = countMap[keyItem] + 1;
        rowSpanJson[keyItem][startIndexMap[keyItem]] = countMap[keyItem];
        rowSpanJson[keyItem][idx] = 0;
      } else {
        countMap[keyItem] = 1;
        beforeNameMap[keyItem] = dataItemValue;
        startIndexMap[keyItem] = idx;
        rowSpanJson[keyItem][idx] = 1;
      }
    }
  }
  return rowSpanJson;
}

function getColSpanJson(cloumnNames, data, eliminateStr = []) {
  data = deepCopy(data);
  //横向合并
  var colSpanJson = {};
  for (let idx = 0; idx < data.length; idx++) {
    let dataItem = data[idx];
    let colSum = 1; //宽度
    let triggerColIndex = null; //记录触发时得位置
    let triggerColSum = 1; //记录触发时得位置
    let isCol = false;
    for (let idj = 0; idj < cloumnNames.length; idj++) {
      let keyItem = cloumnNames[idj];
      let dataItemValue = dataItem[keyItem];
      let dataItemValueNext = idj < cloumnNames.length - 1 ? dataItem[cloumnNames[idj + 1]] : null;
      if (idx === 0) {
        colSpanJson[keyItem] = new Array(data.length);
      }
      if (
        !isCol &&
        dataItemValue === dataItemValueNext &&
        eliminateStr.indexOf(dataItemValue) === -1
      ) {
        //触发合并
        triggerColIndex = keyItem;
        isCol = true;
      }
      if (isCol && (dataItemValue !== dataItemValueNext || dataItemValueNext == null)) {
        //合并结束
        isCol = false;
      }
      if (isCol) {
        //计数
        triggerColSum++;
      }
      if (!isCol && triggerColIndex !== null) {
        colSpanJson[triggerColIndex][idx] = triggerColSum;
        colSpanJson[keyItem][idx] = 0;
        triggerColIndex = null;
      } else if (isCol && triggerColIndex !== null) {
        colSpanJson[keyItem][idx] = 0;
      } else {
        colSpanJson[keyItem][idx] = colSum;
      }
    }
  }
  return colSpanJson;
}

/**
 * ant表头转换成二维数组对象。
 * columns : ant的表头
 *
 * 返回值
 * columnsList 基础数据
 * columnsMerges 合并数据
 * columnsKey key对应的列
 * columnsHeight 行数
 * */
export function getColumns(columns) {
  columns = deepCopy(columns);
  let columnsHeight = getColumnsMaxLevel(columns); //递归行数
  let columnsKey = [];
  const columnsList = new Array(columnsHeight).fill([]);
  let col = 1;
  for (var i in columnsList) {
    columnsList[i] = new Array(getColumnsWidth(columns)).fill({});
  }

  function getColumnsDatas(data = [], res = [], level = 1) {
    try {
      for (let item of data) {
        //item.key = i;
        let isLast = !item.children;
        item.level = level;
        item.isLast = isLast;
        item.width = !isLast ? getColumnsWidth(item.children) : 1;
        item.col = col;
        res.push(item);
        columnsList[level - 1][col - 1] = {
          ...uj,
          v: item.title,
        };
        if (!isLast) {
          if (Array.isArray(item.children)) {
            let x = level + 1;
            getColumnsDatas(item.children, res, x);
          }
        } else {
          col++;
          columnsKey.push(item['dataIndex']);
        }
      }
      return res;
    } catch (e) {
      console.table("getColumnsDatas", e);
      return [];
    }
  }

  //递归行数
  function getColumnsMaxLevel(arr = []) {
    //递归计算树形数据最大的层级数
    let maxLevel = 0;
    (function multiArr(arr, level = 0) {
      ++level;
      maxLevel = Math.max(level, maxLevel);
      for (let i = 0; i < arr.length; i++) {
        let item = arr[i];
        item.level = level;
        if (item.children && item.children.length > 0) {
          multiArr(item.children, level);
        } else {
          delete item.children;
        }
      }
    })(arr, 0);
    return maxLevel;
  }


  //递归当前数据宽度
  function getColumnsWidth(data = [], sum = 0) {
    for (let item of data) {
      if (!item.children) {
        sum++;
      } else {
        sum = getColumnsWidth(item.children, sum);
      }
    }
    return sum;
  }

  let columnsHandle = getColumnsDatas(columns)
    .filter((v, i) => {
      return (v.level < columnsHeight && v.isLast) || v.width > 1;
    });
  let columnsMerges = [];
  columnsHandle.forEach((v, i) => {
    let {
      isLast,
      width,
      col,
      level
    } = v;
    let nowCol = col - 1;
    let nowLevel = level - 1;
    if (isLast && width === 1) {
      //合并表格的 开始行、结束行、开始列、结束列
      columnsMerges.push([nowLevel, columnsHeight - 1, nowCol, nowCol]);
    }
    if (!isLast && width > 1) {
      columnsMerges.push([nowLevel, nowLevel, nowCol, nowCol + width - 1]);
    }
  });
  return {
    columnsList,
    columnsMerges,
    columnsKey,
    columnsHeight,
  };
}

/**
 *
 * @param {sqlKey,columns,styles,fileName,ext,allValues} param
 * 表头和sql数据导出（表头合并表格，数据不合并表格）
 * sqlKey : 数据sql编码
 * columns : ant表头基础数据
 * styles : 导出excl样式
 * fileName : 导出文件名
 * ext : 导出后缀 目前xecl、dbf
 * url : 接口地址
 */
export function getColumnsSqlKeyRealize({
  sqlKey,
  columns,
  styles,
  fileName = '导出文件',
  ext = 'xlsx',
  allValues = JSON.stringify({})
}) {
  columns = deepCopy(columns);

  let {
    columnsList,
    columnsMerges,
    columnsKey
  } = getColumns(columns);

  let content = {
    sheets: [
      {
        name: fileName,
        cells: columnsList,
        merges: columnsMerges,
        sqlKey: sqlKey, //sql编码
        sqlKeyHeader: columnsKey, //sql对应key对应列
      },
    ],
    styles: exportStyles
  };
  if (styles) {
    content.styles = styles;
  }
  try {
    let getFileData = giveFilePostDataInfoForTrue(
      {
        content: JSON.stringify(content),
        title: fileName,
        allValues: allValues
      },
      `${apiUrl + '/DataObjApi/exportCustom'}`,
    );
    let token = getToken();
    downloadFile(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      fileName,
      ext,
    );
  } catch (err) {
    console.table("getColumnsSqlKeyRealize", err);
  }
}


/**
 *
 * @param {sqlKey,columnsList,columnsMerges,columnsKey,styles,fileName,ext,allValues} param
 * 自定义表头和sql数据导出（表头合并表格，数据不合并表格）
 * sqlKey : 数据sql编码
 * columnsList
 * columnsMerges
 * columnsKey
 * styles : 导出excl样式
 * fileName : 导出文件名
 * ext : 导出后缀 目前xecl、dbf
 * url : 接口地址
 */
export function getCustomSqlKeyRealize({
  sqlKey,
  columnsList,
  columnsMerges,
  columnsKey,
  styles,
  fileName = '导出文件',
  ext = 'xlsx',
  allValues = JSON.stringify({})
}) {
  let content = {
    sheets: [
      {
        name: fileName,
        cells: columnsList,
        merges: columnsMerges,
        sqlKey: sqlKey, //sql编码
        sqlKeyHeader: columnsKey, //sql对应key对应列
      },
    ],
    styles: exportStyles
  };
  if (styles) {
    content.styles = styles;
  }
  try {
    let getFileData = giveFilePostDataInfoForTrue(
      {
        content: JSON.stringify(content),
        title: fileName,
        allValues: allValues
      },
      `${apiUrl + '/DataObjApi/exportCustom'}`,
    );
    let token = getToken();
    downloadFile(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      fileName,
      ext,
    );
  } catch (err) {
    console.table("getCustomSqlKeyRealize", err);
  }
}

/**
 *
 * @param {data,columns,styles,defect,fileName,ext,url,eliminateRow,eliminateCol} param
 * 表头和数据导出（合并表格）
 * data : ant基础数据
 * columns : ant表头基础数据
 * styles : 导出excl样式
 * defect : 为null时默认数据
 * fileName : 导出文件名
 * ext : 导出后缀 目前xecl、dbf
 * url : 接口地址
 * eliminateRow : 列需要忽略合并的数据
 * eliminateCol : 行需要忽略合并的数据
 *
 */
export function getColumnsDataRealize({
  data = [],
  mergeKey = [],
  columns,
  styles,
  defect = null,
  fileName = '导出文件',
  ext = 'xlsx',
  eliminateRow = [],
  eliminateCol = [],
  mergeMappingRow = {},// *映射mergeKey 纵向合并结果，key必须在mergeKey数组里面
  mergePrimaryRow,// 所有合并都会在当前mergePrimary 的范围下合并
}) {
  let content = getColumnsData({
    data,
    mergeKey,
    columns,
    styles,
    defect,
    fileName,
    ext,
    eliminateRow,
    eliminateCol,
    mergeMappingRow,// *映射mergeKey 纵向合并结果，key必须在mergeKey数组里面
    mergePrimaryRow,// 所有合并都会在当前mergePrimary 的范围下合并
  });
  if (styles) {
    content.styles = styles;
  }

  try {
    let getFileData = giveFilePostDataInfoForTrue(
      {
        content: JSON.stringify(content),
        title: fileName,
      },
      `${apiUrl + '/DataObjApi/exportCustom'}`,
    );
    let token = getToken();
    downloadFile(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      fileName,
      ext,
    );
  } catch (err) {
    console.table("getColumnsDataRealize", err);
  }

}


/**
 *
 * @param {data,columns,styles,defect,fileName,ext,url,eliminateRow,eliminateCol} param
 * 表头和数据导出（合并表格）
 * data : ant基础数据
 * columns : ant表头基础数据
 * styles : 导出excl样式
 * defect : 为null时默认数据
 * fileName : 导出文件名
 * ext : 导出后缀 目前xecl、dbf
 * url : 接口地址
 * eliminateRow : 列需要忽略合并的数据
 * eliminateCol : 行需要忽略合并的数据
 *
 */
export function getCustomDataRealize({
  data = [],
  mergeKey = [],
  columnsList = [],
  columnsMerges = [],
  columnsKey = [],
  bottomList = [],
  bottomMerges = [],
  styles,
  defect = null,
  fileName = '导出文件',
  ext = 'xlsx',
  eliminateRow = [],
  eliminateCol = [],
}) {
  let content = getCustomData({
    data,
    mergeKey,
    columnsList,
    columnsMerges,
    columnsKey,
    bottomList,
    bottomMerges,
    styles,
    defect,
    fileName,
    ext,
    eliminateRow,
    eliminateCol,
  });
  if (styles) {
    content.styles = styles;
  }

  try {
    let getFileData = giveFilePostDataInfoForTrue(
      {
        content: JSON.stringify(content),
        title: fileName,
      },
      `${apiUrl + '/DataObjApi/exportCustom'}`,
    );
    let token = getToken();
    downloadFile(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      fileName,
      ext,
    );
  } catch (err) {
    console.table("getCustomDataRealize", err);
  }

}
/**
 *
 * @param {data,columns,styles,defect,fileName,ext,url,eliminateRow,eliminateCol} param
 * 表头和数据导出（合并表格）
 * data : ant基础数据
 * columns : ant表头基础数据
 * styles : 导出excl样式
 * defect : 为null时默认数据
 * fileName : 导出文件名
 * ext : 导出后缀 目前xecl、dbf
 * url : 接口地址
 * eliminateRow : 列需要忽略合并的数据
 * eliminateCol : 行需要忽略合并的数据
 * mergeMappingRow : *映射mergeKey 纵向合并结果，key必须在mergeKey数组里面，value不可以在mergeKey里。
 * mergePrimary : 所有合并都会在当前mergePrimary 的范围下合并
 *
 */
export function getColumnsData({
  data = [],
  mergeKey = [],
  columns,
  styles,
  defect = null,
  fileName = '导出文件',
  ext = 'xlsx',
  eliminateRow = [],
  eliminateCol = [],
  docxSheet = {},
  mergeMappingRow = {},// *映射mergeKey 纵向合并结果，key必须在mergeKey数组里面
  mergePrimaryRow,// 所有合并都会在当前mergePrimary 的范围下合并
}) {
  columns = deepCopy(columns);
  data = deepCopy(data);
  let {
    columnsList,
    columnsMerges,
    columnsKey,
    columnsHeight
  } = getColumns(columns);
  let {
    colSpanData,
    rowSpanData
  } = getSpanJson({
    mergeKey,
    data,
    eliminateRow,
    eliminateCol,
    mergeMappingRow,
    mergePrimaryRow
  });
  // 处理数据
  let bodyData = [];
  let dataMerges = [];
  try {
    data.forEach((dv, di) => {
      let nowArroy = new Array(columnsKey.length).fill({});
      columnsKey.forEach((av, ai) => {
        nowArroy[ai] = {
          ...uj,
          v: av in dv && dv[av] != null ? dv[av].toString() : defect || '',
        };
      });
      bodyData.push(nowArroy);
    });
    // 处理合并数据
    let newMergeKey = mergeKey;
    try {
      const newMergeMappingRow = Object.keys(mergeMappingRow).filter(item1 => mergeKey.some(item2 => item2 === item1));
      newMergeMappingRow.map((item) => {
        const mappingList = mergeMappingRow[item].filter(item1 => !mergeKey.some(item2 => item2 === item1));
        newMergeKey = [...newMergeKey, ...mappingList];
      });
    } catch (e) {
      console.table("newMergeKey", e);
    }
    Object.keys(rowSpanData).forEach((mv) => {
      rowSpanData[mv].forEach((cv, ci) => {
        if (cv > 1) {
          //合并表格的 开始行、结束行、开始列、结束列
          let rowIndex = columnsKey.indexOf(mv);
          dataMerges.push([columnsHeight + ci, columnsHeight + ci + cv - 1, rowIndex, rowIndex]);
        }
      });
    })
    Object.keys(colSpanData).forEach((mv) => {
      colSpanData[mv].forEach((cv, ci) => {
        if (cv > 1) {
          //合并表格的 开始行、结束行、开始列、结束列
          let rowIndex = columnsKey.indexOf(mv);
          dataMerges.push([columnsHeight + ci, columnsHeight + ci, rowIndex, rowIndex + cv - 1]);
        }
      });
    })
  } catch (err) {
    console.table("getColumnsData", err);
  }
  let content = {
    sheets: [
      {
        name: fileName,
        cells: [...columnsList, ...bodyData],
        merges: [...columnsMerges, ...dataMerges],
      },
    ],
    styles: exportStyles
  };
  if (ext === "docx") {
    content.sheets[0] = {
      ...content.sheets[0],
      ...docxSheet
    }
  }
  if (styles) {
    content.styles = styles;
  }
  return content

}

/**
 *
 * @param {data,columns,styles,defect,fileName,ext,url,eliminateRow,eliminateCol} param
 * 表头和数据导出（合并表格）
 * data : ant基础数据
 * columns : ant表头基础数据
 * styles : 导出excl样式
 * defect : 为null时默认数据
 * fileName : 导出文件名
 * ext : 导出后缀 目前xecl、dbf
 * url : 接口地址
 * eliminateRow : 列需要忽略合并的数据
 * eliminateCol : 行需要忽略合并的数据
 *
 */
export function getCustomData({
  data = [],
  mergeKey = [],
  columnsList = [],
  columnsMerges = [],
  columnsKey = [],
  bottomList = [],
  bottomMerges = [],
  styles,
  defect = null,
  fileName = '导出文件',
  ext = 'xlsx',
  eliminateRow = [],
  eliminateCol = [],
  docxSheet = {},
}) {
  data = deepCopy(data);
  let columnsHeight = columnsList.length;
  let {
    colSpanData,
    rowSpanData
  } = getSpanJson({
    mergeKey,
    data,
    eliminateRow,
    eliminateCol
  });
  // 处理数据
  let bodyData = [];
  let dataMerges = [];
  try {
    data.forEach((dv, di) => {
      let nowArroy = new Array(columnsKey.length).fill({});
      columnsKey.forEach((av, ai) => {
        nowArroy[ai] = {
          ...uj,
          v: av in dv && dv[av] != null ? dv[av].toString() : defect || '',
        };
      });
      bodyData.push(nowArroy);
    });
    // 处理合并数据
    mergeKey.forEach((mv, mi) => {
      rowSpanData[mv].forEach((cv, ci) => {
        if (cv > 1) {
          //合并表格的 开始行、结束行、开始列、结束列
          let rowIndex = columnsKey.indexOf(mv);
          dataMerges.push([columnsHeight + ci, columnsHeight + ci + cv - 1, rowIndex, rowIndex]);
        }
      });
      colSpanData[mv].forEach((cv, ci) => {
        if (cv > 1) {
          //合并表格的 开始行、结束行、开始列、结束列
          let rowIndex = columnsKey.indexOf(mv);
          dataMerges.push([columnsHeight + ci, columnsHeight + ci, rowIndex, rowIndex + cv - 1]);
        }
      });
    });
  } catch (err) {
    console.table("getCustomData", err);
  }

  const columnsDataCells = [...columnsList, ...bodyData];
  const columnsDataMerges = [...columnsMerges, ...dataMerges];
  let newBottomMerges = [];
  if (bottomList && bottomList.length > 0) { // 新增底部数据
    if (columnsKey.length != bottomList[0].length) {
      console.table("bottomList数据列数和表头列数不一致");
      return
    }
    newBottomMerges = bottomMerges.map((v, i) => {
      let newV = v;
      //合并表格的 开始行、结束行、开始列、结束列
      newV[0] += columnsDataCells.length;
      newV[1] += columnsDataCells.length;
      return v;
    });
  }

  let content = {
    sheets: [
      {
        name: fileName,
        cells: [...columnsDataCells, ...bottomList],
        merges: [...columnsDataMerges, ...newBottomMerges],
      },
    ],
    styles: exportStyles
  };
  if (ext === "docx") {
    content.sheets[0] = {
      ...content.sheets[0],
      ...docxSheet
    }
  }
  if (styles) {
    content.styles = styles;
  }
  return content

}
// ant列表组件合并表格 render属性，合并纵向、横向。
export function renderContentAll(value, row, index, key, spanData, cloumnNames = []) {
  let colSpan,
    rowSpan = null;
  try {
    colSpan = spanData.colSpanData[key][index];// 横向合并
    rowSpan = spanData.rowSpanData[key][index];// 纵向合并
  } catch (err) {
    console.table("renderContentAll", err);
  }
  const obj = {
    children: value,
    props: {
      rowSpan: rowSpan,
      colSpan: colSpan
    }
  };
  return obj;
}

// ant列表组件合并表格 render属性，合并纵向。 meanwhileKey :key 是本身字段key，value 是同步的字段key
export function renderContentRow(value, row, index, key, spanData, cloumnNames = [], meanwhileKey = {}) {
  let colSpan,
    rowSpan = null;
  try {
    if (cloumnNames.indexOf(key) !== -1) {
      rowSpan = spanData.rowSpanData[key][index];// 纵向合并
    } else {
      if (key in meanwhileKey && meanwhileKey[key]) {
        let meanwhileKeyValue = meanwhileKey[key];
        rowSpan = spanData.rowSpanData[meanwhileKeyValue][index];// 同步字段 的纵向合并
      } else {
        rowSpan = 1;
      }
    }
  } catch (err) {
    console.table("renderContentRow", err);
  }
  const obj = {
    children: value,
    props: {
      rowSpan: rowSpan,
      colSpan: 1
    }
  };
  return obj;
}


/**
 * 表头和数据导出（合并表格）
 * templatePath : word文档模板地址
 * params : word文档的替换参数
 * title : 导出文件名
 * allValues : sql参数
 * listConfig : 导出列表配置
 * ext : 导出后缀 目前xecl、dbf,docx,pdf
 * 返回值
 * */
export function getWord({
  templatePath,
  params,
  title,
  allValues = {},
  listConfig = {},
  ext = 'docx',
}) {
  try {
    let getFileData = giveFilePostDataInfoForTrue(
      {
        templatePath: templatePath,
        params: JSON.stringify({
          ...listConfig,
          ...setObjectKey(params),
        }),
        title: `${title}.${ext}`,
        allValues: JSON.stringify({ ...allValues }),
      },
      apiUrl + `/DataColumnApi/exportWord`,
    );
    let token = getToken();
    downloadFile(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      title,
      ext,
    );
  } catch (err) {
    console.table(err);
  }

}


/**
 * 表头和数据导出（合并表格）
 * templatePath : word文档模板地址
 * params : word文档的替换参数
 * title : 导出文件名
 * allValues : sql参数
 * listConfig : 导出列表配置
 * ext : 导出后缀 目前xecl、dbf,docx,pdf
 * 返回值
 * */
export function getFileAndShow({
  templatePath,
  params,
  title,
  allValues = {},
  listConfig = {},
  ext = 'docx',
}) {
  try {
    let getFileData = giveFilePostDataInfoForTrue(
      {
        templatePath: templatePath,
        params: JSON.stringify({
          ...listConfig,
          ...setObjectKey(params),
        }),
        title: `${title}.${ext}`,
        allValues: JSON.stringify({ ...allValues }),
      },
      apiUrl + `/DataColumnApi/exportWord`,
    );
    let token = getToken();
    downloadFileAndShowModal(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      title,
      ext,
    );
  } catch (err) {
    console.table(err);
  }

}


/**
 * 表头和数据导出（合并表格）
 * templatePath : word文档模板地址
 * params : word文档的替换参数
 * title : 导出文件名
 * allValues : sql参数
 * listConfig : 导出列表配置
 * ext : 导出后缀 目前xecl、dbf,docx,pdf
 * 返回值
 * */

export function getListWord({
  templatePath,
  paramsList = [],
  title,
  sonTitleKey,
  allValuesKey = [],
  listConfig = {},
  ext = 'zip',
  sonExt = 'pdf',
  filesKey = []
}) {
  try {
    let content = [];
    paramsList.forEach((v, i) => {
      let files = [];
      let paramsObj = deepCopy(v);
      for (var ki in filesKey) {
        let files_ = v[filesKey[ki]];
        try {
          files = [...files, ...JSON.parse(files_).files]
        } catch (e) {

        }
        delete paramsObj[filesKey[ki]];
      }
      content.push({
        params: {
          ...setObjectKey(paramsObj),
          ...listConfig,
        },
        allValues: {
          ...getObjectsKey(allValuesKey, paramsObj)
        },
        title: (paramsObj[sonTitleKey] || "未设置名称") + `.${sonExt}`,
        files: JSON.stringify(files)
      });
    });
    let getFileData = giveFilePostDataInfoForTrue(
      {
        templatePath: templatePath,
        content: JSON.stringify(content),
        zipTitle: `${title}.${ext}`,
      },
      apiUrl + `/DataColumnApi/batchExportWord`,
    );

    let token = getToken();
    downloadFile(
      getFileData.url,
      {
        ...getFileData.datas,
        token: token,
      },
      title,
      ext,
    );
  } catch (err) {
    console.table(err);
  }
  function getObjectsKey(listKey = [], params = {}) {
    return (
      listKey
        .filter((key) => Object.keys(params).indexOf(key))
        .reduce(
          (acc, key) => ({
            ...acc,
            [key]: params[key] === null ? '' : params[key],
          }),
          {},
        )
    )
  }
}

function setObjectKey(data) {
  return (
    Object.keys(data)
      .reduce(
        (acc, key) => ({
          ...acc,
          ['${' + key + '}']: data[key] === null ? '' : data[key],
        }),
        {},
      )
  );
}

/**
 * 修改对象key
 * 支持对象、数组对象
 * @param {*} obj 数组对象或者对象
 * @param {*} setKey {"被修改的key":"修改后的key"}
 * @returns
 */
export function upObjKey(obj, setKey = {}, defaultValue = "") {
  try {
    obj = deepCopy(obj);
    setKey = deepCopy(setKey);
    let objType = Object.prototype.toString.call(obj);
    if (obj && (objType.indexOf("Array") > -1 || objType.indexOf("Object") > -1) && Object.keys(setKey).length > 0) {
      let nowObj = null;
      if (objType === "[object Object]" && !Array.isArray(obj) && Object.keys(obj).length > 0) {
        nowObj = deepCopy(obj);
        for (var e in setKey) {
          let upKey = setKey[e];
          let { newKey = e, type, timeFormat } = getSetKeyValue(upKey);
          nowObj = {
            ...nowObj,
            ...getSetKeyJson({
              obj, e, newKey, type, timeFormat, defaultValue
            })
          };
          if (e != newKey) {
            delete nowObj[e];
          }
        }
      }
      if (objType === "[object Array]" && Array.isArray(obj) && obj.length > 0) {
        nowObj = new Array();
        obj.forEach((v, i, arr) => {
          let newJson = deepCopy(v);
          for (var e in setKey) {
            let upKey = setKey[e];
            let { newKey = e, type, timeFormat } = getSetKeyValue(upKey);
            newJson = {
              ...newJson,
              ...getSetKeyJson({
                obj: v, e, newKey, type, timeFormat, defaultValue
              })
            };
            if (e != newKey) {
              delete newJson[e];
            }
          }
          nowObj.push(newJson);
        })
      }
      return nowObj;
    } else {
      return null;
    }
  } catch (error) {
    console.table("upObjKey", error);
    return undefined;
  }
}

function getSetKeyValue(value) {
  let valeuType = Object.prototype.toString.call(value);
  let newName = null;
  let extendJson = {
    "type": "string"
  };
  if (valeuType === "[object String]") {
    newName = value;
  }
  if (valeuType === "[object Object]") {
    newName = value["new"];
    delete value["new"];
    extendJson = {
      ...extendJson,
      ...value
    };
  }
  return {
    newKey: newName,
    ...extendJson
  }
}

function getSetKeyJson({
  obj, e, newKey, type, timeFormat = "YYYY-MM-DD HH:mm:ss", defaultValue
}) {
  obj = deepCopy(obj);
  let value = obj[e];
  let newKeyObj = {};
  // delete obj[e];
  switch (type) {
    case "time":
      newKeyObj[newKey] = (timeFormat && value ? moment(value).format(timeFormat) : value) || defaultValue;
      break;
    case "flow":
      newKeyObj[newKey] = {
        "code": value || defaultValue,
        "type": "flow"
      };
      break;
    default:
      newKeyObj[newKey] = value || defaultValue;
  }
  return newKeyObj;
}


// 下载附件FormdataWrapper
function isObject(value) {
  return value === Object(value);
}

function isArray(value) {
  return Array.isArray(value);
}

function isFile(value) {
  return value instanceof File;
}

function makeArrayKey(key) {
  return key;
}

function FormdataWrapper(obj, fd, pre) {
  fd = fd || new FormData();
  Object.keys(obj)
    .forEach(function (prop) {
      var key = pre ? pre + '[' + prop + ']' : prop;
      if (isObject(obj[prop]) && !isArray(obj[prop]) && !isFile(obj[prop])) {
        FormdataWrapper(obj[prop], fd, key);
      } else if (isArray(obj[prop])) {
        obj[prop].forEach(function (value) {
          var arrayKey = makeArrayKey(key);
          if (isObject(value) && !isFile(value)) {
            FormdataWrapper(value, fd, arrayKey);
          } else {
            fd.append(arrayKey, value);
          }
        });
      } else {
        if (obj[prop] != null) fd.append(key, obj[prop]);
      }
    });
  return fd;
}

export async function downloadFile(url, params, fileName = '导出文件', ext = 'xlsx') {
  const { transformApi, headersApi } = await getTransformApi(url);
  let headers = getSassApiHeader();
  // if(headersApi){
  //   headers.apis = headersApi;
  // }
  fetch(transformApi, {
    method: 'POST',
    body: FormdataWrapper(params),
    headers,
  })
    .then((res) => {
      if (res.status + '' !== '200') {
        return res.json();
      } else {
        return res.blob();
      }
    })
    .then((data) => {
      if (data instanceof Blob) {
        let a = document.createElement('a');
        let url = window.URL.createObjectURL(data);
        let filename = fileName + '.' + ext;
        a.href = url;
        a.download = filename;
        a.target = '_blank';
        a.click();
        window.URL.revokeObjectURL(url);
        a = null;
      } else {
      }
    })
    .catch((err) => {
      console.table(err);
    })
    .finally(() => {
      return true;
    });
}


export async function downloadFileAndShowModal(url, params, fileName = '导出文件', ext = 'xlsx') {
  const { transformApi, headersApi } = await getTransformApi(url);
  let headers = getSassApiHeader();
  // if(headersApi){
  //   headers.apis = headersApi;
  // }
  fetch(transformApi, {
    method: 'POST',
    body: FormdataWrapper(params),
    headers,
  })
    .then((res) => {
      if (res.status + '' !== '200') {
        return res.json();
      } else {
        return res.blob();
      }
    })
    .then((data) => {
      if (data instanceof Blob) {
        let url = window.URL.createObjectURL(data);
        let filename = fileName + '.' + ext;
        /**
         * 微软word 文档在线预览
         https://view.officeapps.live.com/op/view.aspx?src=
         https%3A%2F%2Fwww.longchang.gov.cn%2Flcs%2Fgsgg%2F202207%2F3ae45ccac65d40d885f40ec385ae287a%2Ffiles%2F%25E9%259A%2586%25E6%2598%258C%25E5%25B8%2582%25E7%25AC%25AC%25E5%2585%25AB%25E4%25B8%25AD%25E5%25AD%25A6%25E5%258E%2595%25E6%2589%2580%25E6%2594%25B9%25E9%2580%25A0%25E9%25A1%25B9%25E7%259B%25AE%25E5%2585%25AC%25E5%2591%258A.doc&wdOrigin=BROWSELINK
         * */
        Modal.info({
          title: filename,
          width: 1000,
          content: <div>
            <embed width='100%'
              height='568px'
              name='plugin'
              id='pdfView'
              src={url}
              type='application/pdf'

              internalinstanceid='3'
              title={filename} />
          </div>,
          okText: '确定',
          onCancel: () => {
            window.URL.revokeObjectURL(url);
          },
          onOk: () => {
            window.URL.revokeObjectURL(url);
          },
        });
      } else {
      }
    })
    .catch((err) => {
      console.table(err);
    })
    .finally(() => {
      return true;
    });
}
