<template>
  <div class="table-wrapper" @keydown="handlekeyDownKeys">
    <template v-if="config.data.length">
      
      <!-- 公式显示区 -->
      <div class="formula-wrapper" v-if="!disabled">
        <span style="flex-shrink: 0;color:#C0C4CC">公式</span>
        <el-input
          v-if="selectCell&&selectCell.DataType===6"
          v-model="selectCell.Value"
          @change="updateValueByFormula"
        />
      </div>

      <table
        width="auto"
        border="0"
        class="table"
        :style="disabled ? 'width:100%' : ''"
      >
        <thead>
          <tr>
            <!-- 行头 -->
            <th class="th-tg sm"></th>

            <!-- 列头 -->
            <th
              v-for="(item, index) in columnHeader"
              :key="index"
              class="th-tg th-col"
              :data-cindex="item"
              :data-rindex="-1"
              @contextmenu.prevent="rightClickHandle"
            >
              {{ item }}
            </th>
          </tr>
        </thead>

        <tbody>
          <tr v-for="(row, index) in config.data" :key="index">
            <!-- 行头 -->
            <th
              class="th-tg th-row sm"
              @contextmenu.prevent="rightClickHandle"
              :data-rindex="rowHeader[index]"
              :data-cindex="-1"
            >
              {{ rowHeader[index] }}
            </th>

            <td
              v-for="(cell, cell_index) in row"
              :key="`${index}_${cell_index}`"
              :data-rindex="rowHeader[index]"
              :data-cindex="columnHeader[cell_index]"
              :data-key="cell.Uid"
              @click="clickCell($event, cell)"
              @dblclick="dblClickCellHandle($event,cell)"
              @contextmenu.prevent="rightClickHandle($event,cell)"
              @mouseenter="getRelationEdbInfo(cell)"
              @copy="copyCellHandle($event,cell)"
              @paste="pasteCellHandle($event,cell)"
            >

            <!-- 插入单元格禁止编辑 -->
            <template 
              v-if="([4,5,6,7].includes(cell.DataType)&&!cell.CanEdit)
              ||disabled
              ||(cell.DataType===1&&[1,2].includes(cell.DataTimeType))"
            >
              
              <!-- 单元格类型5 7显示指标浮窗 -->
              <el-popover
                v-if="[5,7].includes(cell.DataType)&&!disabled"
                placement="top-start"
                width="350"
                trigger="hover"
              >
                <ul>
                  <li style="display:flex;margin:10px;">
                    <label style="min-width:80px;">指标名称</label> 
                    {{cellrelationEdbInfo.EdbName}}
                  </li>
                  <li style="display:flex;margin:10px;">
                    <label style="min-width:80px;">最新日期</label> 
                    {{cellrelationEdbInfo.LatestDate}}
                  </li>
                  <li style="display:flex;margin:10px;">
                    <label style="min-width:80px;">指标ID</label> 
                    {{cellrelationEdbInfo.EdbCode}}
                  </li>
                </ul>
                <span
                  slot="reference"
                  :data-rindex="rowHeader[index]"
                  :data-cindex="columnHeader[cell_index]"
                  :data-key="cell.Uid"
                >{{ cell.ShowValue }}</span>
              </el-popover>

              <span
                :data-rindex="rowHeader[index]"
                :data-cindex="columnHeader[cell_index]"
                :data-key="cell.Uid"
                v-else
              >{{ cell.ShowValue }}</span>
            </template>

              <el-autocomplete
                v-else
                v-model="cell.Value"
                :ref="`inputRef${cell.Uid}`"
                :fetch-suggestions="searchTarget"
                popper-class="edb-select-popover"
                :data-key="cell.Uid"
                :data-rindex="rowHeader[index]"
                :data-cindex="columnHeader[cell_index]"
                :highlight-first-item="cell.DataType===2"
                @select="selectTarget($event,cell)"
                @click="clickCell($event, cell)"
                @change.native="changeVal($event, cell)"
                @keydown.native="keyEnterHandle($event,cell)"
              >
                <template slot-scope="scope">
                    <edbDetailPopover :info="scope.item">
                      <div slot="reference" v-if="cell.DataType===2" class="edb-item">
                         <span class="edb-item-name text_oneLine">{{ scope.item.EdbName }}</span>
                         <i class="el-icon-check" style="color:#0052D9;font-size:18px;"/>
                      </div>

                      <div slot="reference" v-else>{{ scope.item.EdbName }}</div>
                    </edbDetailPopover>
                </template>
              </el-autocomplete>
            </td>
          </tr>
        </tbody>
      </table>

      <!-- 右键菜单 -->
      <div class="contextMenu-wrapper" id="contextMenu-wrapper" @mouseleave="hideContextMenu">
        <div :class="['item',{'deletesty': menu.key==='reset'}]" v-for="menu in config.contextMenuOption" :key="menu.key" @click="handleContext(menu.key)">
          {{menu.label}}
          
          <i class="el-icon-arrow-right" v-if="menu.children"></i>

          <!-- 二级菜单 -->
          <div class="subMenu-wrapper" v-if="menu.children">
            <div slot="reference" class="item" v-for="submenu in menu.children" :key="submenu.key" @click="edbCalculateInsertOpen(submenu)">
                <el-popover
                  width="300"
                  trigger="hover"
                  placement="right"
                >
                  <div v-html="formulaTip.get(submenu.fromEdbKey)"></div>
                  <div slot="reference" style="width:100%">{{submenu.label}}</div>   
                </el-popover>
            </div>
          </div>
        </div>
      </div>
    </template>

    <div class="nodata" v-else>
      <tableNoData text="暂无数据"/>
    </div>

    <!-- 选择指标 -->
    <selectTargetValueDia
      :isShow.sync="isSelectTargetValueDialog"
      @insert="insertSelectData"
      ref="selectTargetValueRef"
    />

    <!-- 插入系统/指标日期弹窗 -->
    <insertDateDia
      :isShow.sync="isInsertDateDialog"
      :info="insertDateInfo"
      @insert="insertDatehandle"
    />

    <!-- 指标计算弹窗 -->
    <calculateEdbDia
      ref="calculateEdbDiaRef"
      :isShow.sync="isInsertCalculate"
      :info="insertCalculateInfo"
      @insert="insertCalculateData"
    />
  </div>
</template>
<script>
import {
  getRowHeaderCode,
  getColumnHeaderCode,
  selectCellStyle,
  selectMoreCellStyle,
  setRelationStyle,
  getRightClickMenu,
  checkDateFormat,
  setFocus,
  findCellByKey,
  resetRelationStyle,
  resetDialogCellStyle,
  extractFactorsFromFormula,
  findCellByFactor,
  splitString,
  toUpperCase,
  findCellKeyByFactor
} from "../common/customTable";
import * as sheetInterface from "@/api/modules/sheetApi.js";
import { dataBaseInterface } from '@/api/api.js';
import md5 from '@/utils/md5.js';
import selectTargetValueDia from './selectTargetValueDia.vue';
import insertDateDia from './insertDateDia.vue';
import calculateEdbDia from './calculateEdbDia.vue';
import { formulaTip } from '@/views/dataEntry_manage/databaseComponents/util';
export default {
  props: {
    disabled: { //是否只预览
      type: Boolean,
      default: false,
    }
  },
  components: { selectTargetValueDia,insertDateDia,calculateEdbDia },
  computed: {
    //列头
    columnHeader() {
      return getColumnHeaderCode(
        this.config.data[0] ? this.config.data[0].length : 0
      );
    },
    //行头
    rowHeader() {
      let total_length = this.config.data.length;
      // console.log(this.config.data)
      return getRowHeaderCode(total_length);
    },
  },
  watch:{
    'config.data':{
      handler(newVal){
        if(!this.disabled && this.hasInit){
          this.$emit("autoSave")
        }
      },
      deep:true
    },
    insertRelationArr:{
      handler(newVal){
        if(!this.disabled && this.hasInit){
          this.$emit("autoSave")
        }
      },
      deep:true
    },
  },
  data() {
    return {
      config: {
        /* 单元格类型 
          1手动日期格 DataTimeType 0
          2指标格 
          3自定义输入 
          4插入值 表格里有关联的日期和指标格  //隐藏 又不要这个功能了
          5弹窗里的插入值 有关联日期格 
          6公式计算单元格 
          1系统日期导入格 DataTimeType 1
          1指标日期导入格 DataTimeType 2
          7指标计算的插入值单元格
        */
        data: [], 
        contextMenuOption: [],
      },

      selectCell: {},//选中单元格info

      rightClickCell: {},//右键单元格 key c r

      insertTargetCell: {},//选择右键插入时的单元格 可和右键单元格不一样 key c r

      insertRelationArr: [], //表格单元格依赖关系数组

      isSelectTargetValueDialog: false,

      cellrelationEdbInfo: {}, //指标浮窗信息

      copyCellItem: {},//复制时的单元格信息 用于粘贴赋值

      calculateClickCell: null,//双击公式单元格时的单元格信息 用于之后选其他单元格拼接公式

      isInsertDateDialog: false,//导入日期弹窗
      insertDateInfo: {
        key: '',
      },

      calculateChainList: [],//公式链 key数组 后端需要

      isInsertCalculate: false,//插入指标计算值
      insertCalculateInfo: {},//指标计算单元格info

      formulaTip,
      
      hasInit:false,

    };
  },
  mounted() {
    if(this.$route.path === '/addMixedSheet' && !this.$route.query.id) this.initData();
  },
  methods: {

    /* 输入时实时搜索 满足日期格式不搜索 有=视为输入公式不搜索 */
    async searchTarget(query,cb) {
      //又要过滤掉2020-05-这样的奇葩其他格式 不让检索
      let dateOtherRegex = /^(?:(?:19|20)\d\d)([-])(0[1-9]|1[0-2])(-?)$/
      if(!query
        ||checkDateFormat(query)
        ||dateOtherRegex.test(query)
        ||query.startsWith('=')
      ) return cb([])
      
      const { DataType,EdbInfoId } = this.selectCell;

      const res = DataType===2 
        ? await dataBaseInterface.targetDetail({EdbInfoId})
        : await sheetInterface.searchTarget({
            KeyWord: query,
            CurrentIndex: 1,
            PageSize: 1000
          })
      if(res.Ret !== 200) return

      let arr = DataType===2 ? [res.Data] : (res.Data.List||[])
      cb(arr);
    },

    /* 单击 */
    clickCell(e, cell) {
      if(this.disabled) return

      selectCellStyle(e);
      this.selectCell = cell;
      
      setFocus(e);

      /* 如果当前有公式单元格在编辑就拼接当前单元格进公式 */
      // if(this.calculateClickCell && this.calculateClickCell.Uid!==cell.Uid) {
      //   console.log(this.calculateClickCell)
      //   const { cindex,rindex } = e.target.dataset;
      //   this.calculateClickCell.Value += `${cindex}${rindex}`
      // }

      //是插值单元格时寻找关联依赖的单元格 设置选框
      if([4,5,7].includes(cell.DataType)) {
        const { key } = e.target.dataset;
        if(!this.insertRelationArr.find(_ => _.key===key)) return
        let { relation_date,relation_edb } = this.insertRelationArr.find(_ => _.key===key)

        relation_date.key && setRelationStyle(relation_date)
        relation_edb.key && setRelationStyle(relation_edb)
      }

      //选择指标弹窗打开时选择日期更新弹窗数据
      this.isSelectTargetValueDialog&&this.$refs.selectTargetValueRef.chooseEdb(this.$refs.selectTargetValueRef.edbInfo)

      //计算指标弹窗打开时选择日期更新弹窗数据
      this.isInsertCalculate&&this.$refs.calculateEdbDiaRef.showResult&&this.$refs.calculateEdbDiaRef.calculateHandle()
    },

    /* 插入值 往左往上寻找同行同列是否有符合条件的一指标一日期 */
    async insertValue() {
      
      let params = this.findNearestCell();
      console.log(params)
      if(!params) {
        this.selectCell.DataType = 3;
        this.selectCell.DataTimeType = 0;
        this.selectCell.ShowValue = '';
        this.selectCell.Value = '';
        this.selectCell.DataTime = '';
        this.selectCell.EdbInfoId = 0;
        this.$message.warning('无法在此处插入值');
        return
      }

      const { EdbInfoId,Date,DataTimeType } = params

      const res = await sheetInterface.insertData({EdbInfoId,Date})
      if(res.Ret !==200) return

      //日期无值也要建立关联关系
      // if(!res.Data&&!DataTimeType){
      //   this.selectCell.DataType = 3;
      //   this.selectCell.DataTimeType = 0;
      //   this.selectCell.ShowValue = '';
      //   this.selectCell.Value = '';
      //   this.selectCell.DataTime = '';
      //   this.selectCell.EdbInfoId = 0;
      //   this.$message.warning('所选指标的所选日期无值')
      //   return
      // }

      res.Data ? this.$message.success('插入成功') : this.$message.warning('当前日期暂无值') 

      this.selectCell.DataType = 4;
      this.selectCell.ShowValue = res.Data;
      this.selectCell.Value = res.Data;
      this.selectCell.EdbInfoId = EdbInfoId;
      this.selectCell.DataTime = Date;

      this.setRelation(params)
    },
    
    // 建立插入单元格和依赖单元格关联关系
    setRelation(data,cellType=4) {
      const { insert_cell } = data;

      let relation_obj = {
        type: cellType,
        key: insert_cell.key,
        relation_date: {
          type: 1,
          key: insert_cell.relation_date
        },
        relation_edb: {
          type: 2,
          key: insert_cell.relation_edb
        }
      }

      let haveIndex = this.insertRelationArr.findIndex(_ => _.key===insert_cell.key);
      if(haveIndex===-1) {
        this.insertRelationArr.push(relation_obj)
      }else {
        this.insertRelationArr.splice(haveIndex,1,relation_obj)
      }
      console.log(this.insertRelationArr)
    },

    /* 向左向上找出所有格子 找出离插入单元格最近的两个符合条件的单元格 看是否满足一指标一日期的条件
      不满足就无法插入值
    */
    findNearestCell() {
      let { rindex,cindex,key } = this.rightClickCell;
      
      let index_row = this.rowHeader.findIndex(_ => _===rindex);
      let index_col = this.columnHeader.findIndex(_ => _===cindex);

      //同行左侧所有格子
      let row_cell_arr = this.config.data[index_row].filter((_,cell_index) => cell_index<index_col);
      //同列上侧所有格子
      let col_cell_arr = this.config.data.filter((row,row_index) => row_index<index_row).map(row=> row[index_col]);

      if(!row_cell_arr.length || !col_cell_arr.length){
        return null
      }

      //寻找最近的符合1 2类型的两个格子
      let params = null;
      
      for (let i = row_cell_arr.length - 1; i >= 0; i--) {
        for (let j = col_cell_arr.length - 1; j >= 0; j--) {
          if(!params) {
            if((row_cell_arr[i].DataType===1&&col_cell_arr[j].DataType===2)
            ||(row_cell_arr[i].DataType===2&&col_cell_arr[j].DataType===1)) {
              params = {
                DataTimeType: row_cell_arr[i].DataType===1 ? row_cell_arr[i].DataTimeType : col_cell_arr[j].DataTimeType,
                Date: row_cell_arr[i].DataType===1 ? row_cell_arr[i].ShowValue : col_cell_arr[j].ShowValue,
                EdbInfoId: row_cell_arr[i].DataType===2 ? row_cell_arr[i].EdbInfoId : col_cell_arr[j].EdbInfoId,
                insert_cell: {
                  key,
                  relation_date: row_cell_arr[i].DataType===1 ? row_cell_arr[i].Uid: col_cell_arr[j].Uid,
                  relation_edb: row_cell_arr[i].DataType===2 ? row_cell_arr[i].Uid: col_cell_arr[j].Uid,
                },
              }
              break
            }
          }
        }
      }
      return params;

    },

    /* 选择指标 单元格类型为2 已经是指标单元格了就重置单元格 否则就视为选择指标*/
    selectTarget(e,cell) {
      const { EdbName,EdbInfoId }  = e;

      //如果已经是指标单元格了再次点击就清空
      if(cell.DataType===2&&cell.EdbInfoId) {
        this.clearCell()
      }else {
        cell.DataType = 2;
        cell.DataTime = '';
        cell.ShowValue = EdbName;
        cell.Value = EdbName;
        cell.EdbInfoId = EdbInfoId;
      }

      this.checkCellRelation(cell)
    },

    /* 输入框失焦 设置单元格类型 处理关联关系 */
    async changeVal(e, cell) {

      // 是日期格式 DataType为1
      // 自定义内容 DataType 3
      //有=号为输入公式 DataType 6

      const {value} = e.target;
      if(!value){ //无值重置单元格
        cell.DataType = 3;
        cell.ShowValue = value;
        cell.Value = value;
        cell.EdbInfoId = 0;
        cell.DataTime = '';
        cell.Extra=''
      }else {
        //指标类型不做格式处理
        if(cell.DataType===2) return
        
        console.log(checkDateFormat(value))
        let dateFormat = checkDateFormat(value);
        if(dateFormat) { //是日期格式
          cell.DataType = 1;
          cell.Extra='';
          cell.ShowValue = dateFormat;
          cell.Value = dateFormat;
        }else if(value.startsWith('=')) { //公式单元格
          cell.DataType = 6;
          let calculateVal = await this.getValueByFormula(value);
          if(!calculateVal) return
          cell.ShowValue = calculateVal;
          //处理公式关系
          this.$set(cell,'Extra',this.dealFormulaConstruction(value))
          

        }else {//自定义值
          cell.DataType = 3;
          cell.ShowValue = value;
          cell.Value = value;
          cell.EdbInfoId = 0;
          cell.DataTime = '';
          cell.Extra=''
        }
      }

      //判断是否是有插入值的依赖单元格 更新值或重置关系
      this.checkCellRelation(cell)
    },

    /* 当前单元格是否和插入值有关联 无就不管 */
    async checkCellRelation(cell) {
      if(!this.insertRelationArr.length) return

      const key= cell.Uid;
      
      //有关联的N组数组
      let haveRelationArr = this.insertRelationArr.filter(_ => _.relation_date.key===key||_.relation_edb.key===key);

      if(!haveRelationArr.length) return

      //去处理每一组关联的情况
      haveRelationArr.forEach( async(relation) => {
        const { relation_date,relation_edb } = relation;
  
        if((relation_date.key === key && cell.DataType === 1) || (relation_edb.key === key && cell.DataType === 2)) { //单元格类型不变只变值仍有关联关系 更新值
  
          //刷新插入值结果
          let params = null;
          if(relation_date.key === key && cell.DataType === 1) { //修改的是依赖日期格
            let { EdbInfoId } = findCellByKey(this.config.data,relation.key)
            params = {
              EdbInfoId,
              Date: cell.ShowValue
            }
  
          } else if( relation_edb.key === key && cell.DataType === 2) { //修改的依赖指标格
            let {ShowValue} = findCellByKey(this.config.data,relation_date.key)
            params = {
              EdbInfoId: cell.EdbInfoId,
              Date: ShowValue
            }
          }
  
          const res = await sheetInterface.insertData(params)
          if(res.Ret !==200) return

          //现在日期无值也不清除关系了
          // !res.Data && this.updateInsertCell(relation.key);
          
          this.config.data.forEach(row => {
            row.forEach(cell => {
              if(cell.Uid === relation.key) {
                  cell.DataType = relation.type;
                  cell.ShowValue = res.Data;
                  cell.Value = res.Data;
                  cell.EdbInfoId = params.EdbInfoId;
                  cell.DataTime = params.Date;
              }
            })
          })
  
        }else {
          // 清除插入值单元格式和关联关系
          this.updateInsertCell(relation.key);
        }
      })
 
    },

    // 清除插入值单元格式和关联关系
    updateInsertCell(key) {
      this.config.data.forEach(row => {
        row.forEach(cell => {
          if(cell.Uid === key) {
            cell.DataType = 3;
            cell.EdbInfoId = 0;
            cell.DataTime = '';
            cell.ShowValue = '';
            cell.Value = '';
          }
        })
      })

      let relationIndex = this.insertRelationArr.findIndex(_ => _.key===key)
      this.insertRelationArr.splice(relationIndex,1)
    },

    /* 输入公式的计算值 */
    async getValueByFormula(val) {

      // 提取因数数组
      let factors = extractFactorsFromFormula(val)
      console.log(factors)
      
      //根据因数找单元格
      let isAllCell = factors.some(_ => findCellByFactor(_)===null||isNaN(findCellByFactor(_)))
      if(isAllCell) {
        this.$message.warning('公式参数有误')
        return '';
      } 

      let TagMap = {};
      factors.forEach(_ => {
        if(!TagMap[_]) {
          TagMap[_] = Number(findCellByFactor(_))
        }
      });

      const res = await sheetInterface.calculateCustomCellData({
        CalculateFormula: val,
        TagMap
      })
      if(res.Ret !== 200) return 
      return res.Data
    },

    /* 顶部公式改变 */
    async updateValueByFormula(value) {
      this.changeVal({target: {value}},this.selectCell)
    },

    /* 右键 */
    rightClickHandle(e,cell) {
      if(this.disabled) return

      const { rindex,cindex,key } = e.target.dataset;
      this.rightClickCell = {
        rindex,
        cindex,
        key
      }

      this.selectCell = cell;

      let pos;
      if(rindex==='-1') { //列头处
        pos = 'col'
      }else if(cindex==='-1') { //行头
        pos = 'row'
      }else {//单元格
        pos = 'cell'
      }
      this.config.contextMenuOption = pos === 'cell' 
        ? getRightClickMenu(pos,(cell.DataType===1&&[1,2].includes(cell.DataTimeType))||cell.DataType===7)
        : getRightClickMenu(pos)

      this.$nextTick(() => {
        let dom = $('#contextMenu-wrapper')[0];

        if(e.clientY > window.innerHeight/2) {
          dom.style.left = e.clientX-3 + 'px';
          dom.style.top = e.clientY-dom.offsetHeight-3 + 'px';
        }else {
          dom.style.left = e.clientX-3 + 'px';
          dom.style.top = e.clientY-3 + 'px';
        }

        ['col','row'].includes(pos) && selectMoreCellStyle(e);
        pos==='cell' && this.clickCell(e,cell);

      })
      
    },

    /*  */
    hideContextMenu() {
      const dom = $('#contextMenu-wrapper')[0];
			dom.style.left = '-9999px';
			dom.style.top = '-9999px';
    },

    /* 右键事件 */
    async handleContext(key) {

      let editHandlesMap = {
        1: this.insertDateOpen,
        7: this.edbCalculateInsertOpen
      }

      const keyMap = {
        'del': this.delColOrRow,//删除
        'insert-col-left': this.insertCol,//向左插入列
        'insert-col-right': this.insertCol,//向右插入列
        'insert-row-up': this.insertRow,//向上插入行
        'insert-row-down': this.insertRow,//向下插入行
        'insert-value': this.insertValue,//插入值
        'choose-target': this.selectTargetOpen,//选择指标插入值
        'insert-sys-date': this.insertDateOpen,//导入系统日期
        'insert-edb-date': this.insertDateOpen,//导入指标日期
        'reset': this.clearCell, //清空
        'cell-edit': this.selectCell ? editHandlesMap[this.selectCell.DataType] : null
      }
      keyMap[key] && keyMap[key](key)
      
      key!=='insert-edb-calculate' && this.hideContextMenu()
    },

    /* 打开选择指标弹窗  
    打开弹窗后仍可以在页面上点击 多存一个选择指标时的当前单元格信息 */
    selectTargetOpen() {
      this.insertTargetCell = this.selectCell;
      resetDialogCellStyle();
      setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target')
      this.isSelectTargetValueDialog = true;

      this.isInsertCalculate = false;
      this.$refs.calculateEdbDiaRef.initData();
    },

    /* 插入选择指标的值 */
    insertSelectData({ edbId,value,date }) {

      this.insertTargetCell.DataType = 5;
      this.insertTargetCell.ShowValue = value;
      this.insertTargetCell.Value = value;
      this.insertTargetCell.EdbInfoId = edbId;
      this.insertTargetCell.DataTime = date;

      this.$message.success('插入成功')

      //如果有关联表格日期就建立新的关联关系
      if(date) {
        let relation = {
          insert_cell: {
            key: this.insertTargetCell.Uid,
            relation_date: this.selectCell.Uid,
            relation_edb: '',
          }
        }
  
        this.setRelation(relation,5);
      }

    },

    /* 清除单元格内容 格式 关联关系 */
    clearCell() {
      if([4,5].includes(this.selectCell.DataType)) resetRelationStyle();

      this.selectCell.DataType = 3;
      this.selectCell.ShowValue = '';
      this.selectCell.Value = '';
      this.selectCell.DataTime = '';
      this.selectCell.DataTimeType = 0;
      this.selectCell.EdbInfoId = 0;

      this.checkCellRelation(this.selectCell)
    },

    /* 删除行列 */
    delColOrRow() {
      let { rindex,cindex } = this.rightClickCell;

      if(rindex==='-1') { //删除列
        console.log('删除列',cindex)

        if(this.columnHeader.length === 1) return this.$message.warning('请至少保留一列')

        let index = this.columnHeader.findIndex(_ => _ === cindex);

        //删除时清除关系
        if(this.insertRelationArr.length) {
          let delCellIds = this.config.data.map(row => row[index].Uid);
          
          this.clearRelationInsertCell(delCellIds);
        }

        this.config.data.forEach(row => {
          row.splice(index,1)
        })
      }else if(cindex === '-1') { //删除行
        console.log('删除行',rindex)

        if(this.rowHeader.length === 1) return this.$message.warning('请至少保留一行')

        let index = this.rowHeader.findIndex(_ => _ === rindex)
        
        if(this.insertRelationArr.length) {
          //删除时清除关系
          let delCellIds = this.config.data[index].map(cell => cell.Uid);
          
          this.clearRelationInsertCell(delCellIds);
        }

        this.config.data.splice(index,1)

      }
    },

    /* 删除时清除关联关系 和删除单元格有关联的插入值单元格和 */
    clearRelationInsertCell(delCellIds) {
      //清除关联插入值得单元格
      let haveRelationArr = this.insertRelationArr.filter(_ => delCellIds.includes(_.relation_date.key)||delCellIds.includes(_.relation_edb.key));
      // console.log(haveRelationArr)

      haveRelationArr.forEach(relation => {
        !delCellIds.includes(relation)&&this.updateInsertCell(relation.key);
      })

      this.insertRelationArr = this.insertRelationArr.filter(_ => !delCellIds.includes(_.key)&&!delCellIds.includes(_.relation_date.key)&&!delCellIds.includes(_.relation_edb.key))
    },

    /* 插入列 */
    insertCol(key) {
      let { cindex } = this.rightClickCell;
      
      let index = this.columnHeader.findIndex(_ => _ === cindex);

      this.config.data.forEach((row,rindex) => {
        row.splice(key==='insert-col-left'?index:index+1,0,{
          ShowValue: "",
          Value: "",
          DataType: 3,
          DataTime: "",
          EdbInfoId: 0,
          Uid: md5.hex_md5(`${new Date().getTime()}${rindex}`)
        })
      })
      
    },

    /* 插入行 */
    insertRow(key) {
      let { rindex } = this.rightClickCell;
      
      let index = this.rowHeader.findIndex(_ => _ === rindex)

      let row = new Array(this.columnHeader.length).fill("").map((_,cindex) => ({
        ShowValue: "",
        Value: "",
        DataType: 3,
        DataTime: "",
        EdbInfoId: 0,
        Uid: md5.hex_md5(`${new Date().getTime()}${cindex}`)
      }));

      this.config.data.splice( key==='insert-row-up'?index:index+1,0,row)

    },

    /* 单元格类型5 浮到上面展示指标信息浮窗 */
    async getRelationEdbInfo({EdbInfoId,DataType}) {
      if(![5,7].includes(DataType)||this.disabled) return

      const res = await dataBaseInterface.targetDetail({EdbInfoId})

      if(res.Ret !== 200) return

      this.cellrelationEdbInfo =  res.Data;
    },

    /* 导入系统/指标日期弹窗 */
    insertDateOpen(type) {
      this.insertTargetCell = this.selectCell;
      resetDialogCellStyle();

      if(type === 'cell-edit') { //编辑日期
        const { DataTimeType } = this.insertTargetCell;
        this.insertDateInfo = {
          key: DataTimeType===1? 'insert-sys-date' : 'insert-edb-date',
          ...this.insertTargetCell
        }
      }else {
        this.insertDateInfo = {
          key:type
        }
      }
      this.isInsertDateDialog = true;

      this.isSelectTargetValueDialog = false;
      this.$refs.selectTargetValueRef.initData();
      this.isInsertCalculate = false;
      this.$refs.calculateEdbDiaRef.initData();
    },

    /* 插入系统/指标日期 */
    insertDatehandle({insertValue,dataTimeType,str}) {

      this.insertTargetCell.DataType = 1;
      this.insertTargetCell.DataTimeType = dataTimeType;
      this.insertTargetCell.ShowValue = insertValue;
      this.insertTargetCell.Value = str;
      this.insertTargetCell.EdbInfoId = 0;
      this.insertTargetCell.DataTime = insertValue;
    },

    /* 指标计算弹窗 */
    edbCalculateInsertOpen(item) {
      this.insertTargetCell = this.selectCell;
      resetDialogCellStyle();
      setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target');

      if(item === 'cell-edit') { //编辑
        const { Value } = this.insertTargetCell;

        let menuInfo = this.config.contextMenuOption
          .find(_ => _.key==='insert-edb-calculate').children
          .find(menu => menu.source === JSON.parse(Value).Source);

        this.insertCalculateInfo = {
          ...menuInfo,
          formStr: Value,
        }
      }else {
        this.insertCalculateInfo = {
          ...item
        }
      }
      this.isInsertCalculate = true;

      this.isSelectTargetValueDialog = false;
      this.$refs.selectTargetValueRef.initData();
    },

    /* 导入指标计算值 */
    insertCalculateData(item) {
      console.log(item)
      const { InsertValue,EdbInfoId,Str,Date } = item;
      this.insertTargetCell.DataType = 7;
      this.insertTargetCell.ShowValue = InsertValue;
      this.insertTargetCell.Value = Str;
      this.insertTargetCell.EdbInfoId = EdbInfoId;
      this.insertTargetCell.DataTime = Date;

      this.$message.success('插入成功')

      //如果有关联表格日期就建立新的关联关系
      if(Date) {
        let relation = {
          insert_cell: {
            key: this.insertTargetCell.Uid,
            relation_date: this.selectCell.Uid,
            relation_edb: '',
          }
        }
  
        this.setRelation(relation,7);
      }
    },

    /* 初始化8行5列 */
    initData(initData=null) {
      console.log('initData');
      this.hasInit=false
      if(initData) {
        const { CellRelation,Data } = initData;
        this.config.data = Data;
        this.insertRelationArr = JSON.parse(CellRelation);
      }else {

        this.config.data = new Array(8).fill("").map((_,_rindex) => {
          return new Array(5).fill("").map((cell,_cindex) => ({
            ShowValue: "",
            Value: "",
            DataType: 3,
            DataTimeType: 0,
            DataTime: "",
            EdbInfoId:0,
            Uid: md5.hex_md5(`${new Date().getTime()}${_rindex}${_cindex}`)
          }));
        });
      }
      this.$nextTick(()=>{
        this.hasInit=true
      })
    },

     /* 处理因数结构 =a1+b1 => [{ Tag: a,Row:1,Key:'' }] */
    dealFormulaConstruction(val) {
      // 提取因数数组
      let factors = extractFactorsFromFormula(val)
      let arr = factors.map(str => ({
          Tag: splitString(toUpperCase(str))[0],
          Row: splitString(toUpperCase(str))[1],
          Key: findCellKeyByFactor(str)
      }))
      return JSON.stringify(arr)
    },


    /* 要支持复制粘贴把公式也带过去 公式单元格类型为6 其余就正常复制文本 */
    copyCellHandle(e,cell) {
      this.copyCellItem = cell;
      // 阻止默认的复制操作
      e.preventDefault();
    },

    /* 要支持复制粘贴把公式也带过去 公式单元格类型为6 其余就正常复制文本 */
    pasteCellHandle(e,cell) {
      if(this.copyCellItem.DataType === 6) {
        cell.DataType = this.copyCellItem.DataType;
        cell.ShowValue = this.copyCellItem.ShowValue;
        cell.Value = this.copyCellItem.Value;
        cell.DataTime = this.copyCellItem.DataTime;
        cell.EdbInfoId = this.copyCellItem.EdbInfoId;
      }else {
        cell.DataType = 3;
        cell.ShowValue = this.copyCellItem.ShowValue;
        cell.Value = this.copyCellItem.ShowValue;
        cell.DataTime = '';
        cell.EdbInfoId = 0;
      }

      // 阻止默认的粘贴操作
      e.preventDefault();
    },

    /* 单元格enter时切换编辑状态 */
    keyEnterHandle(e,cell) {
      if(e.keyCode===13) {
        //非得搞个要回车失焦
        e.target.nodeName && e.target.blur();
        this.$refs[`inputRef${e.target.dataset.key}`]&&this.$refs[`inputRef${e.target.dataset.key}`][0].close()

        cell.DataType===6 && this.$set(cell,'CanEdit',false)
        // this.calculateClickCell = null
      }
    },

    /* 支持公式单元格双击切换状态 */
    dblClickCellHandle(e,cell) {
      if(this.disabled || cell.DataType!==6) return

      this.$set(cell,'CanEdit',true)

      // this.calculateClickCell = cell;
      // setRelationStyle({ key:cell.Uid },'td-choose-insert-target')

      this.$nextTick(() => {
        if(e.target.childNodes[0].childNodes[0].childNodes[1].nodeName==='INPUT') e.target.childNodes[0].childNodes[0].childNodes[1].focus();
      })
    },

    /* 处理保存的参数 */
    getSaveParams() {
      const { data } = this.config;

      let params = {
        CellRelation: JSON.stringify(this.insertRelationArr),
        Data: data
      }

      return params
    },

    /* tab禁掉 */
    handlekeyDownKeys(e) {
      if(e.keyCode === 9) {
        e.preventDefault();
      }
    }
  },
};
</script>
<style scoped lang="scss">
.nodata {
  text-align: center;
  font-size: 16px;
  color: #666;
  padding: 100px 0;
}
.table-wrapper {
  width: 100%;
  overflow: auto;

  .formula-wrapper {
    height: 42px;
    display: flex;
    align-items: center;
    background: #fff;
    border-radius: 4px;
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
    border: 1px solid #DCDFE6;
    margin-bottom: 15px;
    padding: 0 15px;
  }
  .table td,th {
    width: 104px;
    min-width: 104px;
    height: 35px;
    max-height: 35px;
    background: #fff;
    text-align: center;
    word-break: break-all;
    border: 1px solid #dcdfe6;
    overflow: hidden;
    text-overflow: ellipsis;
    position: relative;
    color: #606266;

    &.td-chose::after {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      content: "";
      display: block;
      outline: 0;
      border: 2px solid #0033ff;
      box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
    }
    &.td-relation::after {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      content: "";
      display: block;
      outline: 0;
      border: 2px dashed #0033ff;
      box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
    }
    &.td-col-select::after {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      content: "";
      display: block;
      outline: 0;
      border: 1px solid rgb(24, 173, 24);
      border-bottom: none;
      border-top: none;
    }
    &.td-row-select::after {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      content: "";
      display: block;
      outline: 0;
      border: 1px solid rgb(24, 173, 24);
      border-left: none;
      border-right: none;
    }
    &.td-choose-insert-target::after {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      content: "";
      display: block;
      outline: 0;
      border: 2px dashed orange;
      box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
    }
  }

  .th-tg {
    background: #ebeef5;
    &:hover {
      cursor: pointer;
      background: #ddd;
      /* border: 2px solid #409eff; */
    }
    &.sm {
      width: 36px;
      min-width: 36px;
      max-width: 36px;
    }
  }
  //整行选中
  tr {
    position: relative;
    &.choose-all::after {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      content: "";
      display: block;
      outline: 0;
      border: 2px solid #5897fb;
      box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
    }
  }

  .contextMenu-wrapper {
    position: fixed;
    z-index: 99;
    top: -9999px;
    left: -9999px;
    background: #fff;
    padding: 10px 0;
    /* border: 1px solid #999; */
    box-shadow: 0 1px 4px #999;
    .item {
      padding: 10px 25px;
      cursor: pointer;
      &:hover {
        background-color: #f5f7fa;
      }
      &:hover .subMenu-wrapper {
        display: block;
      }
    }

    .subMenu-wrapper {
      display: none;
      padding: 10px 0;
      box-shadow: 0 1px 4px #999;
      background: #fff;
      position: absolute;
      right: -172px;
      top:-205px;
      max-height: 400px;
      overflow-y: auto;
    }
  }
}
</style>
<style lang="scss">
.table-wrapper {
  td {
    .el-input__inner {
      border: none;
      outline: none;
      text-align: center;
      height: 34px;
      line-height: 34px;
    }
  }
  .el-input.is-disabled .el-input__inner {
    background-color: #fff;
  }
}
.formula-wrapper .el-input__inner { border: none; outline: none; }
.edb-select-popover {
  width: 300px !important;
  .edb-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .edb-item-name {
      max-width: 260px;
    }
  }
}
</style>
