<script setup lang='ts'>
import { PropType,computed,ref,nextTick } from 'vue';
import { isMobile } from '@/utils/utils'
import { useRoute } from 'vue-router';
const route = useRoute();

const props = defineProps({
  data: {
    type: Array as PropType<any[]>,
    required: true
  },
  config: {
    type: Object
  }
})


//手机端pc端又要不同样式
const dynamicSty = computed(()=>{
  return isMobile() ? 'mobile-sty' : 'pc-sty';
})

const HtObj=ref({
  0:"center",
  1:'left',
  2:'right'
})

// 默认取消鼠标右键操作
const preventRight=()=>{
  document.addEventListener('contextmenu', function(event) {
    event.preventDefault();
  });
}
preventRight()

const moveVal=ref(6)

/* 右键 */
const activeNames=ref('')
const sizeOptions=ref([
    { label:'5',val:'5' },
    { label:'6',val:'6' },
    { label:'7',val:'7' },
    { label:'8',val:'8' },
    { label:'9',val:'9' },
    { label:'10',val:'10' },
    { label:'11',val:'11' },
    { label:'12',val:'12' },
    { label:'13',val:'13' },
    { label:'14',val:'14' },
    { label:'15',val:'15' },
    { label:'16',val:'16' },
    { label:'17',val:'17' },
    { label:'18',val:'18' },
    { label:'20',val:'20' },
    { label:'24',val:'24' },
    { label:'28',val:'28' },
    { label:'32',val:'32' },
    { label:'36',val:'36' },
    { label:'40',val:'40' },
])
const contextMenuRef=ref(null)

function rightClickHandle(e,cell,rowIndex,colIndex) {
  if(route.query.type==2){
    return
  }
  if(clickStatus.value || !selectionStart.value || !selectionEnd.value) return
  const start = {
    row: Math.min(selectionStart.value.row, selectionEnd.value.row),
    col: Math.min(selectionStart.value.col, selectionEnd.value.col)
  };
  const end = {
    row: Math.max(selectionStart.value.row, selectionEnd.value.row),
    col: Math.max(selectionStart.value.col, selectionEnd.value.col)
  };
  if(rowIndex >= start.row && rowIndex <= end.row && colIndex >= start.col && colIndex <= end.col){
    nextTick(() => {
      let dom = contextMenuRef.value;
      console.log(dom)
      console.log(e.clientX,e)
      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';
      }
      if(e.clientX > window.innerWidth/2){
        dom.style.left = e.clientX-dom.offsetWidth-3 + 'px';
      }
    })
  }
}

function hideContextMenu() {
  const dom = contextMenuRef.value;
  dom.style.left = '-9999px';
  dom.style.top = '-9999px';
}

function chooseCellSize(val){
  let indexArr = getCellIndices(selectionStart.value.row,selectionEnd.value.row,selectionStart.value.col,selectionEnd.value.col);
  console.log(indexArr)
  indexArr.forEach(el=>{
    props.data[el.row][el.column].fs=val
  })
  resetSelect()
  hideContextMenu()
}

// 获取区间所有坐标
function getCellIndices(startRow, endRow, startCol, endCol) {
    const indices = [];
    for (let i = startRow; i <= endRow; i++) {
        for (let j = startCol; j <= endCol; j++) {
            indices.push({ row: i, column: j });
        }
    }
    return indices;
}

// 选区选择
const selectionStart=ref(null)
const selectionEnd=ref(null)
const clickStatus=ref(false)

function isCellSelected(row, col) {
  if (!selectionStart.value || !selectionEnd.value) {
    return false;
  }
  const start = {
    row: Math.min(selectionStart.value.row, selectionEnd.value.row),
    col: Math.min(selectionStart.value.col, selectionEnd.value.col)
  };
  const end = {
    row: Math.max(selectionStart.value.row, selectionEnd.value.row),
    col: Math.max(selectionStart.value.col, selectionEnd.value.col)
  };
  return (
    row >= start.row && row <= end.row && col >= start.col && col <= end.col
  );
}

function updateSelection(event,endRow, endCol) {
  if(event.button!=0){
    return
  }
  if (selectionStart.value&&clickStatus.value) {
    selectionEnd.value = { row: endRow, col: endCol };
  }
}

function endSelection(event,endRow, endCol) {
  if(event.button!=0){
    return
  }
  if (selectionStart.value&&clickStatus.value) {
    selectionEnd.value = { row: endRow, col: endCol };
    clickStatus.value=false
  }
}

//列宽行高
const getSize=(cell,index,key)=>{
  if(key=='width'){
    return columnWidths.value[index]?columnWidths.value[index]+'px':''
  }else{
    return rowHeights.value[index]?rowHeights.value[index]+'px':'20px'
  }
}

const tableRef=ref(null)
const dragging=ref(false)
const dragState=ref({})
const columnWidths=ref([])

const draggingHeight=ref(false)
const dragStateHeight=ref({})
const rowHeights=ref([])

measureColumnWidths();

// 初始化获取高度
function measureColumnWidths(type='init') {
  nextTick(()=>{
    const table = tableRef.value;
    if (table) {
      const cells = table.rows[0].cells;
      let widthArr= Array.from(cells).map(cell => cell.offsetWidth);
      console.log(widthArr)
      const rows=table.rows
      let heightArr=Array.from(rows).map(row => row.offsetHeight);
      console.log(heightArr)
      if(type=='init'){
        columnWidths.value=widthArr
        rowHeights.value=heightArr
        // console.log(columnWidths.value)
        // console.log(rowHeights.value)
      }
    }
  })
}

// 鼠标拖动列宽
function handleMouseMove(event) {
  if(route.query.type==2){
    return
  }
  let target = event.target
  if (!dragging.value) {
      let rect = target.getBoundingClientRect()
      const bodyStyle = event.target.style
      if (rect.width > 12 && rect.right - event.pageX < moveVal.value) {
          // 拖拽的鼠标样式
          bodyStyle.cursor = 'col-resize'
      }else if (rect.height > 12 && rect.bottom - event.pageY < moveVal.value) {
          // 拖拽的鼠标样式
          bodyStyle.cursor = 'row-resize'
      } else if (!dragging.value) {
          bodyStyle.cursor = ''
      }
  }
}
function handleMouseOut(event) {
  event.target.style.cursor = ''
}

const startResize = (event,index,rowIndex) => {
  document.onselectstart = function() { return false; };//解决拖动会选中文字的问题
  if(route.query.type==2){
    return
  }
  if(event.button!=0){
    return
  }
  let target = event.target
  // let cellWidth=0
  // let startX, startWidth;
  let rect = target.getBoundingClientRect()
  if (rect.width > 12 && rect.right - event.pageX < moveVal.value) {
    // 开始拖拽
    // 当前拖拽的列所在的表格
    let tableEl = event.target
    // 当前所在列（单元格）
    let thEL = event.target
    dragging.value = true
     // 获取列宽拖拽的显示线（拖拽线）
    let resizeProxy = tableRef.value.querySelector(
        'tbody'
    )
    // console.log(resizeProxy)
    const columnRect = thEL.getBoundingClientRect()
    thEL.classList.add('noclick')
    dragState.value = {
        startMouseLeft: event.clientX, // 鼠标开始的地方
        columnWidth: columnRect.width, // th开始拖拽的宽度
    }
    resizeProxy.classList.remove('dn')
    document.onselectstart = function () {
        return false
    }
    document.ondragstart = function () {
        return false
    }
    // startX = event.clientX;
    // startWidth = event.target.clientWidth;
    const doResize = (event) => {
       // 拖拽中，拖拽线与鼠标的位置同步
        resizeProxy.style.left = event.clientX + 'px'
    };

    const endResize = (event) => {
        if(dragging.value){
        // 拖拽完毕
          const { startMouseLeft, columnWidth } = dragState.value
          const finalLeft = parseInt(resizeProxy.style.left, 10)
          const columnWidthDiff = finalLeft - startMouseLeft
          const finalColumnWidth = columnWidthDiff + columnWidth
          // console.log(finalColumnWidth)
          columnWidths.value[index]=finalColumnWidth>=30?finalColumnWidth:30
          console.log(columnWidths.value,111)
          let widthTotal=0
          columnWidths.value.forEach((item,colIndex)=>{
            widthTotal+=item
          })
          // console.log(widthTotal)
          //多出来的宽度
          let otherWidth=widthTotal-tableRef.value.offsetWidth
          // console.log(otherWidth)
          //其余每个减去的宽度
          let oneWidth=parseFloat((+(parseFloat(otherWidth).toFixed(2)))/(columnWidths.value.length-1)).toFixed(2)
          // console.log(oneWidth)
          columnWidths.value.forEach((item,colIndex)=>{
            if(colIndex!=index){
              columnWidths.value[colIndex]=item-(+oneWidth)
            }
          })
          // console.log(columnWidths.value,222)
          setTimeout(()=>{
            measureColumnWidths('get')
          },500)
          resizeProxy.style.left = '0px'
          event.target.style.cursor = ''
          dragging.value = false
          dragState.value = {}
          resizeProxy.classList.add('dn')
        }
        document.removeEventListener('mousemove', doResize);
        document.removeEventListener('mouseup', endResize);
        document.onselectstart = null
        document.ondragstart = null
        setTimeout(function () {
            thEL.classList.remove('noclick')
        }, 0)
      }

      document.addEventListener('mousemove',doResize);
      document.addEventListener('mouseup', endResize);
    }
    //else if (rect.height > 12 && rect.bottom - event.pageY < moveVal.value){
    //}else{
      //hideContextMenu()
      //clickStatus.value=true
      //selectionStart.value = null;
      //selectionEnd.value = null;
      //document.onselectstart = function() { return false; };//解决拖动会选中文字的问题
      //selectionStart.value = { row: rowIndex, col: index };
    //}
};

function resetSelect(){
  clickStatus.value=false
  selectionStart.value = null;
  selectionEnd.value = null;
}

const startResizeHeight= (event,index) => {
  if(route.query.type==2){
    return
  }
  if(event.button!=0){
    return
  }
  let target = event.target
  let rect = target.getBoundingClientRect()
  if (rect.height > 12 && rect.bottom - event.pageY < moveVal.value) {
    // 开始拖拽
    // 当前拖拽的列所在的表格
    let tableEl = event.target
    // 当前所在列（单元格）
    let thEL = event.target
    draggingHeight.value = true
     // 获取列宽拖拽的显示线（拖拽线）
    let resizeProxy = tableRef.value.querySelector(
        'tbody'
    )
    // console.log(resizeProxy)
    const columnRect = thEL.getBoundingClientRect()
    thEL.classList.add('noclick')
    dragStateHeight.value = {
        startMouseTop: event.clientY, // 鼠标开始的地方
        columnHeight: columnRect.height, // th开始拖拽的宽度
    }
    resizeProxy.classList.remove('dn')
    document.onselectstart = function () {
        return false
    }
    document.ondragstart = function () {
        return false
    }
    const doResize = (event) => {
       // 拖拽中，拖拽线与鼠标的位置同步
        resizeProxy.style.top = event.clientY + 'px'
    };

    const endResize = (event) => {
        if(draggingHeight.value){
          // 拖拽完毕
          const { startMouseTop, columnHeight } = dragStateHeight.value
          const finalTop = parseInt(resizeProxy.style.top, 10)
          const columnHeightDiff = finalTop - startMouseTop
          const finalColumnHeight = columnHeightDiff + columnHeight
          console.log(finalColumnHeight,index)
          rowHeights.value[index]=finalColumnHeight>=20?finalColumnHeight:20
          setTimeout(()=>{
            measureColumnWidths('get')
          },500)
          resizeProxy.style.top = '0px'
          event.target.style.cursor = ''
          draggingHeight.value = false
          dragStateHeight.value = {}
          resizeProxy.classList.add('dn')
        }
        document.removeEventListener('mousemove', doResize);
        document.removeEventListener('mouseup', endResize);
        document.onselectstart = null
        document.ondragstart = null
        setTimeout(function () {
            thEL.classList.remove('noclick')
        }, 0)
      }

      document.addEventListener('mousemove',doResize);
      document.addEventListener('mouseup', endResize);
    }
};

</script>

<template>
<div :class="['table-wrapper',dynamicSty ]">
  <table
    ref="tableRef"
    cellpadding="0" 
    cellspacing="0" 
    :class="config.Watermark?'background-watermark':'no-water'"
    :style="{'font-size':(config.FontSize||12)+'px',backgroundImage: 'url('+config.Watermark+')'}"
  >
    <tbody>
      <tr 
        :style="`height:${getSize(item,index,'height')}`"
        @mousedown="event=>startResizeHeight(event,index)"
        @mouseout="handleMouseOut"
        v-for="(item,index) in props.data"
        :key="index"
      >
      <!-- @contextmenu.prevent="event=>rightClickHandle(event,cell,index,cell_index)" -->
        <td
          @mouseout="handleMouseOut"
          @mousemove="handleMouseMove" 
          @mousedown="event=>startResize(event,cell_index,index)"
          @mouseover="event=>updateSelection(event,index, cell_index)"
          @mouseup="event=>endSelection(event,index, cell_index)"
          :class="['data-cell',{
            'one-bg':(index+1)%2&&index>0&&!config.Watermark,
            'tow-bg': (index+1)%2!==0&&index>0,
            'head-column': index === 0
          },{ 'selected': isCellSelected(index, cell_index) }]"
          v-for="(cell,cell_index) in item"
          :key="cell_index"
          :colspan="cell.mc.cs||1"
          :rowspan="cell.mc.rs||1"
          :style="`
            color: ${cell.fc};
            font-weight: ${cell.bl ? 'bold' : 'normal'};
            font-style: ${cell.it ? 'italic' : 'normal'};
            font-size: ${cell.fs ? cell.fs: config.FontSize?config.FontSize:12}px;
            background: ${cell.bg};
            text-align: ${HtObj[cell.HorizontalType]};
            width:${index==0?getSize(cell,cell_index,'width'):'auto'}
          `"
        >
          <!-- 单元格拆分 -->
          <div class="split-word" v-if="cell.ct.s">
            <span 
              v-for="(word,word_index) in cell.ct.s" 
              :key="`${index}_${cell_index}_${word_index}`"
              :style="`
                color: ${word.fc};
                font-weight: ${word.bl ? 'bold' : 'normal'};
                font-style: ${word.it ? 'italic' : 'normal'};
                text-decoration:${word.un?'underline':word.cl?'line-through':'normal'};
              `"
            >{{word.v}}</span>
          </div>
          <div v-else 
            :style="`text-decoration:${cell.un?'underline':cell.cl?'line-through':'normal'};`">{{cell.m}}</div>
        </td>
      </tr>
    </tbody>
  </table>
   <!-- 右键菜单 -->
   <div class="contextMenu-wrapper" ref="contextMenuRef" @mouseleave="()=>{activeNames=[];hideContextMenu()}">
      <el-collapse v-model="activeNames" accordion>
        <el-collapse-item name="1">
          <template #title>
            <div class="title-size">字号</div>
          </template>
          <div @click="chooseCellSize(item.val)" class="size-text" v-for="(item,index) in sizeOptions" :key="index">
            {{ item.label }}px
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
</div>
</template>

<style lang='less' scoped>
.selected {
  background-color: rgba(0, 82, 217, 0.1);
}
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: rgb(239, 239, 239);
  border-radius: 2px;
}
::-webkit-scrollbar-thumb {
  background: #ccc;
  border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
  background: #888;
}
::-webkit-scrollbar-corner {
  background: #666;
}
.table-wrapper {
  max-width: calc(100vw - 20px);
  margin: 0 auto;
  // margin-right: -5px;
  overflow: auto;
}
table {
  width: 100%;
  font-size: 14px;
  color: #333;
  td,
  th {
    // min-width: 120px;
    word-break: break-all;
    word-wrap: break-word;
    line-height: 1.2em;
    border: 1px solid #dcdfe6;
    // height: 40px;
    text-align: center;
    border-left: none;
    border-top: none;
    &:first-child {
			border-left: 1px solid #dcdfe6;
		}
  }

  .data-cell{
    color: #333;
    min-width: 30px;
    min-height: 20px;
    padding: 0 !important;
    &>div{
      padding: 0.4em !important;
    }
    &.one-bg {
      background-color: #EFEEF1;
    }
    &.two-bg {
      background-color: #fff;
    }
  }

  .thead-sticky {
    position: sticky;
    top: 0;
  }

  .head-column {
    background-color: #505B78;
    color: #fff;
  }
  .split-word {
    span { display: inline; }
  }
}

.no-water{
  td,
  th {
    background-color: #fff;
  }
  .head-column {
    background-color: #505B78;
    color: #fff;
  }
}

.pc-sty table {
  table-layout: auto;
  td,th {
    width: auto;
    height: auto;
    padding: 0.4em 0;
  }
}

.mobile-sty table {
  table-layout: auto;
  td,th {
    min-width: 120px;
    height: 40px;
  }
}
.background-watermark{
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 100%;
}

.contextMenu-wrapper {
    position: fixed;
    z-index: 99;
    top: -9999px;
    left: -9999px;
    background: #fff;
    min-width: 100px;
    max-height: 100px;
    overflow-y: auto;
    /* 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;
      }
    }
    .title-size{
      text-align: center;
      width: 100%;
      position: absolute;
    }
    .size-text{
      text-align: center;
      padding: 5px 0;
      cursor: pointer;
      &:hover{
        background: #f5f7fa;
      }
    }
  }
</style>