import React, { useEffect, useCallback, useState, useRef } from 'react'
import { useTabStore } from '../../stores/tabStore'
import { useSidebarStore } from '../../stores/sidebarStore'
import { getFileName } from '../../lib/fileUtils'
import type { FileNode } from '../../types/file'

export function Sidebar() {
  const tabs = useTabStore(s => s.tabs)
  const activeTabId = useTabStore(s => s.activeTabId)
  const switchToTab = useTabStore(s => s.switchToTab)
  const createTab = useTabStore(s => s.createTab)

  const rootPath = useSidebarStore(s => s.rootPath)
  const tree = useSidebarStore(s => s.tree)
  const expandedDirs = useSidebarStore(s => s.expandedDirs)
  const toggleDir = useSidebarStore(s => s.toggleDir)
  const setRootPath = useSidebarStore(s => s.setRootPath)
  const setTree = useSidebarStore(s => s.setTree)
  const isVisible = useSidebarStore(s => s.isVisible)

  // 计算当前活动标签的文件路径（用于文件树高亮）
  const activeFilePath = tabs.find(t => t.id === activeTabId)?.filePath ?? null

  const [isResizing, setIsResizing] = useState(false)
  const sidebarRef = useRef<HTMLDivElement>(null)

  // 打开文件夹
  const handleOpenFolder = useCallback(async () => {
    if (!window.electronAPI) return
    const dirPath = await window.electronAPI.openFolderDialog()
    if (dirPath) {
      setRootPath(dirPath)
      const result = await window.electronAPI.readDirTree(dirPath)
      if (result.success && result.tree) {
        setTree(result.tree)
        window.electronAPI.watchDir(dirPath)
      }
    }
  }, [setRootPath, setTree])

  // 刷新目录树
  const refreshTree = useCallback(async () => {
    if (!rootPath || !window.electronAPI) return
    const result = await window.electronAPI.readDirTree(rootPath)
    if (result.success && result.tree) {
      setTree(result.tree)
    }
  }, [rootPath, setTree])

  // 目录变化监听
  useEffect(() => {
    if (!window.electronAPI) return
    window.electronAPI.onDirChanged(() => {
      refreshTree()
    })
    return () => {
      window.electronAPI?.removeAllListeners('sidebar:dirChanged')
    }
  }, [refreshTree])

  // 侧边栏宽度调节
  useEffect(() => {
    if (!isResizing) return
    const handleMouseMove = (e: MouseEvent) => {
      if (sidebarRef.current) {
        const newWidth = Math.max(180, Math.min(500, e.clientX))
        sidebarRef.current.style.width = newWidth + 'px'
      }
    }
    const handleMouseUp = () => setIsResizing(false)
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mouseup', handleMouseUp)
    return () => {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mouseup', handleMouseUp)
    }
  }, [isResizing])

  // L-12: 提取为 useCallback 避免每次渲染重建
  const handleFileClick = useCallback(async (path: string) => {
    const existing = tabs.find(t => t.filePath === path)
    if (existing) {
      switchToTab(existing.id)
    } else if (window.electronAPI) {
      const result = await window.electronAPI.readFile(path)
      if (result.success && result.content) {
        createTab(path, result.content)
      }
    }
  }, [tabs, switchToTab, createTab])
  const independentFiles = tabs.filter(t => {
    if (!t.filePath) return false
    if (!rootPath) return true
    return !t.filePath.startsWith(rootPath)
  })

  if (!isVisible) return null

  return (
    <div id="sidebar" ref={sidebarRef}>
      <div id="sidebar-header">
        <span id="sidebar-title">资源管理器</span>
        <button className="sidebar-header-btn" onClick={handleOpenFolder} title="打开文件夹">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
          </svg>
        </button>
      </div>

      <div id="sidebar-tree">
        {/* 独立文件区 */}
        {independentFiles.length > 0 && (
          <div className="independent-files-section">
            <div className="independent-files-header">已打开的文件</div>
            {independentFiles.map(tab => (
              <div
                key={tab.id}
                className={`tree-item independent-file-item ${tab.id === activeTabId ? 'active' : ''}`}
                style={{ paddingLeft: '8px' }}
                onClick={() => switchToTab(tab.id)}
              >
                <span className="tree-icon">
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                    <polyline points="14 2 14 8 20 8" />
                  </svg>
                </span>
                <span className="tree-name">{getFileName(tab.filePath!)}</span>
                {tab.isModified && <span className="independent-modified-dot"> •</span>}
              </div>
            ))}
          </div>
        )}

        {/* 文件夹目录树 */}
        {rootPath && (
          <>
            <div className="sidebar-section-header">文件夹目录树</div>
            <FileTree
              nodes={tree}
              depth={0}
              expandedDirs={expandedDirs}
              toggleDir={toggleDir}
              activeTabId={activeTabId}
              activeFilePath={activeFilePath}
              onFileClick={handleFileClick}
            />
          </>
        )}
      </div>

      {/* 调节手柄 */}
      <div
        className="sidebar-resize-handle"
        onMouseDown={() => setIsResizing(true)}
      />
    </div>
  )
}

// 文件树递归组件
function FileTree({ nodes, depth, expandedDirs, toggleDir, activeTabId, activeFilePath, onFileClick }: {
  nodes: FileNode[]
  depth: number
  expandedDirs: Set<string>
  toggleDir: (path: string) => void
  activeTabId: string | null
  activeFilePath: string | null
  onFileClick: (path: string) => void
}) {
  return (
    <>
      {nodes.map(node => (
        <React.Fragment key={node.path}>
          <div
            className={`tree-item ${node.type === 'file' && node.path === activeFilePath ? 'active' : ''}`}
            style={{ paddingLeft: (8 + depth * 16) + 'px' }}
            onClick={() => {
              if (node.type === 'dir') {
                toggleDir(node.path)
              } else {
                onFileClick(node.path)
              }
            }}
          >
            {node.type === 'dir' ? (
              <>
                <span className={`tree-arrow ${expandedDirs.has(node.path) ? 'expanded' : ''}`}>
                  <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                    <polyline points="9 18 15 12 9 6" />
                  </svg>
                </span>
                <span className="tree-icon">
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
                  </svg>
                </span>
              </>
            ) : (
              <>
                <span style={{ width: '16px', flexShrink: 0 }} />
                <span className="tree-icon">
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                    <polyline points="14 2 14 8 20 8" />
                  </svg>
                </span>
              </>
            )}
            <span className="tree-name">{node.name}</span>
          </div>
          {node.type === 'dir' && expandedDirs.has(node.path) && node.children && (
            <FileTree
              nodes={node.children}
              depth={depth + 1}
              expandedDirs={expandedDirs}
              toggleDir={toggleDir}
              activeTabId={activeTabId}
              activeFilePath={activeFilePath}
              onFileClick={onFileClick}
            />
          )}
        </React.Fragment>
      ))}
    </>
  )
}
