<script setup lang="ts">
import { onMounted, onUnmounted, reactive, ref, nextTick, createVNode, render, watch, computed } from 'vue'
import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
import Handsontable from "handsontable";
import { HotTable } from '@handsontable/vue3'
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n'
import { registerAllModules } from 'handsontable/registry'
import 'handsontable/styles/handsontable.css'
// import 'handsontable/styles/ht-theme-main.css'
import 'handsontable/styles/ht-theme-classic.css';
registerAllModules()
registerLanguageDictionary(zhCN)
import { handlerDropdownRenderer } from './dropdown'
import { handlerTableRenderer } from './table'
import { handlerDuplicateCodeRenderer } from './text'
import { computeCodeColWidth,codeRenderer } from './tree'
import ContextMenu from './contextmenu.vue'
import { handleRowOperation } from '#/components/db-hst/tree'
// import { sourceDataObject } from './mockData'
// const language = ref('zh-CN')
defineOptions({ name: 'DbHst' });
const componentProps = defineProps<{ 
  settings?: any
  contextMenuItems?: Array<{
    key: string
    name: string
    callback?: (hotInstance: any) => void
    separator?: boolean
  }>
}>()
// 导入和注册插件和单元格类型
// import { registerCellType, NumericCellType } from 'handsontable/cellTypes';
// import { registerPlugin, UndoRedo } from 'handsontable/plugins';
// registerCellType(NumericCellType);
// registerPlugin(UndoRedo);
// const tableHeight = computed(() => componentProps.height ?? 0)
// const defaultData = ref<any[][]>(Array.from({ length: 30 }, () => Array(componentProps.columns?.length ?? 0).fill('')))
const hotTableComponent = ref<any>(null)
const selectedRow = ref<number | null>(null) // 记录当前选中的行
const codeColWidth = ref<number>(120)


// const colHeaders = ref<string[]>([])
let defaultSettings = {
  // themeName: 'ht-theme-main',
  themeName: 'ht-theme-classic',
  
  language: 'zh-CN',
  // data: sourceDataObject,
  // colWidths: [100, 120, 100, 100, 100, 100],
  // rowHeights: [30, 30, 30, 30, 30, 30],
  colWidths: 120,  // 固定列宽
  // colWidths(index) {
  //   return (index + 1) * 40;
  // },
  // colWidths: undefined,
  rowHeights: 23,  // 固定行高  
  wordWrap: false,// 禁止单元格内容自动换行

  //manualColumnMove: true,
  manualColumnResize: true,
  autoRowSize: false,
  autoColumnSize: false,

  renderAllRows: false,
  viewportColumnRenderingOffset: 12,//渲染列数
  viewportRowRenderingOffset: 12,//渲染行数
  // colHeaders: componentProps.colHeaders ?? [],
  rowHeaders: false,
  // columns: componentProps.columns ?? [],
  autoWrapRow: true,
  autoWrapCol: true,
  width: '100%',
  // height: 'auto',
  // height: tableHeight.value,
  // height: 200,
  // stretchH: 'all',
  // loading: true,
  //contextMenu: true,
  // dialog: true,
  // dialog: {
  //   content: 'This dialog can be controlled programmatically.',
  //   closable: true,
  //   contentBackground: true,
  //   background: 'semi-transparent',
  // },
  licenseKey: '424fc-f3b67-5905b-a191b-9b809',
  // 如果使用第一行作为列头（colHeaders: false），添加以下配置
  // cells: function(row: number, col: number) {
  //   const cellProperties: any = {};
    
  //   // 如果 colHeaders 为 false，将第一行设置为列头样式
  //   if (row === 0) {
  //     cellProperties.readOnly = true; // 不可编辑
  //     cellProperties.className = 'custom-header-row'; // 自定义样式类
  //     cellProperties.renderer = function(instance: any, td: HTMLTableCellElement, row: number, col: number, prop: any, value: any, cellProperties: any) {
  //       Handsontable.renderers.TextRenderer.apply(this, arguments as any);
  //       td.style.fontWeight = 'bold';
  //       td.style.backgroundColor = '#f5f5f5';
  //       td.style.textAlign = 'center';
  //       td.style.borderBottom = '2px solid #ddd';
  //     };
  //   }
    
  //   return cellProperties;
  // },
  // afterSelection(row1: number, _col1: number, _row2: number, _col2: number) {
  //   const hot = this as any
  //   if (selectedRow.value !== null && selectedRow.value !== row1) {
  //     const colCount = hot.countCols()
  //     for (let c = 0; c < colCount; c++) {
  //       const meta = hot.getCellMeta(selectedRow.value, c)
  //       const classes = (meta.className || '').split(' ').filter(Boolean)
  //       const idx = classes.indexOf('row-highlight')
  //       if (idx !== -1) classes.splice(idx, 1)
  //       hot.setCellMeta(selectedRow.value, c, 'className', classes.join(' '))
  //     }
  //   }

  //   selectedRow.value = row1

  //   const colCount = hot.countCols()
  //   for (let c = 0; c < colCount; c++) {
  //     const meta = hot.getCellMeta(row1, c)
  //     const classes = (meta.className || '').split(' ').filter(Boolean)
  //     if (!classes.includes('row-highlight')) classes.push('row-highlight')
  //     hot.setCellMeta(row1, c, 'className', classes.join(' '))
  //   }

  //   hot.render()
  // },
  //afterDeselect() {
    // const hot = this as any
    // if (selectedRow.value === null) return
    // const colCount = hot.countCols()
    // for (let c = 0; c < colCount; c++) {
    //   const meta = hot.getCellMeta(selectedRow.value, c)
    //   const classes = (meta.className || '').split(' ').filter(Boolean)
    //   const idx = classes.indexOf('row-highlight')
    //   if (idx !== -1) classes.splice(idx, 1)
    //   hot.setCellMeta(selectedRow.value, c, 'className', classes.join(' '))
    // }
    // selectedRow.value = null
    // hot.render()
  //},
  
  // modifyColWidth(width: number, col: number) {
  //   const hot = hotInstance.value
  //   if (!hot) return width
  //   const codeCol = hot.propToCol('code')
  //   // console.log('modifyColWidth',codeCol,width)
  //   return col === codeCol ? (codeColWidth.value ?? width) : width
  // },
  // afterChange(changes: any, source: string) {
  //   if (!changes || !hotInstance.value) return
  //   if (source !== 'edit' && source !== 'Autofill' && source !== 'UndoRedo') return
  //   const hot = hotInstance.value
  //   const codeCol = hot.propToCol('code')
  //   const hasCodeEdit = changes.some((c: any) => c && (c[1] === 'code' || c[1] === codeCol))
  //   // console.log('afterChange',changes,hasCodeEdit, codeCol)
  //   if (!hasCodeEdit) return
  //   codeColWidth.value = computeCodeColWidth(hot)
  //   // console.log('afterChange',codeColWidth.value)
  //   hot.render()
  //   // console.log('afterChange',codeColWidth.value)
  // },
  afterOnCellContextMenu: () => {
    // Handsontable 内置右键菜单打开后，关闭自定义菜单
    contextMenuRef.value?.hideContextMenu?.()
  },
}
// 合并外部 settings 和默认配置
let hotSettings = {}
  // 保留必要的回调函数

const hotInstance = ref<any>(null)
const contextMenuRef = ref<any>(null)

// 处理右键菜单事件
const handleContextMenu = (event: MouseEvent) => {
  contextMenuRef.value?.handleContextMenu(event)
}

onMounted(() => {
  hotInstance.value = hotTableComponent.value?.hotInstance
})
onUnmounted(() => {
})

watch(
  () => componentProps.settings,
  (newSettings) => {
    if (!newSettings) return
    
    const merged = {
      ...defaultSettings,
      ...newSettings,
    }
    Object.assign(hotSettings, merged)
    hotSettings = merged
    
    // console.log(merged)
  },
  {  immediate: true,deep:true }
)

const loadData = (rows: any[][]) => {
 
  if (!hotInstance.value) return
  // hotInstance.value.loadData(rows.length === 0?defaultData.value:rows)
  hotInstance.value.loadData(rows)
  //console.log('Source Data:', hotInstance.value.getSourceData());
}

const updateCodeColWidth = () => {
  if (!hotInstance.value) return
  const newWidth = computeCodeColWidth(hotInstance.value)
  
  // 如果宽度没有变化，不需要更新
  if (newWidth === codeColWidth.value) return
  
  codeColWidth.value = newWidth
  
  // 查找配置了 code: true 的列
  const currentSettings = hotInstance.value.getSettings()
  const columns = currentSettings.columns || []
  const codeColIndex = columns.findIndex((col: any) => col.code === true)
  
  if (codeColIndex !== null && codeColIndex >= 0) {
    // 获取当前列数
    const colCount = hotInstance.value.countCols()
    const currentColWidths = currentSettings.colWidths
    
    // 构建新的列宽数组
    const newColWidths: number[] = []
    for (let i = 0; i < colCount; i++) {
      if (i === codeColIndex) {
        newColWidths[i] = codeColWidth.value
      } else {
        // 获取其他列的当前宽度
        if (Array.isArray(currentColWidths)) {
          newColWidths[i] = currentColWidths[i] || 100
        } else if (typeof currentColWidths === 'function') {
          newColWidths[i] = 100
        } else {
          newColWidths[i] = currentColWidths || 100
        }
      }
    }
    console.log(newColWidths)
    // 更新列宽
    hotInstance.value.updateSettings({
      colWidths: newColWidths
    })
  }
  
  hotInstance.value.render()
}
defineExpose({ loadData, hotTableComponent, hotInstance, updateCodeColWidth, codeColWidth })


Handsontable.renderers.registerRenderer("db-table", handlerTableRenderer);
Handsontable.renderers.registerRenderer("db-dropdown", handlerDropdownRenderer);
Handsontable.renderers.registerRenderer("db-duplicate", handlerDuplicateCodeRenderer);
</script>

<template>
  <div @contextmenu="handleContextMenu">
    <hot-table ref="hotTableComponent" :settings="hotSettings"></hot-table>
    <ContextMenu ref="contextMenuRef" :hotTableComponent="hotTableComponent" :menuItems="componentProps.contextMenuItems" />
  </div>
   
  <!-- <div id="hot-dialog-container" style="display:none">
    <div class="ht-dialog-content">
      <h3>执行操作</h3>
      <el-table :data="gridData">
      <el-table-column property="date" label="Date" width="150" />
      <el-table-column property="name" label="Name" width="200" />
      <el-table-column property="address" label="Address" />
    </el-table>
      <div style="margin-top:12px;display:flex;gap:8px;justify-content:flex-end">
        <button class="el-button el-button--default el-button--small btn-cancel">取消</button>
        <button class="el-button el-button--primary el-button--small btn-ok">确定</button>
      </div>
    </div>
  </div>
  </div> -->
  <!-- <el-popover
    ref="popoverRef"
    :virtual-ref="popoverButtonRef"
    v-model:visible="isPopoverOpen"
    trigger="manual"
    virtual-triggering
    width="auto"
  >
   <el-table :data="gridData" size="small" @row-click="onClickOutside" border>
        <el-table-column width="150" property="date" label="date" />
        <el-table-column width="100" property="name" label="name" />
        <el-table-column width="300" property="address" label="address" />
      </el-table>
  </el-popover> -->
</template>

<style lang="css">
  /* 禁止单元格内容换行 */
.handsontable td {
  white-space: nowrap !important;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 自定义滚动条样式 */
/* .ht_master .wtHolder::-webkit-scrollbar {
    width: 10px;
    background-color: #f1f1f1;
}

.ht_master .wtHolder::-webkit-scrollbar-thumb {
    background-color: #888;
    border-radius: 6px;
    border: 3px solid #ffffff;
}

.ht_master .wtHolder::-webkit-scrollbar-thumb:hover {
    background-color: #555;
} */
/* 滚动条width */
.ht_master .wtHolder{
  /* overflow: hidden !important; */
    scrollbar-width: thin;
    scrollbar-color: #a6a8ac #ecf0f1;
}
/* dropdown */
.ht-cell-dropdown { display: flex; align-items: center; justify-content: center; width: 100%; position: relative; box-sizing: border-box; height: 100%; }
.ht-cell-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ht-cell-value:empty::after { content: "\200b"; }
.ht-cell-caret { position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid #979797; }
.ht-dropdown-menu { position: absolute; background: #fff; border: 1px solid var(--el-border-color-light); border-radius: 8px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); min-width: 160px; max-height:300px; overflow: auto; z-index: 10000; }
.ht-dropdown-menu.is-bottom { margin-top: 4px; }
.ht-dropdown-menu.is-top { margin-bottom: 4px; }
.ht-dropdown-item { padding: 8px 12px; cursor: pointer; font-size: 13px; }
.ht-dropdown-item:hover { background-color: #f5f7fa; }
.ht-dropdown-item.is-selected { background-color: #eef3ff; }
.ht-dropdown-item.is-disabled { color: #c0c4cc; cursor: not-allowed; }
/* tree */
.handsontable .text-relative span.ht_nestingLevel_empty{
  position: relative;
    display: inline-block;
    width: 5px;
    height: 1px;
    order: -2;
}
.handsontable .text-relative span:last-child {
    padding-left: calc(var(--ht-icon-size) + 5px);
}
/* table */

/* 自定义下拉渲染样式 */
.hot-cell-dropdown { display: flex; align-items: center; gap: 6px; padding: 0 6px; }
.hot-dropdown-display { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hot-dropdown-text { font-size: 12px; color: #1f2328; }
.hot-dropdown-placeholder { font-size: 12px; color: #a0a0a0; }

.hot-dropdown-trigger {
    margin-left: auto;
    border: none;
    background: transparent;
    position: relative;
    cursor: pointer;
    width: 16px;
    height: 16px;
    font-size: 0;
}
.hot-dropdown-trigger::after {
    width: 16px;
    height: 16px;
    -webkit-mask-size: contain;
    -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cpath d='m21 21-4.35-4.35'%3E%3C/path%3E%3C/svg%3E");
    background-color: currentColor;
}
.hot-dropdown-trigger::after {
    content: "";
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0.6;
}
.hot-dropdown { position: fixed; z-index: 10000; background: #fff; border: 1px solid #e5e7eb; box-shadow: 0 8px 24px rgba(0,0,0,0.12); border-radius: 6px; max-height: 260px; overflow: hidden; will-change: top, left; display: flex; flex-direction: column; }
.hot-dropdown--up { border-top-left-radius: 6px; border-top-right-radius: 6px; }
.hot-dropdown--down { border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; }
.hot-dropdown-search { padding: 0px; border-bottom: 1px solid #e5e7eb; background: #fff; position: sticky; top: 0; z-index: 1; }
.hot-dropdown-search-input { width: 100%; padding: 6px 10px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 12px; outline: none; transition: border-color 0.2s; }
.hot-dropdown-search-input:focus { border-color: #3b82f6; }
.hot-dropdown-table-wrapper { overflow: auto; flex: 1; }
.hot-dropdown-table { width: 100%; border-collapse: collapse; font-size: 12px; text-align: center; }
.hot-dropdown-table thead th { position: sticky; top: 0; background: #f9fafb; font-weight: 600; color: #374151; padding: 8px; border-bottom: 1px solid #e5e7eb; text-align: center; }
.hot-dropdown-table tbody td { padding: 8px; border-bottom: 1px solid #f3f4f6; color: #374151; }
.hot-dropdown-row { cursor: pointer; }
.hot-dropdown-row:hover { background: #f3f4f6; }


/* 整行高亮样式 */
.row-highlight {
  background-color: #e9ecfc !important; /* 浅蓝色背景 */
}

/* 确保 Handsontable 右键菜单在 ElDialog 之上 - 必须是全局样式 */
.handsontable.htDropdownMenu:not(.htGhostTable),
.handsontable.htContextMenu:not(.htGhostTable),
.handsontable.htFiltersConditionsMenu:not(.htGhostTable) {
  z-index: 9999 !important;
}

.ht-id-cell {
  position: relative !important;
  z-index: 3 !important;
  overflow: visible !important;
}

.ht-id-icon {
  position: absolute;
  top: 0px;
  right: -14px;
  width: 14px;
  height: 14px;
  display: none;
  cursor: pointer;
  z-index: 4;
}

.ht-id-cell.current .ht-id-icon,
.ht-id-cell.area .ht-id-icon {
  display: inline-flex;
}

.handsontable {
  --ht-tree-line-color: #7c7c7c;
  --ht-tree-line-style: solid;
  --ht-tree-line-width: 1px;
  --ht-tree-indent: 14px;
}
/** 新树形连接线 */
.handsontable .ht_treeCell {
  display: flex;
  align-items: stretch;
  height: 100%;
}

.handsontable .ht_treeIndentLayer {
  flex: 0 0 auto;
  height: 100%;
}

.handsontable .ht_treeContent {
  display: flex;
  align-items: center;
  gap: 6px;
}

.handsontable .ht_treeToggleSpacer {
  display: inline-block;
  width: var(--ht-icon-size);
  height: var(--ht-icon-size);
  flex: 0 0 auto;
}


.handsontable .ht_treeContent {
  min-width: 0;
}

/* 整行高亮样式 */
.handsontable td.ht_rowHighlight:not(.current):not(.area) {
  background-color: #e9ecfc;
}

</style>
