import React, { useCallback, useState, useEffect, useRef } from 'react'
import { useTabStore } from '../../stores/tabStore'
import { useConfirm } from '../../hooks/useConfirm'
import { getFileName } from '../../lib/fileUtils'
import { Close, Plus } from '../Icons'
import { ConfirmDialog } from '../ConfirmDialog/ConfirmDialog'

interface ContextMenuState {
  visible: boolean
  x: number
  y: number
  tabId: string
}

export const TabBar = React.memo(function TabBar() {
  const tabs = useTabStore(s => s.tabs)
  const activeTabId = useTabStore(s => s.activeTabId)
  const switchToTab = useTabStore(s => s.switchToTab)
  const closeTab = useTabStore(s => s.closeTab)
  const createTab = useTabStore(s => s.createTab)
  const closeOtherTabs = useTabStore(s => s.closeOtherTabs)
  const closeAllTabs = useTabStore(s => s.closeAllTabs)
  const closeTabsToRight = useTabStore(s => s.closeTabsToRight)
  const moveTab = useTabStore(s => s.moveTab)

  const tabListRef = useRef<HTMLDivElement>(null)
  const [menu, setMenu] = useState<ContextMenuState>({ visible: false, x: 0, y: 0, tabId: '' })
  const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)
  const dragTabIdRef = useRef<string | null>(null)
  const { confirm, confirmDialogProps } = useConfirm()

  // 滚动到活动标签
  const scrollToActiveTab = useCallback(() => {
    const tabList = tabListRef.current
    if (!tabList) return
    const activeTab = tabList.querySelector('.tab-item.active') as HTMLElement
    if (!activeTab) return

    const listRect = tabList.getBoundingClientRect()
    const tabRect = activeTab.getBoundingClientRect()

    // 如果标签在可视区域左侧之外
    if (tabRect.left < listRect.left) {
      tabList.scrollLeft -= (listRect.left - tabRect.left + 20)
    }
    // 如果标签在可视区域右侧之外
    else if (tabRect.right > listRect.right) {
      tabList.scrollLeft += (tabRect.right - listRect.right + 20)
    }
  }, [])

  // 自动滚动到活动标签
  useEffect(() => {
    requestAnimationFrame(scrollToActiveTab)
  }, [activeTabId, scrollToActiveTab])

  // 支持鼠标滚轮水平滚动标签栏
  useEffect(() => {
    const tabList = tabListRef.current
    if (!tabList) return

    const handleWheel = (e: WheelEvent) => {
      // 检查是否有水平溢出
      if (tabList.scrollWidth <= tabList.clientWidth) return

      // 阻止默认滚动
      e.preventDefault()

      // 计算滚动量：支持触控板 deltaX 和鼠标滚轮 deltaY
      const delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY
      tabList.scrollLeft += delta
    }

    // 直接绑定到 tabList，使用 passive: false 允许 preventDefault
    tabList.addEventListener('wheel', handleWheel, { passive: false })
    return () => tabList.removeEventListener('wheel', handleWheel)
  }, [])

  const handleClose = useCallback(async (e: React.MouseEvent, tabId: string) => {
    e.stopPropagation()
    const tab = tabs.find(t => t.id === tabId)
    if (tab?.isModified) {
      const name = tab.filePath ? getFileName(tab.filePath) : '未命名'
      const confirmed = await confirm({
        title: '关闭标签',
        message: `"${name}" 尚未保存，确定要关闭吗？`,
        variant: 'warning',
        confirmLabel: '关闭'
      })
      if (!confirmed) return
    }
    closeTab(tabId)
  }, [tabs, closeTab, confirm])

  // C-06: 右键菜单（带边界修正）
  const handleContextMenu = useCallback((e: React.MouseEvent, tabId: string) => {
    e.preventDefault()
    e.stopPropagation()
    const MENU_WIDTH = 170
    const MENU_HEIGHT = 140
    const x = Math.min(e.clientX, window.innerWidth - MENU_WIDTH)
    const y = Math.min(e.clientY, window.innerHeight - MENU_HEIGHT)
    setMenu({ visible: true, x: Math.max(0, x), y: Math.max(0, y), tabId })
  }, [])

  useEffect(() => {
    if (!menu.visible) return
    const handleClick = () => setMenu(prev => ({ ...prev, visible: false }))
    document.addEventListener('click', handleClick)
    return () => document.removeEventListener('click', handleClick)
  }, [menu.visible])

  const handleMenuClose = useCallback(async () => {
    const tab = tabs.find(t => t.id === menu.tabId)
    if (tab?.isModified) {
      const name = tab.filePath ? getFileName(tab.filePath) : '未命名'
      const confirmed = await confirm({
        title: '关闭标签',
        message: `"${name}" 尚未保存，确定要关闭吗？`,
        variant: 'warning',
        confirmLabel: '关闭'
      })
      if (!confirmed) return
    }
    closeTab(menu.tabId)
    setMenu(prev => ({ ...prev, visible: false }))
  }, [tabs, menu.tabId, closeTab, confirm])

  const handleMenuCloseOthers = useCallback(async () => {
    const otherModified = tabs.filter(t => t.id !== menu.tabId && t.isModified)
    if (otherModified.length > 0) {
      const names = otherModified.map(t => t.filePath ? getFileName(t.filePath) : '未命名').join('、')
      const confirmed = await confirm({
        title: '关闭其他标签',
        message: `以下文件尚未保存：${names}，确定要关闭吗？`,
        variant: 'warning',
        confirmLabel: '关闭'
      })
      if (!confirmed) return
    }
    closeOtherTabs(menu.tabId)
    setMenu(prev => ({ ...prev, visible: false }))
  }, [tabs, menu.tabId, closeOtherTabs, confirm])

  const handleMenuCloseAll = useCallback(async () => {
    const modified = tabs.filter(t => t.isModified)
    if (modified.length > 0) {
      const names = modified.map(t => t.filePath ? getFileName(t.filePath) : '未命名').join('、')
      const confirmed = await confirm({
        title: '关闭全部标签',
        message: `以下文件尚未保存：${names}，确定要关闭吗？`,
        variant: 'warning',
        confirmLabel: '关闭'
      })
      if (!confirmed) return
    }
    closeAllTabs()
    setMenu(prev => ({ ...prev, visible: false }))
  }, [tabs, closeAllTabs, confirm])

  const handleMenuCloseRight = useCallback(async () => {
    const index = tabs.findIndex(t => t.id === menu.tabId)
    const rightTabs = tabs.slice(index + 1)
    const modified = rightTabs.filter(t => t.isModified)
    if (modified.length > 0) {
      const names = modified.map(t => t.filePath ? getFileName(t.filePath) : '未命名').join('、')
      const confirmed = await confirm({
        title: '关闭右侧标签',
        message: `以下文件尚未保存：${names}，确定要关闭吗？`,
        variant: 'warning',
        confirmLabel: '关闭'
      })
      if (!confirmed) return
    }
    closeTabsToRight(menu.tabId)
    setMenu(prev => ({ ...prev, visible: false }))
  }, [tabs, menu.tabId, closeTabsToRight, confirm])

  // D1: 拖拽排序事件处理
  const handleDragStart = useCallback((e: React.DragEvent, tabId: string) => {
    dragTabIdRef.current = tabId
    e.dataTransfer.effectAllowed = 'move'
    e.dataTransfer.setData('text/plain', tabId)
    // 延迟添加 dragging 类，避免拖拽图像被 CSS 捕获
    requestAnimationFrame(() => {
      const el = document.querySelector(`[data-tab-id="${tabId}"]`) as HTMLElement
      el?.classList.add('dragging')
    })
  }, [])

  const handleDragOver = useCallback((e: React.DragEvent, index: number) => {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
    setDragOverIndex(index)
  }, [])

  const handleDragLeave = useCallback(() => {
    setDragOverIndex(null)
  }, [])

  const handleDrop = useCallback((e: React.DragEvent, toIndex: number) => {
    e.preventDefault()
    setDragOverIndex(null)
    const fromId = dragTabIdRef.current
    if (fromId) {
      moveTab(fromId, toIndex)
    }
    dragTabIdRef.current = null
    // 清理 dragging 类
    document.querySelectorAll('.tab-item.dragging').forEach(el => el.classList.remove('dragging'))
  }, [moveTab])

  const handleDragEnd = useCallback(() => {
    setDragOverIndex(null)
    document.querySelectorAll('.tab-item.dragging').forEach(el => el.classList.remove('dragging'))
    dragTabIdRef.current = null
  }, [])

  const hasRightTabs = menu.visible && (() => {
    const index = tabs.findIndex(t => t.id === menu.tabId)
    return index < tabs.length - 1
  })()

  if (tabs.length === 0) return null

  return (
    <>
      <div id="tab-bar">
        <div id="tab-list" ref={tabListRef} role="tablist" aria-label="标签页">
          {tabs.map((tab, index) => (
            <div
              key={tab.id}
              className={`tab-item ${tab.id === activeTabId ? 'active' : ''} ${tab.isModified ? 'modified' : ''} ${dragOverIndex === index ? 'drag-over' : ''}`}
              role="tab"
              aria-selected={tab.id === activeTabId}
              tabIndex={tab.id === activeTabId ? 0 : -1}
              data-tab-id={tab.id}
              draggable
              onClick={() => switchToTab(tab.id)}
              onContextMenu={(e) => handleContextMenu(e, tab.id)}
              onDragStart={(e) => handleDragStart(e, tab.id)}
              onDragOver={(e) => handleDragOver(e, index)}
              onDragLeave={handleDragLeave}
              onDrop={(e) => handleDrop(e, index)}
              onDragEnd={handleDragEnd}
            >
              <span className="tab-name">
                {tab.filePath ? getFileName(tab.filePath) : '未命名'}
              </span>
              <button
                className="tab-close"
                onClick={(e) => handleClose(e, tab.id)}
                aria-label={`关闭 ${tab.filePath ? getFileName(tab.filePath) : '未命名'}`}
              >
                <Close size={10} />
              </button>
            </div>
          ))}
        </div>
        <button
          className="tab-add-btn"
          onClick={() => createTab(null, '')}
          title="新建标签页 (Ctrl+T)"
          aria-label="新建标签页"
        >
          <Plus size={14} />
        </button>

        {/* 右键菜单 */}
        {menu.visible && (
          <div
            className="tab-context-menu"
            style={{ left: menu.x, top: menu.y }}
            role="menu"
            aria-label="标签操作"
            onClick={(e) => e.stopPropagation()}
            onMouseDown={(e) => e.stopPropagation()}
          >
            <div className="tab-context-item" role="menuitem" onClick={handleMenuClose}>
              关闭
            </div>
            {tabs.length > 1 && (
              <div className="tab-context-item" role="menuitem" onClick={handleMenuCloseOthers}>
                关闭其他标签
              </div>
            )}
            {hasRightTabs && (
              <div className="tab-context-item" role="menuitem" onClick={handleMenuCloseRight}>
                关闭右侧标签
              </div>
            )}
            <div className="tab-context-divider" role="separator" />
            <div className="tab-context-item" role="menuitem" onClick={handleMenuCloseAll}>
              关闭全部标签
            </div>
          </div>
        )}
      </div>
      <ConfirmDialog {...confirmDialogProps} />
    </>
  )
})

TabBar.displayName = 'TabBar'
