// 空数据表
const EMPTY_BOOK = (() => {
  const setting = {
    header: [
      { headerName: '主从对应码', headerWidth: 100, dataCode: 'code', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
      { headerName: '别名编码', headerWidth: 70, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
      { headerName: '计算式', headerWidth: 100, dataCode: 'expString', dataType: 'String', hAlign: 'left', vAlign: 'center' },
      { headerName: '材料名称', headerWidth: 275, dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' },
      { headerName: '规格型号', headerWidth: 180, dataCode: 'specs', dataType: 'String', hAlign: 'left', vAlign: 'center' },
      { headerName: '单位', headerWidth: 80, dataCode: 'unit', dataType: 'String', hAlign: 'center', vAlign: 'center' },
    ],
  };
  // 初始化表格
  const workBookObj = {
    book: null,
    sheet: null,
  };
  const buildWorkBook = () => {
    workBookObj.book = initSheet($('.empty-spread')[0], setting);
    workBookObj.book.options.allowUserDragDrop = true;
    workBookObj.book.options.allowUserDragFill = true;
    workBookObj.book.options.allowExtendPasteRange = false;
    lockUtil.lockSpreads([workBookObj.book], locked);
    workBookObj.sheet = workBookObj.book.getSheet(0);
  }


  // 总数据（数据没合并前）
  let totalData = [];
  let totalMap = {};

  // 表格显示的数据（合并后）
  const cache = [];

  const getCompareKey = (item) => {
    const props = ['name', 'specs', 'unit'];
    return props.map(prop => item[prop] ? item[prop].trim() : '').join('@');
  }

  const setTotalMap = (items) => {
    totalMap = {};
    items.forEach(item => {
      const key = getCompareKey(item);
      if (totalMap[key]) {
        totalMap[key].push(item);
      } else {
        totalMap[key] = [item];
      }
    })
  }

  // 获取表格数据，汇总空数据，多地区可能存在相同材料，按名称规格单位做筛选，重复材料仅显示一条即可
  const getTableData = (items) => {
    const map = {};
    items.forEach(item => {
      const key = getCompareKey(item);
      if (!map[key]) {
        map[key] = { ...item };
      }
    });
    return Object.values(map);
  }

  // 根据表格数据，获取实际信息价数据（一对多）
  const getItemsFromTableItem = (item) => {
    const key = getCompareKey(item);
    return totalMap[key] || [];
  }

  // 获取材料关键字： 名称 规格
  const getKeyword = (item) => {
    return item ? `${item.name} ${item.specs}` : '';
  }

  // 改变关键字
  const changeKeyword = (item) => {
    const keyword = getKeyword(item);
    $('#recommend-search').val(keyword);
    if (!keyword) {
      RECOMMEND_BOOK.clear();
    } else {
      RECOMMEND_BOOK.loadRecommendData(keyword);
    }
  }

  // 清空
  function clear() {
    cache.length = 0;
    workBookObj.sheet.setRowCount(0);
  }

  let curRow = 0;

  // 初始化数据
  async function initData() {
    clear();
    curRow = 0;
    $.bootstrapLoading.start();
    try {
      const matchAll = $('#match-all-input')[0].checked;
      const areaID = matchAll ? '' : AREA_BOOK.curArea?.ID;
      totalData = await ajaxPost('/priceInfo/getPriceEmptyData', { libID, compilationID, areaID }, 1000 * 60 * 10);
      setTotalMap(totalData);
      const tableData = getTableData(totalData);
      cache.push(...tableData)
      showData(workBookObj.sheet, cache, setting.header);
      changeKeyword(cache[0]);
    } catch (err) {
      clear();
      alert(err);
    } finally {
      $.bootstrapLoading.end();
    }
  }

  // 编辑处理
  async function handleEdit(changedCells, diffMap, needRefresh) {
    const postData = []; // 请求用
    // 更新缓存用
    const updateData = [];
    const deleteData = [];
    const insertData = [];
    try {
      changedCells.forEach(({ row }) => {
        if (cache[row]) {
          const rowData = getRowData(workBookObj.sheet, row, setting.header);
          if (Object.keys(rowData).length) { // 还有数据，更新
            let diffData;
            if (diffMap) {
              diffData = diffMap[row];
            } else {
              diffData = getRowDiffData(rowData, cache[row], setting.header);
            }
            if (diffData) {
              // 改一行， 实际可能是改多行，表格一行数据是多行合并显示的
              const items = getItemsFromTableItem(cache[row]);
              items.forEach(item => {
                // 只有珠海才更新计算式
                const updateObj = { ...diffData };
                const area = AREA_BOOK.cache.find(areaItem => areaItem.ID === item.areaID);
                if (diffMap && (!area || !area.name || !/珠海/.test(area.name))) {
                  delete updateObj.expString;
                  delete diffData.expString;
                }
                postData.push({ type: UpdateType.UPDATE, ID: item.ID, areaID: area.ID, compilationID, period: curLibPeriod, data: updateObj });
              });
              updateData.push({ row, data: diffData });
            }
          } else { // 该行无数据了，删除
            const items = getItemsFromTableItem(cache[row]);
            items.forEach(item => {
              const area = AREA_BOOK.cache.find(areaItem => areaItem.ID === item.areaID);
              postData.push({ type: UpdateType.DELETE, areaID: area.ID, compilationID, period: curLibPeriod, ID: item.ID });
            });
            deleteData.push(cache[row]);
          }
        }
      });
      if (postData.length) {
        $.bootstrapLoading.start();
        await ajaxPost('/priceInfo/editPriceData', { postData }, TIME_OUT);
        // 更新缓存，先更新然后删除，最后再新增，防止先新增后缓存数据的下标与更新、删除数据的下标对应不上
        updateData.forEach(item => {
          // 更新总表
          const curItem = cache[item.row];
          const compareKey = getCompareKey(curItem);
          const totalItems = totalMap[compareKey];
          if (totalItems) {
            const newCompareKey = getCompareKey({ ...curItem, ...item.data });
            totalItems.forEach(totalItem => {
              Object.assign(totalItem, item.data);
            });
            if (newCompareKey !== compareKey) {
              totalMap[newCompareKey] = totalItems;
              delete totalMap[compareKey];
            }
          }
          // 更新表格缓存
          Object.assign(cache[item.row], item.data);
        });
        deleteData.forEach(item => {
          // 更新总表
          const compareKey = getCompareKey(item);
          const totalItems = totalMap[compareKey];
          if (totalItems) {
            const totalItemIDs = totalItems.map(item => item.ID);
            totalData = totalData.filter(totalItem => !totalItemIDs.includes(totalItem));
            delete totalMap[compareKey];
          }
          // 更新表格缓存
          const index = cache.indexOf(item);
          if (index >= 0) {
            cache.splice(index, 1);
          }
        });
        insertData.forEach(item => cache.push(item));
        if (deleteData.length || insertData.length || needRefresh) {
          showData(workBookObj.sheet, cache, setting.header);
        }
        $.bootstrapLoading.end();
        CLASS_BOOK.reload();
      }
    } catch (err) {
      // 恢复各单元格数据
      showData(workBookObj.sheet, cache, setting.header);
      $.bootstrapLoading.end();
    }
  }

  // 跟新行的编号、编码编码
  async function updateRowCode(code, classCode, expString) {
    const item = cache[curRow];
    if (!item) {
      return;
    }
    const diffData = { code, classCode, expString };
    await handleEdit([{ row: curRow }], { [curRow]: diffData }, true);
  }

  const bindEvent = () => {
    workBookObj.sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) {
      const changedCells = [{ row: info.row }];
      handleEdit(changedCells);
    });
    workBookObj.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, info) {
      const row = info.newSelections && info.newSelections[0] ? info.newSelections[0].row : 0;
      if (curRow !== row) {
        const item = cache[row];
        changeKeyword(item);
      }
      curRow = row;
    });
    workBookObj.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, function (e, info) {
      const changedRows = [];
      let preRow;
      info.changedCells.forEach(({ row }) => {
        if (row !== preRow) {
          changedRows.push({ row });
        }
        preRow = row;
      });
      handleEdit(changedRows);
    });
  }

  // 将空表的表格保存至总表
  const saveInSummary = async () => {
    const documents = [];
    const removeIDs = [];
    cache.filter(item => item.code && item.classCode).forEach(item => {
      removeIDs.push(item.ID);
      documents.push({
        ID: uuid.v1(),
        code: item.code,
        classCode: item.classCode,
        expString: item.expString,
        name: item.name,
        specs: item.specs,
        unit: item.unit,
      });
    });
    if (!documents.length) {
      alert('不存在可保存数据');
      return;
    }
    console.log(documents);
    try {
      $.bootstrapLoading.progressStart('保存至总表', true);
      $("#progress_modal_body").text('正在保存至总表，请稍后...');
      await ajaxPost('/priceInfoSummary/saveInSummary', { documents }, 1000 * 60 * 5);
      setTimeout(() => {
        $.bootstrapLoading.progressEnd();
        alert('保存成功');
        const filterCache = cache.filter(item => !removeIDs.includes(item.ID));
        cache.length = 0;
        cache.push(...filterCache);
        showData(workBookObj.sheet, cache, setting.header);
      }, 1000);
    } catch (error) {
      setTimeout(() => {
        $.bootstrapLoading.progressEnd();
      }, 500);
      console.log(error);
      alert(error);
    }
  }


  return {
    buildWorkBook,
    bindEvent,
    clear,
    initData,
    workBookObj,
    updateRowCode,
    saveInSummary,
  }
})();

$(document).ready(() => {
  $('#empty-area').on('shown.bs.modal', function () {
    if (!EMPTY_BOOK.workBookObj.book) {
      EMPTY_BOOK.buildWorkBook();
      EMPTY_BOOK.bindEvent();
    }
    EMPTY_BOOK.initData();
  });

  $('#empty-area').on('hidden.bs.modal', function () {
    EMPTY_BOOK.clear();
  });

  // 保存至总表
  $('#save-in-summary').click(() => {
    EMPTY_BOOK.saveInSummary();
  });
});