import defaultSetting from "./config.js";
import { common_extend } from "./utils/util";
import Store from "./store";
import server from "./controllers/server";
import luckysheetConfigsetting from "./controllers/luckysheetConfigsetting";
import sheetmanage from "./controllers/sheetmanage";
import luckysheetsizeauto from "./controllers/resize";
import luckysheetHandler from "./controllers/handler";
import { initialFilterHandler } from "./controllers/filter";
import { initialMatrixOperation } from "./controllers/matrixOperation";
import { initialSheetBar } from "./controllers/sheetBar";
import { formulaBarInitial } from "./controllers/formulaBar";
import { rowColumnOperationInitial } from "./controllers/rowColumnOperation";
import { keyboardInitial } from "./controllers/keyboard";
import { orderByInitial } from "./controllers/orderBy";
import { initPlugins } from "./controllers/expendPlugins";
import {
  getluckysheetfile,
  getluckysheet_select_save,
  getconfig,
} from "./methods/get";
import { setluckysheet_select_save } from "./methods/set";
import { luckysheetrefreshgrid, jfrefreshgrid } from "./global/refresh";
import functionlist from "./function/functionlist";
import { luckysheetlodingHTML } from "./controllers/constant";
import { getcellvalue, getdatabyselection } from "./global/getdata";
import { setcellvalue } from "./global/setdata";
import { selectHightlightShow } from "./controllers/select";
import { zoomInitial } from "./controllers/zoom";
import { printInitial } from "./controllers/print";
import method from "./global/method";

import * as api from "./global/api";

import flatpickr from "flatpickr";
import Mandarin from "flatpickr/dist/l10n/zh.js";
import { initListener } from "./controllers/listener";
import { hideloading, showloading } from "./global/loading.js";
import { luckysheetextendData } from "./global/extend.js";

let luckysheet = {};

// mount api
// luckysheet.api = api;
// Object.assign(luckysheet, api);

luckysheet = common_extend(api, luckysheet);

//创建luckysheet表格
luckysheet.create = function(setting) {
  method.destroy();
  server.websocket && server.websocket.close(1000, "Work complete");
  // Store original parameters for api: toJson
  Store.toJsonOptions = {};
  for (let c in setting) {
    if (c !== "data") {
      Store.toJsonOptions[c] = setting[c];
    }
  }

  let extendsetting = common_extend(defaultSetting, setting);

  let loadurl = extendsetting.loadUrl,
    authorityUrl = extendsetting.authorityUrl,
    templateId = extendsetting.templateId,
    data = extendsetting.data,
    menu = extendsetting.menu,
    authority = extendsetting.authority,
    title = extendsetting.title;
  if (!loadurl) {
    data.forEach((sheet) => {
      initSheet(sheet, authority, setting.permissions);
    });
  }

  let container = extendsetting.container;
  Store.container = container;
  Store.luckysheetfile = data;
  Store.defaultcolumnNum = extendsetting.column;
  Store.defaultrowNum = extendsetting.row;
  Store.defaultFontSize = extendsetting.defaultFontSize;
  Store.fullscreenmode = extendsetting.fullscreenmode;
  Store.lang = extendsetting.lang; //language
  Store.allowEdit = extendsetting.allowEdit;
  Store.limitSheetNameLength = extendsetting.limitSheetNameLength;
  Store.defaultSheetNameMaxLength = extendsetting.defaultSheetNameMaxLength;
  Store.fontList = extendsetting.fontList;
  Store.pauseUpdate = extendsetting.pauseUpdate;
  server.gridKey = extendsetting.gridKey;
  server.loadUrl = extendsetting.loadUrl;
  server.updateUrl = extendsetting.updateUrl;
  server.updateImageUrl = extendsetting.updateImageUrl;
  server.title = extendsetting.title;
  server.loadSheetUrl = extendsetting.loadSheetUrl;
  server.allowUpdate = extendsetting.allowUpdate;

  luckysheetConfigsetting.autoFormatw = extendsetting.autoFormatw;
  luckysheetConfigsetting.accuracy = extendsetting.accuracy;
  luckysheetConfigsetting.total = extendsetting.data[0].total;

  luckysheetConfigsetting.loading = extendsetting.loading;
  luckysheetConfigsetting.allowCopy = extendsetting.allowCopy;
  luckysheetConfigsetting.showtoolbar = extendsetting.showtoolbar;
  luckysheetConfigsetting.showtoolbarConfig = extendsetting.showtoolbarConfig;
  luckysheetConfigsetting.showinfobar = extendsetting.showinfobar;
  luckysheetConfigsetting.showsheetbar = extendsetting.showsheetbar;
  luckysheetConfigsetting.showsheetbarConfig = extendsetting.showsheetbarConfig;
  luckysheetConfigsetting.showstatisticBar = extendsetting.showstatisticBar;
  luckysheetConfigsetting.showstatisticBarConfig =
    extendsetting.showstatisticBarConfig;
  luckysheetConfigsetting.sheetFormulaBar = extendsetting.sheetFormulaBar;
  luckysheetConfigsetting.cellRightClickConfig =
    extendsetting.cellRightClickConfig;
  luckysheetConfigsetting.sheetRightClickConfig =
    extendsetting.sheetRightClickConfig;
  luckysheetConfigsetting.pointEdit = extendsetting.pointEdit;
  luckysheetConfigsetting.pointEditUpdate = extendsetting.pointEditUpdate;
  luckysheetConfigsetting.pointEditZoom = extendsetting.pointEditZoom;

  luckysheetConfigsetting.userInfo = extendsetting.userInfo;
  luckysheetConfigsetting.userMenuItem = extendsetting.userMenuItem;
  luckysheetConfigsetting.myFolderUrl = extendsetting.myFolderUrl;
  luckysheetConfigsetting.functionButton = extendsetting.functionButton;

  luckysheetConfigsetting.showConfigWindowResize =
    extendsetting.showConfigWindowResize;
  luckysheetConfigsetting.enableAddRow = extendsetting.enableAddRow;
  luckysheetConfigsetting.enableAddBackTop = extendsetting.enableAddBackTop;
  luckysheetConfigsetting.addRowCount = extendsetting.addRowCount;
  luckysheetConfigsetting.enablePage = extendsetting.enablePage;
  luckysheetConfigsetting.pageInfo = extendsetting.pageInfo;

  luckysheetConfigsetting.editMode = extendsetting.editMode;
  luckysheetConfigsetting.beforeCreateDom = extendsetting.beforeCreateDom;
  luckysheetConfigsetting.workbookCreateBefore =
    extendsetting.workbookCreateBefore;
  luckysheetConfigsetting.workbookCreateAfter =
    extendsetting.workbookCreateAfter;
  luckysheetConfigsetting.remoteFunction = extendsetting.remoteFunction;

  luckysheetConfigsetting.fireMousedown = extendsetting.fireMousedown;
  luckysheetConfigsetting.forceCalculation = extendsetting.forceCalculation;
  luckysheetConfigsetting.plugins = extendsetting.plugins;

  luckysheetConfigsetting.rowHeaderWidth = extendsetting.rowHeaderWidth;
  luckysheetConfigsetting.columnHeaderHeight = extendsetting.columnHeaderHeight;

  luckysheetConfigsetting.defaultColWidth = extendsetting.defaultColWidth;
  luckysheetConfigsetting.defaultRowHeight = extendsetting.defaultRowHeight;

  luckysheetConfigsetting.title = extendsetting.title;
  luckysheetConfigsetting.container = extendsetting.container;
  luckysheetConfigsetting.hook = extendsetting.hook;

  luckysheetConfigsetting.pager = extendsetting.pager;

  luckysheetConfigsetting.initShowsheetbarConfig = false;

  luckysheetConfigsetting.imageUpdateMethodConfig =
    extendsetting.imageUpdateMethodConfig;

  if (Store.lang === "zh") flatpickr.localize(Mandarin.zh);

  // Store the currently used plugins for monitoring asynchronous loading
  Store.asyncLoad.push(...luckysheetConfigsetting.plugins);

  // Register plugins
  initPlugins(extendsetting.plugins, extendsetting.data);

  // Store formula information, including internationalization
  functionlist();

  let devicePixelRatio = extendsetting.devicePixelRatio;
  if (devicePixelRatio == null) {
    devicePixelRatio = 1;
  }
  Store.devicePixelRatio = Math.ceil(devicePixelRatio);

  //loading
  const loadingObj = luckysheetlodingHTML("#" + container);
  Store.loadingObj = loadingObj;

  if (loadurl == "") {
    sheetmanage.initialjfFile(menu, title);
    // luckysheetsizeauto();

    initialWorkBook();
  } else {
    $.post(loadurl, { gridKey: server.gridKey }, function(d) {
      let data = new Function("return " + d)();
      console.log("====================================================");
      console.log(data);
      data.forEach((sheet) => {
        initSheet(sheet, authority, setting.permissions);
      });

      console.log(data);
      Store.luckysheetfile = data;

      sheetmanage.initialjfFile(menu, title);
      // luckysheetsizeauto();
      initialWorkBook();

      //需要更新数据给后台时，建立WebSocket连接
      if (server.allowUpdate) {
        server.getUser = setting.getUser;
        server.openWebSocket();
      }
    });
  }
};

function initialWorkBook() {
  luckysheetHandler(); //Overall dom initialization
  initialFilterHandler(); //Filter initialization
  initialMatrixOperation(); //Right click matrix initialization
  initialSheetBar(); //bottom sheet bar initialization
  formulaBarInitial(); //top formula bar initialization
  rowColumnOperationInitial(); //row and coloumn operate initialization
  keyboardInitial(); //Keyboard operate initialization
  orderByInitial(); //menu bar orderby function initialization
  zoomInitial(); //zoom method initialization
  printInitial(); //print initialization
  initListener();
}

//获取所有表格数据
luckysheet.getluckysheetfile = getluckysheetfile;

//获取当前表格 选区
luckysheet.getluckysheet_select_save = getluckysheet_select_save;

//设置当前表格 选区
luckysheet.setluckysheet_select_save = setluckysheet_select_save;

//获取当前表格 config配置
luckysheet.getconfig = getconfig;

//二维数组数据 转化成 {r, c, v}格式 一维数组 (传入参数为二维数据data)
luckysheet.getGridData = sheetmanage.getGridData;

//生成表格所需二维数组 （传入参数为表格数据对象file）
luckysheet.buildGridData = sheetmanage.buildGridData;

// Refresh the canvas display data according to scrollHeight and scrollWidth
luckysheet.luckysheetrefreshgrid = luckysheetrefreshgrid;

// Refresh canvas
luckysheet.jfrefreshgrid = jfrefreshgrid;

// Get the value of the cell
luckysheet.getcellvalue = getcellvalue;

// Set cell value
luckysheet.setcellvalue = setcellvalue;

// Get selection range value
luckysheet.getdatabyselection = getdatabyselection;

luckysheet.sheetmanage = sheetmanage;

// Data of the current table
luckysheet.flowdata = function() {
  return Store.flowdata;
};

// Set selection highlight
luckysheet.selectHightlightShow = selectHightlightShow;

// Reset parameters after destroying the table
luckysheet.destroy = method.destroy;

luckysheet.setPauseUpdate = method.setPauseUpdate;

luckysheet.showLoadingProgress = showloading;
luckysheet.hideLoadingProgress = hideloading;
luckysheet.luckysheetextendData = luckysheetextendData;

export { luckysheet };

const getColSign = (celldata, days) => {
  // 定义44927代表的日期基准
  let baseDate = new Date(1900, 0, 1); // 1900年1月1日
  let resultDate = new Date(baseDate);
  resultDate.setDate(baseDate.getDate() + Number(days));
  const curMonth = resultDate.getMonth() + 1;
  const curYear = resultDate.getFullYear();
  let colNum = 0;
  celldata.forEach((item) => {
    if (item.r == 5 && item.c >= 12 && item.c <= 84) {
      let itemDate = new Date(baseDate);
      itemDate.setDate(baseDate.getDate() + item.v.v);
      const month = itemDate.getMonth() + 1;
      const year = itemDate.getFullYear();
      if (month == curMonth && year == curYear) colNum = item.c;
      return month;
    }
  });
  //获取日期列数据
  return colNum;
};

function numberToExcelColumn(num) {
  let result = "";
  while (num >= 0) {
    const remainder = num % 26;
    result = String.fromCharCode(65 + remainder) + result;
    num = Math.floor(num / 26) - 1;
  }
  return result;
}

function initSheet(sheet, authority, permissions) {
  console.log("--------------permissions----------", permissions);
  let colhidden = {};
  let rowhidden = {};
  if (sheet.config) {
    delete sheet.config.authority;
  }
  sheet.config = sheet.config || {};

  let canEditRangeList = [];

  if (sheet.name == "PSR") {
    canEditRangeList = [
      // {
      //   hintText: "",
      //   sqref: "$C$47:$C$52",
      // },
      // {
      //   hintText: "",
      //   sqref: "$C$55:$C$55",
      // },
      // {
      //   hintText: "",
      //   sqref: "$C$57:$C$57",
      // },
      // {
      //   hintText: "",
      //   sqref: "$C$86:$C$87",
      // },
      {
        hintText: "",
        sqref: "$B$104:$B$122",
      },
    ];
    // 隐藏PSR表
    if (!permissions["func-psr-01"]) {
      sheet.hide = 1;
      sheet.status = 0;
    }
    // 隐藏项目经理预算
    if (!permissions["func-psr-02"]) {
      for (let i = 78; i <= 100; i++) {
        rowhidden[i] = 0;
      }
    }
    // 最下方预算
    if (!permissions["func-psr-03"]) {
      for (let i = 101; i <= 122; i++) {
        rowhidden[i] = 0;
      }
      canEditRangeList.push({
        hintText: "",
        sqref: "$C$90:$C$99",
      });
    }
    // // 更新时间权限
    // if (permissions["func-psr-04"]) {
    //   canEditRangeList.push({
    //     hintText: "",
    //     sqref: "$B$2:$B$2",
    //   });
    // }
    // 预算列权限
    if (permissions["func-psr-05"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$C$6:$C$89",
      });
    }
    // 实际支出列编辑权限
    if (permissions["func-psr-06"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$D$6:$D$89",
      });
    }
    // 预测费用列编辑权限
    if (permissions["func-psr-07"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$F$6:$F$89",
      });
    }
    // 当月发生额列编辑权限
    if (permissions["func-psr-08"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$H$6:$H$89",
      });
    }
  } else if (sheet.name == "现金流") {
    if (!permissions["func-actual-01"]) {
      sheet.hide = 1;
      sheet.status = 0;
    }
    // 预计回款权限
    if (permissions["func-actual-02"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$A$3:$CF$3",
      });
    }
    // 实际回款权限
    if (permissions["func-actual-03"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$A$4:$CF$4",
      });
    }
    // 日期列已发生：成本会计；
    if (permissions["func-actual-04"]) {
      //获取当前表单日期 44675
      const days = sheet.celldata.find((item) => item.r == 1 && item.c == 3)?.v
        .v;
      //获取跟当前日期匹配的 col
      const colNum = getColSign(sheet.celldata, days);
      //转化成 ABC
      const colSign = numberToExcelColumn(colNum);
      canEditRangeList.push({
        hintText: "",
        sqref: `$M$7:$${colSign}$298`,
      });
    }
    // 日期列未发生：采购经理；
    if (permissions["func-actual-05"]) {
      //获取当前表单日期 44675
      const days = sheet.celldata.find((item) => item.r == 1 && item.c == 3)?.v
        .v;
      //获取跟当前日期匹配的 col 的后一列
      const colNum = getColSign(sheet.celldata, days) + 1;
      //转化成 ABC  不包括当前列
      const colSign = numberToExcelColumn(colNum);
      canEditRangeList.push({
        hintText: "",
        sqref: `$${colSign}$7:$CF$298`,
      });
    }
    // 其他列编辑权限
    if (permissions["func-actual-06"]) {
      canEditRangeList.push({
        hintText: "",
        sqref: "$B249:$H$298",
      });
    }
  } else if (sheet.name == "清单") {
    sheet.status = 1;
    canEditRangeList.push({
      hintText: "",
      sqref: "$A$1:$Q$999",
    });
    // 清单预算列显示
    if (!permissions["func-list-01"]) {
      colhidden[8] = 0;
      colhidden[9] = 0;
    }
  } else {
    canEditRangeList.push({
      hintText: "",
      sqref: "$A$1:$Q$999",
    });
  }

  // 处于审批时  所有人都无法修改
  if (authority) {
    sheet.config.authority = authority;
  } else {
    // 设置保护区域，lucksheet不能直接设置不允许编辑的区域
    // 只能禁止整体编辑，设置例外区域
    sheet.config.authority = {
      sheet: 1,
      hintText: "禁止编辑",
      allowRangeList: canEditRangeList,
    };
  }

  if (sheet.config.colhidden) {
    sheet.config.colhidden = { ...colhidden, ...sheet.config.colhidden };
  } else {
    sheet.config.colhidden = colhidden;
  }
  if (sheet.config.rowhidden) {
    sheet.config.rowhidden = { ...rowhidden, ...sheet.config.rowhidden };
  } else {
    sheet.config.rowhidden = rowhidden;
  }

  // 公式计算
  let calcChain = [];
  let index = sheet.index;
  sheet.celldata.forEach((item) => {
    if (typeof item.v.f !== "undefined") {
      calcChain.push({
        r: item.r,
        c: item.c,
        index,
      });
    }
  });
  sheet.calcChain = calcChain;
}
