let currentDropdownEl: HTMLElement | null = null
let currentOnDocClick: ((e: MouseEvent) => void) | null = null
let currentAnchor: { instance: any; row: number; col: number; td: HTMLTableCellElement | null } | null = null

const clamp = (x: number, min: number, max: number) => (x < min ? min : x > max ? max : x)

/**
 * 创建表格数据结构的辅助函数
 * @param dataSource 数据源数组
 * @param fieldKeys 字段键数组，按顺序对应表格列
 * @param getLabelFn 获取标签的函数
 * @returns 格式化后的表格行HTML和数据属性
 */
export function createTableDataStructure(
  dataSource: any[],
  fieldKeys: string[],
  getLabelFn?: (item: any) => string
) {
  const getLabel = getLabelFn ?? ((x: any) => x?.name ?? '')
  
  return dataSource.map(item => {
    // 动态生成单元格
    const cells = fieldKeys.map(key => `<td>${String(item?.[key] ?? '')}</td>`).join('')
    
    // 动态生成 data 属性
    const dataAttrs = fieldKeys
      .map(key => `data-${key.toLowerCase()}="${String(item?.[key] ?? '')}"`)
      .join(' ')
    
    return {
      html: `<tr class="hot-dropdown-row" data-label="${String(getLabel(item) ?? '')}" ${dataAttrs}>${cells}</tr>`,
      data: item
    }
  })
}

const getSelectedCoords = (inst: any): { row: number; col: number } | null => {
  const r = inst?.getSelectedRangeLast?.()
  if (!r) return null
  return { row: r.to.row, col: r.to.col }
}

const getTargetCellRect = (inst: any, fallbackTD: HTMLTableCellElement | null): DOMRect | null => {
  const sel = getSelectedCoords(inst)
  if (sel) {
    const td = inst.getCell(sel.row, sel.col, true) as HTMLTableCellElement | null
    if (td) return td.getBoundingClientRect()
  }
  return fallbackTD ? fallbackTD.getBoundingClientRect() : null
}

const positionDropdown = (inst: any) => {
  if (!currentDropdownEl || !inst) return
  const containerRect = inst.rootElement?.getBoundingClientRect?.()
  const cellRect = getTargetCellRect(inst, currentAnchor?.td ?? null)
  if (!containerRect || !cellRect) return
  const minWidth = Math.max(cellRect.width, 220)
  currentDropdownEl.style.minWidth = `${minWidth}px`
  const ddRect = currentDropdownEl.getBoundingClientRect()
  const spaceBelow = containerRect.bottom - cellRect.bottom
  const spaceAbove = cellRect.top - containerRect.top
  const openUp = spaceBelow < ddRect.height && spaceAbove > spaceBelow
  currentDropdownEl.classList.remove('hot-dropdown--up', 'hot-dropdown--down')
  currentDropdownEl.classList.add(openUp ? 'hot-dropdown--up' : 'hot-dropdown--down')
  const maxH = Math.max(0, Math.min(260, (openUp ? spaceAbove : spaceBelow)))
  currentDropdownEl.style.maxHeight = `${maxH}px`
  const dropdownW = Math.max(ddRect.width || minWidth, minWidth)
  const left = clamp(
    Math.round(cellRect.left),
    Math.round(containerRect.left ),
    Math.round(containerRect.right - dropdownW )
  )
  const ddh = Math.min(ddRect.height, maxH)
  const topCandidate = openUp ? Math.round(cellRect.top - ddh) : Math.round(cellRect.bottom)
  const top = clamp(
    topCandidate,
    Math.round(containerRect.top),
    Math.round(containerRect.bottom - ddh)
  )
  currentDropdownEl.style.left = `${left}px`
  currentDropdownEl.style.top = `${top}px`
}


export function handlerTableRenderer(instance: any, td: HTMLTableCellElement, row: number, column: number, prop: string | number, value: any, cellProperties: any) {
  td.innerHTML = ''
  td.classList.add('hot-cell-dropdown')

  const createEl = (tag: string, className?: string, text?: string) => {
    const el = document.createElement(tag)
    if (className) el.className = className
    if (text !== undefined) el.textContent = text
    return el
  }

  const labelFn: ((x: any) => string) | undefined = cellProperties.customGetLabel

  const display = createEl('div', 'hot-dropdown-display')
  const labelText = typeof value === 'string' ? value : labelFn?.(value) ?? (value && typeof value === 'object' ? String(value.name ?? '') : '')
  if (labelText && labelText.length > 0) display.appendChild(createEl('span', 'hot-dropdown-text', labelText))
  else display.appendChild(createEl('span', 'hot-dropdown-placeholder', '选择'))

  const trigger = createEl('button', 'hot-dropdown-trigger', '▼') as HTMLButtonElement
  trigger.type = 'button'

  const buildDropdown = () => {
    const src = cellProperties.customDropdownSource as any[] | undefined
    const headers: string[] | undefined = cellProperties.customTableHeaders
    const dropdown = createEl('div', 'hot-dropdown')
    const getLabel = labelFn ?? ((x: any) => x?.name ?? '')
    
    // 创建搜索栏
    const searchContainer = createEl('div', 'hot-dropdown-search')
    const searchInput = createEl('input', 'hot-dropdown-search-input') as HTMLInputElement
    searchInput.type = 'text'
    searchInput.placeholder = '搜索...'
    searchContainer.appendChild(searchInput)
    
    const theadHtml = headers && headers.length ? `<thead><tr>${headers.map(h => `<th>${h}</th>`).join('')}</tr></thead>` : ''
    
    // 使用自定义字段键或默认字段键
    const fieldKeys = cellProperties.customFieldKeys || ['code', 'name', 'spec', 'category', 'unit', 'taxRate', 'priceExTax', 'priceInTax', 'priceExTaxComp', 'priceInTaxComp', 'calcBase']
    
    const rowsHtml = Array.isArray(src)
      ? createTableDataStructure(src, fieldKeys, labelFn).map(row => row.html).join('')
      : ''
    
    const tableEl = createEl('div', 'hot-dropdown-table-wrapper')
    tableEl.innerHTML = `<table class="hot-dropdown-table">${theadHtml}<tbody>${rowsHtml}</tbody></table>`
    
    dropdown.appendChild(searchContainer)
    dropdown.appendChild(tableEl)
    
    const tbody = dropdown.querySelector('tbody') as HTMLTableSectionElement
    const allRows = Array.from(tbody.querySelectorAll('tr')) as HTMLTableRowElement[]
    
    // 搜索功能 - 动态搜索所有字段
    const searchFieldKeys = cellProperties.customSearchFields || cellProperties.customFieldKeys || ['code', 'name', 'spec', 'category', 'unit']
    searchInput.addEventListener('input', (ev) => {
      ev.stopPropagation()
      const keyword = searchInput.value.toLowerCase().trim()
      allRows.forEach(tr => {
        const matches = searchFieldKeys.some((key: string) => {
          const value = (tr.dataset[key.toLowerCase()] ?? '').toLowerCase()
          return value.includes(keyword)
        })
        tr.style.display = matches ? '' : 'none'
      })
    })
    
    // 阻止搜索框点击事件冒泡
    searchInput.addEventListener('click', (ev) => ev.stopPropagation())
    
    tbody.addEventListener('click', (ev) => {
      ev.stopPropagation()
      const tr = (ev.target as HTMLElement).closest('tr') as HTMLTableRowElement | null
      if (!tr) return
      const next = tr.dataset.label ?? ''
      instance.setDataAtCell(row, column, next)
      if (dropdown.parentNode) dropdown.parentNode.removeChild(dropdown)
      currentDropdownEl = null
      if (currentOnDocClick) {
        document.removeEventListener('click', currentOnDocClick)
        currentOnDocClick = null
      }
    })
    
    // 自动聚焦搜索框
    setTimeout(() => searchInput.focus(), 50)
    
    return dropdown
  }

  const openDropdown = () => {
    if (currentDropdownEl && currentDropdownEl.parentNode) currentDropdownEl.parentNode.removeChild(currentDropdownEl)
    if (currentOnDocClick) document.removeEventListener('click', currentOnDocClick)

    const dropdown = buildDropdown()
    document.body.appendChild(dropdown)
    currentDropdownEl = dropdown
    currentAnchor = { instance, row, col: column, td }
    positionDropdown(instance)
    currentOnDocClick = (e: MouseEvent) => {
      if (!dropdown.contains(e.target as Node)) {
        if (dropdown.parentNode) dropdown.parentNode.removeChild(dropdown)
        currentDropdownEl = null
        currentAnchor = null
        document.removeEventListener('click', currentOnDocClick!)
        currentOnDocClick = null
      }
    }
    document.addEventListener('click', currentOnDocClick)
  }

  trigger.addEventListener('click', (e) => { e.stopPropagation(); openDropdown() })
  display.addEventListener('click', (e) => { e.stopPropagation(); openDropdown() })

  td.appendChild(display)
  td.appendChild(trigger)
  return td
}