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';

const apiUrl = queryOauthActionPath();

/**
 * 公共函数代码
 *
 * */

/**
 * 列表获取纵向合并数据
 * mergeKey : 需要合并的表头key
 * data : 列表数据
 * eliminateRow : 列需要忽略合并的数据
 * eliminateCol : 行需要忽略合并的数据
 *
 * 返回值
 * rowSpanData 列合并数据，colSpanData行合并数据
 * */
export function getSpanJson({
                              mergeKey,
                              data,
                              eliminateRow = [],
                              eliminateCol = []
                            }) {

  try {
    let dataList = deepCopy(data);
    return {
      rowSpanData: getRowSpanJson(mergeKey, dataList, eliminateRow),
      colSpanData: getColSpanJson(mergeKey, dataList, eliminateCol),
    };
  } catch (err) {
    console.table(err);
  }
}

function getRowSpanJson(cloumnNames, data, eliminateStr = []) {
  data = deepCopy(data);
  //纵向合并
  // 获取列的 dataIndex 集合
  var rowSpanJson = {};
  //保存上一个name
  var beforeNameMap = {};
  //相同name出现的次数
  var countMap = {};
  //该name第一次出现的位置
  var startIndexMap = {};
  for (var idx = 0; idx < data.length; idx++) {
    var dataItem = data[idx];
    for (var idj = 0; idj < cloumnNames.length; idj++) {
      var keyItem = cloumnNames[idj];
      var dataItemValue = dataItem[keyItem];
      if (idx === 0) {
        beforeNameMap[keyItem] = dataItem[keyItem];
        countMap[keyItem] = 1;
        startIndexMap[keyItem] = 0;
        rowSpanJson[keyItem] = new Array(data.length);
        rowSpanJson[keyItem][0] = 1;
        continue;
      }
      if (dataItemValue === 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;
      //console.log("dataItemValue",dataItemValue,idj)
      if (idx === 0) {
        colSpanJson[keyItem] = new Array(getRowSpanJson.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;
      }
    }
  }
  //console.log("colSpanJson",colSpanJson)
  return colSpanJson;
}

/**
 * ant表头转换成二维数组对象。
 * columns : ant的表头
 *
 * 返回值
 * columnsList 基础数据
 * columnsMerges 合并数据
 * columnsKey key对应的列
 * columnsHeight 行数
 * */
export function getColumns(columns) {
  columns = deepCopy(columns);

  const uj = {
    t: 1,
    v: '序号',
    s: 'header',
  };
  let columnsHeight = 0;
  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 getColumnsData(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;
            getColumnsData(item.children, res, x);
          }
        } else {
          col++;
          columnsKey.push(item['dataIndex']);
        }
      }
      return res;
    } catch (e) {
      debugger;
      console.table(e);
      return false;
    }
  }

  //递归行数
  function getColumnsMaxLevel(data = [], level = 1) {
    for (let item of data) {
      let isLast = !item.children;
      if (!isLast && Array.isArray(item.children)) {
        let x = level + 1;
        if (columnsHeight < x) {
          columnsHeight = x;
        }
        getColumnsMaxLevel(item.children, x);
      } else {
        columnsHeight += 1;
      }
    }
    return level;
  }

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

  let columnsHandle = getColumnsData(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对应列
        allValues:allValues
      },
    ],
    styles: {
      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',
      },
    },
  };
  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(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 = [],
                                      }) {
  columns = deepCopy(columns);
  data = deepCopy(data);
  let {
    columnsList,
    columnsMerges,
    columnsKey,
    columnsHeight
  } = getColumns(columns);
  let {
    colSpanData,
    rowSpanData
  } = getSpanJson({
    mergeKey,
    data,
    eliminateRow,
    eliminateCol
  });
  // 处理数据
  let bodyData = [];
  let dataMerges = [];
  const uj = {
    t: 1,
    v: '序号',
    s: 'header',
  };
  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(err);
  }


  let content = {
    sheets: [
      {
        name: fileName,
        cells: [...columnsList, ...bodyData],
        merges: [...columnsMerges, ...dataMerges],
      },
    ],
    styles: {
      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',
      },
    },
  };
  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(err);
  }

}

// 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(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(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);
  }

  //可更新的

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


/**
 * 表头和数据导出（合并表格）
 * 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);
  }

  //可更新的

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


// 下载附件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 function downloadFile(url, params, fileName = '导出文件', ext = 'xlsx') {
  // console.log("downloadFile",url);
  fetch(url, {
    method: 'POST',
    body: FormdataWrapper(params),
    headers: {
      Authorization: `bearer ${localStorage.getItem('antd-pro-token-onestop')}`,
    },
  })
    .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.click();
        window.URL.revokeObjectURL(url);
        a = null;
      } else {
      }
    })
    .catch((err) => {
      console.log(err);
    })
    .finally(() => {
      return true;
    });
}


export function downloadFileAndShowModal(url, params, fileName = '导出文件', ext = 'xlsx') {
  // console.log("downloadFile",url);
  fetch(url, {
    method: 'POST',
    body: FormdataWrapper(params),
    headers: {
      Authorization: `bearer ${localStorage.getItem('antd-pro-token-onestop')}`,
    },
  })
    .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;
        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.log(err);
    })
    .finally(() => {
      return true;
    });
}
