<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import {
  Folder,
  FolderOpen,
  FileText,
  Database,
  Copy,
  GitBranch,
  Trash2,
  X,
  Plus,
  Minus,
  CornerUpLeft,
  CornerDownLeft,
  Link
} from 'lucide-vue-next'
import { initializeTreeData, saveTreeDataToStorage } from '../utils/treeStorage'
import { generateNodeSpecificContent } from '../utils/mockDataGenerator'
import { generateMockReviewHistory } from '../utils/mockReviewData'
import type { EditorBlock, ImageBlock, TableBlock, VideoBlock, TextBlock } from '../utils/mockDataGenerator'

export interface TreeNode {
  id: string
  label: string
  type: 'folder'
  status?: 'work' | 'released' | 'approved' | 'rejected' | 'pending' | 'CS Released' | 'mapped'
  version?: string
  nextVersion?: string
  pss?: string
  expanded?: boolean
  selected?: boolean
  children?: TreeNode[]
  isClone?: boolean
  cloneSourceId?: string
  isTerminal?: boolean
  // 元数据字段
  createDate?: string
  access?: string
  owner?: string
  department?: string
  lastChangedBy?: string
  lastChangedDate?: string
  // Inbox状态（仅末端节点）
  inboxStatus?: 'mapped' | 'ongoing' | 'rejected' | 'agreed' | 'accepted'
  reviewer?: string
  // 富文本内容（仅末端节点）
  content?: EditorBlock[]
  // 版本历史（仅末端节点）
  versions?: VersionData[]
}

// 版本数据
export interface VersionData {
  version: string
  date: string
  author: string
  content: EditorBlock[]
}

export type { EditorBlock, ImageBlock, TableBlock, VideoBlock, TextBlock }

// 判断节点是否为映射节点
const isMappedNode = (node: TreeNode): boolean => {
  if (!node.versions?.length) return false
  const author = node.versions[0].author
  return author === '系统映射' || author === 'System Mapping'
}

// 节点权限配置 - 允许所有节点进行所有操作（作为目标）
const getNodePermissions = (node: TreeNode) => {
  return {
    copy: true,
    clone: true,
    branch: true
  }
}

// Mock 用户列表
const mockUsers = ['zhangsan', 'lisi', 'wangwu', 'hongwei', 'admin']
const mockAccessLevels = ['Read', 'Write', 'Admin']

// 生成随机日期
const generateDate = (daysOffset: number = 0) => {
  const date = new Date()
  date.setDate(date.getDate() - daysOffset)
  return date.toISOString().split('T')[0]
}

// 生成版本历史
const generateVersions = (nodeName: string, count: number = 10): VersionData[] => {
  const versions: VersionData[] = []
  for (let i = 0; i < count; i++) {
    versions.push({
      version: `0.0.${i}`,
      date: generateDate((count - 1 - i) * 7),
      author: mockUsers[i % mockUsers.length],
      content: generateNodeSpecificContent(nodeName, i + 1)
    })
  }
  return versions.reverse()
}

// 全局计数器，确保每个状态至少分配一次
const globalStatusCounter = {
  mapped: 0,
  ongoing: 0,
  rejected: 0,
  agreed: 0,
  accepted: 0
}

const buildTreeData = (items: any[], parentId: string, depth: number = 0): TreeNode[] => {
  return items.map((item, i) => {
    const id = `${parentId}-${i}`
    const isTerminal = item.isTerminal || false
    const randomUser = mockUsers[Math.floor(Math.random() * mockUsers.length)]
    const createDate = generateDate(Math.floor(Math.random() * 30))
    
    // Inbox 状态分配逻辑
    let inboxStatus: 'mapped' | 'ongoing' | 'rejected' | 'agreed' | 'accepted' = 'mapped'
    
    if (isTerminal) {
      // 确保每个状态至少出现一次
      const statusKeys = Object.keys(globalStatusCounter) as Array<keyof typeof globalStatusCounter>
      const minCount = Math.min(...statusKeys.map(key => globalStatusCounter[key]))

      // 找到还没有达到最小数量的状态
      const availableStatuses = statusKeys.filter(key => globalStatusCounter[key] === minCount)

      // 随机选择一个可用的状态
      const selectedKey = availableStatuses[Math.floor(Math.random() * availableStatuses.length)]
      inboxStatus = selectedKey
      globalStatusCounter[selectedKey]++
    }

    // 如果是末端节点，先生成版本历史
    const versions = isTerminal ? generateVersions(item.name, 10) : []

    const node: TreeNode = {
      id,
      label: item.name,
      type: 'folder',
      status: 'work',
      version: isTerminal ? versions[versions.length - 1].version : '(1)',
      expanded: depth <= 2,
      children: item.children ? buildTreeData(item.children, id, depth + 1) : undefined,
      isTerminal,
      // 添加元数据字段
      createDate,
      access: mockAccessLevels[i % mockAccessLevels.length],
      owner: randomUser,
      lastChangedBy: randomUser,
      lastChangedDate: createDate,
      reviewer: isTerminal ? mockUsers[(i + 2) % mockUsers.length] : undefined,
      // 如果是末端节点，添加inbox状态、内容和版本历史
      ...(isTerminal && {
        inboxStatus,
        content: generateNodeSpecificContent(item.name, 2),
        versions
      })
    }

    return node
  })
}

const treeDataSource = [
  {
    name: "Inbox",
    children: [
      { name: "Review", children: [] },
      { name: "Map", children: [] }
    ]
  },
  {
    name: "Standards",
    children: [
      { name: "Product Scenario", children: [] },
      {
        name: "Product Definition Context",
        children: [
          { name: "Competitors", children: [] },
          { name: "Production Vision & Mission", children: [] },
          { name: "Product Concepts", children: [] }
        ]
      },
      {
        name: "Product Strategy and Targets",
        children: [
          { name: "Design", children: [] },
          { name: "Accommodation & Usage", children: [] },
          { name: "FE", children: [] }
        ]
      },
      {
        name: "Attributes",
        children: [
          {
            name: "Safety",
            children: [
              {
                name: "Passive Safety",
                children: [
                  { name: "64km ODB", isTerminal: true },
                  { name: "112km ODB", isTerminal: true },
                  { name: "80km ODB", isTerminal: true },
                  { name: "Low Speed Crash", children: [] }
                ]
              }
            ]
          },
          { name: "Vehicle Energy Efficient", children: [] },
          { name: "Weight", children: [] },
          { name: "Aerodynamics", children: [] }
        ]
      },
      {
        name: "Function",
        children: [
          { name: "Connectivity Infrastructure Domain", children: [] },
          { name: "Electrical Platform Domain", children: [] },
          { name: "HMI Domain", children: [] }
        ]
      },
      {
        name: "System",
        children: [
          {
            name: "Powertrain",
            children: [
              {
                name: "Engine",
                children: [
                  { name: "Crankshaft", isTerminal: true },
                  { name: "Ignition", isTerminal: true },
                  { name: "Engine Body", isTerminal: true }
                ]
              },
              { name: "Transmission", children: [] },
              { name: "Motor", children: [] },
              { name: "incoming requirements", children: [] },
              { name: "attribute", children: [] },
              { name: "NVH 1", isTerminal: true },
              { name: "NVH 2", isTerminal: true },
              { name: "Safety 1", isTerminal: true },
              { name: "function", children: [] }
            ]
          },
          { name: "Powertrain Integration", children: [] },
          {
            name: "Exterior",
            children: [
              { name: "Incoming Requirements", children: [] },
              {
                name: "Product targets", children: [
                  { name: "requirements 1", isTerminal: true },
                  { name: "requirements 2", isTerminal: true }
                ]
              },
              { name: "attribute", children: [] },
              { name: "function", children: [] }
            ]
          }
        ]
      }
    ]
  },
  {
    name: "Projects",
    children: [
      {
        name: "A",
        children: [
          { name: "Product Scenario", children: [] },
          {
            name: "Product Definition Context",
            children: [
              { name: "Competitors", children: [] },
              { name: "Production Vision & Mission", children: [] },
              { name: "Product Concepts", children: [] }
            ]
          },
          {
            name: "Product Strategy and Targets",
            children: [
              { name: "Design", children: [] },
              { name: "Accommodation & Usage", children: [] },
              { name: "FE", children: [] }
            ]
          },
          {
            name: "Attributes",
            children: [
              {
                name: "Safety",
                children: [
                  {
                    name: "Passive Safety",
                    children: [
                      { name: "64km ODB", isTerminal: true },
                      { name: "112km ODB", isTerminal: true },
                      { name: "80km ODB", isTerminal: true },
                      { name: "Low Speed Crash", children: [] }
                    ]
                  }
                ]
              },
              { name: "Vehicle Energy Efficient", children: [] },
              { name: "Weight", children: [] },
              { name: "Aerodynamics", children: [] }
            ]
          },
          {
            name: "Function",
            children: [
              { name: "Connectivity Infrastructure Domain", children: [] },
              { name: "Electrical Platform Domain", children: [] },
              { name: "HMI Domain", children: [] }
            ]
          },
          {
            name: "System",
            children: [
              {
                name: "Powertrain",
                children: [
                  {
                    name: "Engine",
                    children: [
                      { name: "Crankshaft", isTerminal: true },
                      { name: "Ignition", isTerminal: true },
                      { name: "Engine Body", isTerminal: true }
                    ]
                  },
                  { name: "Transmission", children: [] },
                  { name: "Motor", children: [] },
                  { name: "incoming requirements", children: [] },
                  { name: "attribute", children: [] },
                  { name: "NVH 1", isTerminal: true },
                  { name: "NVH 2", isTerminal: true },
                  { name: "Safety 1", isTerminal: true },
                  { name: "function", children: [] }
                ]
              },
              { name: "Powertrain Integration", children: [] },
              {
                name: "Exterior",
                children: [
                  { name: "Incoming Requirements", children: [] },
                  {
                    name: "Product targets", children: [
                      { name: "requirements 1", isTerminal: true },
                      { name: "requirements 2", isTerminal: true }
                    ]
                  },
                  { name: "attribute", children: [] },
                  { name: "function", children: [] }
                ]
              }
            ]
          }
        ]
      },
      {
        name: "B",
        children: [
          {
            name: "Attribute",
            children: [
              {
                name: "Safety",
                children: [{ name: "64 ODB", isTerminal: true }]
              },
              {
                name: "NVH",
                children: [
                  { name: "PWT 40dB", isTerminal: true },
                  { name: "PWT 38dB", isTerminal: true }
                ]
              }
            ]
          },
          {
            name: "System",
            children: [
              {
                name: "Subsystem 1",
                children: [
                  {
                    name: "Component",
                    children: [
                      { name: "Incoming Requirements", children: [] },
                      { name: "NVH1 Accepted", children: [] }
                    ]
                  }
                ]
              },
              {
                name: "Subsystem 2",
                children: [
                  { name: "Component 2", children: [] },
                  {
                    name: "Component 3",
                    children: [
                      { name: "Incoming Requirements", children: [] },
                      { name: "NVH2 Accepted", children: [] }
                    ]
                  }
                ]
              }
            ]
          },
          { name: "Incoming Requirements", children: [] }
        ]
      },
      { name: "C", children: [] },
      { name: "XX", children: [] }
    ]
  }
]

const cloneNode = (node: TreeNode, newId?: string): TreeNode => {
  return {
    ...node,
    id: newId || node.id,
    children: node.children ? node.children.map(child => cloneNode(child)) : undefined
  }
}

const findNode = (nodes: TreeNode[], id: string): TreeNode | null => {
  for (const node of nodes) {
    if (node.id === id) return node
    if (node.children) {
      const found = findNode(node.children, id)
      if (found) return found
    }
  }
  return null
}

const deleteNodeFromTree = (nodes: TreeNode[], id: string): boolean => {
  const index = nodes.findIndex(n => n.id === id)
  if (index !== -1) {
    nodes.splice(index, 1)
    return true
  }
  for (const node of nodes) {
    if (node.children && deleteNodeFromTree(node.children, id)) {
      return true
    }
  }
  return false
}

const addChildNode = (parentNode: TreeNode, childNode: TreeNode) => {
  if (!parentNode.children) {
    parentNode.children = []
  }
  parentNode.children.push(childNode)
}

// 初始化树数据：优先从 localStorage 读取，否则使用 mockData
// 重置全局状态计数器，确保每次初始化都能正确分配状态
// globalStatusCounter 是局部常量，每次组件初始化都会重新创建，无需手动重置
const mockTreeData = ref<TreeNode[]>(initializeTreeData(buildTreeData(treeDataSource)))

// Ensure Inbox has Review and Map subfolders (Data Migration)
const inboxNode = mockTreeData.value.find(n => n.label === 'Inbox')
if (inboxNode) {
  const hasReview = inboxNode.children?.some(c => c.label === 'Review')
  const hasMap = inboxNode.children?.some(c => c.label === 'Map')
  
  if (!hasReview || !hasMap) {
    inboxNode.children = inboxNode.children || []
    if (!hasReview) {
      inboxNode.children.push({ 
        id: `${inboxNode.id}-review`, 
        label: 'Review', 
        type: 'folder', 
        children: [], 
        isTerminal: false 
      })
    }
    if (!hasMap) {
      inboxNode.children.push({ 
        id: `${inboxNode.id}-map`, 
        label: 'Map', 
        type: 'folder', 
        children: [], 
        isTerminal: false 
      })
    }
    saveTreeDataToStorage(mockTreeData.value)
  }
}

// 从树数据中获取所有末端节点作为Inbox数据
const inboxData = computed(() => {
  const terminals: TreeNode[] = []

  const traverse = (nodes: TreeNode[]) => {
    for (const node of nodes) {
      if (node.isTerminal) {
        terminals.push(node)
      }
      if (node.children) {
        traverse(node.children)
      }
    }
  }

  traverse(mockTreeData.value)
  return terminals.map((node, index) => ({
    id: index + 1,
    nodeName: node.label,
    nodeOwner: node.owner || 'unknown',
    requirementName: getRequirementName(node.label),
    owner: node.lastChangedBy || node.owner || 'unknown',
    type: getNodeType(node.label),
    version: node.version || '1.0',
    status: node.inboxStatus || 'mapped',
    mappedTime: node.createDate || '2023-01-01',
    latestRevisionTime: node.lastChangedDate || node.createDate || '2023-01-01'
  }))
})

// 根据节点名称推断需求名称
const getRequirementName = (nodeName: string): string => {
  const nameMap: Record<string, string> = {
    '64km ODB': 'Passive Safety',
    '112km ODB': 'Passive Safety',
    '80km ODB': 'Passive Safety',
    'Low Speed Crash': 'Passive Safety',
    'Crankshaft': 'Engine Performance',
    'Ignition': 'Engine Performance',
    'Engine Body': 'Engine Performance',
    'NVH 1': 'Noise Control',
    'NVH 2': 'Noise Control',
    'Safety 1': 'Vehicle Safety',
    'requirements 1': 'Product Requirements',
    'requirements 2': 'Product Requirements'
  }
  return nameMap[nodeName] || nodeName
}

// 根据节点名称推断类型
const getNodeType = (nodeName: string): string => {
  const typeMap: Record<string, string> = {
    '64km ODB': 'Attribute',
    '112km ODB': 'Attribute',
    '80km ODB': 'Attribute',
    'Low Speed Crash': 'Attribute',
    'Crankshaft': 'Attribute',
    'Ignition': 'Attribute',
    'Engine Body': 'Attribute',
    'NVH 1': 'Function',
    'NVH 2': 'Function',
    'Safety 1': 'Function',
    'requirements 1': 'Function',
    'requirements 2': 'Function'
  }
  return typeMap[nodeName] || 'Attribute'
}

// 计算Inbox中mapped状态的数量
const mappedCount = computed(() => {
  return inboxData.value.filter(item => item.status === 'mapped').length
})

// 计算待review的节点数量
const pendingReviewCount = computed(() => {
  let count = 0

  const traverse = (nodes: TreeNode[]) => {
    for (const node of nodes) {
      if (node.isTerminal) {
        // 检查是否有pending或submitted状态的review记录
        const reviewHistoryKey = `review_history_${node.id}`
        const storedHistory = localStorage.getItem(reviewHistoryKey)

        if (storedHistory) {
          const reviewData = JSON.parse(storedHistory)
          // pending 或 submitted 状态都需要处理
          const needsReview = reviewData.some((record: any) => 
            record.status === 'pending' || record.status === 'submitted'
          )
          if (needsReview) {
            count++
          }
        }
      }

      if (node.children) {
        traverse(node.children)
      }
    }
  }

  traverse(mockTreeData.value)
  return count
})

// 计算 Inbox 总数（Review + Map 的和）
const inboxTotalCount = computed(() => {
  return mappedCount.value + pendingReviewCount.value
})

defineProps<{
  modelValue?: string | null
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: string | null): void
  (e: 'select', node: TreeNode): void
  (e: 'tree-data-update', data: TreeNode[]): void
  (e: 'switch-view', viewMode: string): void
}>()

// 监听数据变化，自动保存到 localStorage
watch(mockTreeData, (newData) => {
  saveTreeDataToStorage(newData)
  emit('tree-data-update', newData)
}, { deep: true, immediate: true })

const selectedId = ref<string | null>('1')
const expandedIds = ref<Set<string>>(new Set())
const dialogExpandedIds = ref<Set<string>>(new Set())

const contextMenu = ref({
  show: false,
  x: 0,
  y: 0,
  nodeId: ''
})

const operationDialog = ref({
  show: false,
  mode: 'copy' as 'copy' | 'clone' | 'branch',
  sourceNodeId: '',
  selectedSourceIds: [] as string[],
  owner: 'admin' // default owner
})

const toggleSourceSelection = (node: TreeNode) => {
  // Only allow terminal nodes
  if (!isTerminalNode(node)) return

  const ids = operationDialog.value.selectedSourceIds
  
  if (ids.includes(node.id)) {
    // Toggle off if already selected
    operationDialog.value.selectedSourceIds = []
  } else {
    // Single select: replace any existing selection
    operationDialog.value.selectedSourceIds = [node.id]
  }
}

const getAllTerminalDescendants = (node: TreeNode): string[] => {
  const results: string[] = []
  const traverse = (n: TreeNode) => {
    if (isTerminalNode(n)) {
      results.push(n.id)
    }
    if (n.children) {
      n.children.forEach(traverse)
    }
  }
  traverse(node)
  return results
}

const isIdsSelected = (node: TreeNode): boolean => {
  if (isTerminalNode(node)) {
    return operationDialog.value.selectedSourceIds.includes(node.id)
  }
  // For folders, checked if all terminal descendants are checked
  const descendants = getAllTerminalDescendants(node)
  return descendants.length > 0 && descendants.every(id => operationDialog.value.selectedSourceIds.includes(id))
}

const isIdsIndeterminate = (node: TreeNode): boolean => {
  if (isTerminalNode(node)) return false
  
  const descendants = getAllTerminalDescendants(node)
  if (descendants.length === 0) return false
  
  const selectedCount = descendants.filter(id => operationDialog.value.selectedSourceIds.includes(id)).length
  return selectedCount > 0 && selectedCount < descendants.length
}

const addNodeDialog = ref({
  show: false,
  mode: 'sibling' as 'sibling' | 'child',
  parentNodeId: '',
  targetNodeId: '',
  nodeType: '',
  owner: '',
  reviewer: ''
})

// 节点类型选项
const nodeTypes = ['folder', 'document']

const initExpanded = (nodes: TreeNode[]) => {
  nodes.forEach(node => {
    if (node.expanded) {
      expandedIds.value.add(node.id)
    }
    if (node.children) {
      initExpanded(node.children)
    }
  })
}
initExpanded(mockTreeData.value)

// 初始化时emit tree data
emit('tree-data-update', mockTreeData.value)

// 查找 Review 和 Map 节点用于分类判断
const findInboxChildren = () => {
  const inboxNode = mockTreeData.value.find(n => n.label === 'Inbox')
  return {
    reviewNode: inboxNode?.children?.find(c => c.label === 'Review'),
    mapNode: inboxNode?.children?.find(c => c.label === 'Map')
  }
}

// 检查节点是否在某个父节点下
const isDescendantOf = (ancestor: TreeNode | undefined, node: TreeNode): boolean => {
  if (!ancestor) return false
  if (node.id === ancestor.id) return true
  if (node.children) {
    return node.children.some(child => isDescendantOf(ancestor, child))
  }
  return false
}

// 查找节点的父节点
const findParent = (nodes: TreeNode[], targetNode: TreeNode): TreeNode | null => {
  for (const node of nodes) {
    if (node.children) {
      if (node.children.some(child => child.id === targetNode.id)) {
        return node
      }
      const found = findParent(node.children, targetNode)
      if (found) return found
    }
  }
  return null
}

// 初始化 review_history：每个终端节点生成多种类型的初始数据
onMounted(() => {
  let terminalNodeIndex = 0

  const traverse = (nodes: TreeNode[]) => {
    for (const node of nodes) {
      // 跳过 Inbox 及其直接子节点
      const isInboxOrDirectChild = node.label === 'Inbox' ||
        node.label === 'Review' ||
        node.label === 'Map' ||
        mockTreeData.value.find(n => n.label === 'Inbox')?.children?.some(c => c.id === node.id)

      if (!isInboxOrDirectChild && node.isTerminal) {
        const reviewHistoryKey = `review_history_${node.id}`
        const existingHistory = localStorage.getItem(reviewHistoryKey)

        if (!existingHistory) {
          // 使用 generateMockReviewHistory 生成完整的审核历史
          const reviewRecords = generateMockReviewHistory(node.id, node.label, node.lastChangedBy || 'zhangsan')
          
          // 为一些节点添加特殊的 Map 状态
          if (terminalNodeIndex % 3 === 1) { // 每第三个终端节点添加 Map Approved
            // 添加 Map Approved 记录
            const mapApprovedRecord = {
              id: `${node.id}-map-approved`,
              type: 'response',
              reviewer: 'admin',
              status: 'map approved',
              comment: 'Map Approved - 此文档已通过地图审核，可以进行下一步处理',
              date: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString().split('T')[0] + ' 16:30:00',
              version: '0.0.9',
              reviewType: 'map'
            }
            reviewRecords.unshift(mapApprovedRecord)
          } else if (terminalNodeIndex % 3 === 2) { // 每第四个终端节点添加 Map Reviewed
            // 添加 Map Reviewed 记录
            const mapReviewedRecord = {
              id: `${node.id}-map-reviewed`,
              type: 'response',
              reviewer: 'admin',
              status: 'map reviewed',
              comment: 'Map Reviewed - 地图审核已完成，等待最终批准',
              date: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString().split('T')[0] + ' 14:15:00',
              version: '0.0.9',
              reviewType: 'map'
            }
            reviewRecords.unshift(mapReviewedRecord)
          }
          
          localStorage.setItem(reviewHistoryKey, JSON.stringify(reviewRecords))
        }
        terminalNodeIndex++
      }

      if (node.children) {
        traverse(node.children)
      }
    }
  }

  traverse(mockTreeData.value)
})

const handleToggle = (id: string, isDialog = false) => {
  const targetSet = isDialog ? dialogExpandedIds : expandedIds
  if (targetSet.value.has(id)) {
    targetSet.value.delete(id)
  } else {
    targetSet.value.add(id)
  }
}

const handleDoubleClick = (id: string, node: TreeNode) => {
  if (hasChildren(node)) {
    handleToggle(id)
  }
}

const handleSelect = (id: string, node: TreeNode) => {
  selectedId.value = id
  emit('update:modelValue', id)
  emit('select', node)
}

// 展开所有节点
const expandAll = () => {
  const expandNode = (nodes: TreeNode[]) => {
    nodes.forEach(node => {
      if (node.children && node.children.length > 0) {
        expandedIds.value.add(node.id)
        expandNode(node.children)
      }
    })
  }
  expandNode(mockTreeData.value)
}

// 折叠所有节点
const collapseAll = () => {
  expandedIds.value.clear()
}

const isExpanded = (id: string, isDialog = false) => {
  const targetSet = isDialog ? dialogExpandedIds : expandedIds
  return targetSet.value.has(id)
}
const isSelected = (id: string) => selectedId.value === id

const hasChildren = (node: TreeNode) => node.children && node.children.length > 0
// 终端节点：只根据显式标记的isTerminal判断
const isTerminalNode = (node: TreeNode) => {
  return node.isTerminal === true
}

// 检查节点权限 - 基于末端节点状态
const canCopy = (node: TreeNode) => getNodePermissions(node).copy
const canClone = (node: TreeNode) => getNodePermissions(node).clone
const canBranch = (node: TreeNode) => getNodePermissions(node).branch

// 右键菜单 - 添加边界检查
const handleContextMenu = (e: MouseEvent, nodeId: string) => {
  e.preventDefault()

  const menuWidth = 180
  const menuHeight = 300  // 增加高度以适应更多菜单项
  let x = e.clientX
  let y = e.clientY

  if (x + menuWidth > window.innerWidth) {
    x = window.innerWidth - menuWidth - 10
  }

  if (y + menuHeight > window.innerHeight) {
    y = window.innerHeight - menuHeight - 10
  }

  if (x < 0) x = 10
  if (y < 0) y = 10

  contextMenu.value = {
    show: true,
    x,
    y,
    nodeId
  }
}

const closeContextMenu = () => {
  contextMenu.value.show = false
}

const openOperationDialog = (mode: 'copy' | 'clone' | 'branch') => {
  const currentSourceNodeId = contextMenu.value?.nodeId || ''
  const currentNode = findNode(mockTreeData.value, currentSourceNodeId)
  
  operationDialog.value = {
    show: true,
    mode,
    sourceNodeId: currentSourceNodeId,
    selectedSourceIds: [],
    owner: currentNode?.owner || 'admin'
  }
  dialogExpandedIds.value = new Set(expandedIds.value)
  closeContextMenu()
}

const handleDelete = () => {
  const nodeId = contextMenu.value?.nodeId || ''
  if (nodeId === '1') {
    alert('Cannot delete root node')
    closeContextMenu()
    return
  }
  if (confirm('Are you sure you want to delete this node?')) {
    deleteNodeFromTree(mockTreeData.value, nodeId)
    if (selectedId.value === nodeId) {
      selectedId.value = null
    }
  }
  closeContextMenu()
}

// 添加同级节点
const handleAddSibling = () => {
  console.log('handleAddSibling called')
  const nodeId = contextMenu.value?.nodeId || ''
  console.log('nodeId:', nodeId)
  const node = findNode(mockTreeData.value, nodeId)
  console.log('node found:', node)
  if (!node) return
  
  // 找到父节点
  const parentNode = findParentNode(mockTreeData.value, nodeId)
  console.log('parentNode found:', parentNode)
  
  // 打开添加节点对话框
  // 如果没有父节点，则使用空字符串作为parentNodeId
  addNodeDialog.value = {
    show: true,
    mode: 'sibling',
    parentNodeId: parentNode?.id || '',
    targetNodeId: nodeId,
    nodeType: 'Product Scenario',
    owner: 'admin',
    reviewer: ''
  }
  console.log('addNodeDialog set to show')
  
  closeContextMenu()
}

// 添加下级节点
const handleAddChild = () => {
  console.log('handleAddChild called')
  const nodeId = contextMenu.value?.nodeId || ''
  console.log('nodeId:', nodeId)
  const node = findNode(mockTreeData.value, nodeId)
  console.log('node found:', node)
  if (!node) return
  
  // 打开添加节点对话框
  addNodeDialog.value = {
    show: true,
    mode: 'child',
    parentNodeId: nodeId,
    targetNodeId: nodeId,
    nodeType: 'Product Scenario',
    owner: 'admin',
    reviewer: ''
  }
  console.log('addNodeDialog set to show')
  
  closeContextMenu()
}

// 查找节点在父节点中的索引位置
const findNodeIndex = (parent: TreeNode, targetId: string): number => {
  if (!parent.children) return -1
  return parent.children.findIndex(child => child.id === targetId)
}

// 确认添加节点
const confirmAddNode = () => {
  const { mode, parentNodeId, targetNodeId } = addNodeDialog.value
  const targetNode = findNode(mockTreeData.value, targetNodeId)
  
  if (!targetNode) {
    alert('Node does not exist')
    return
  }
  
  // 获取输入的节点名称
  const nodeName = (document.getElementById('new-node-name') as HTMLInputElement)?.value || 
    (mode === 'sibling' ? '新建节点' : '新建子节点')
  
  // 获取owner
  const owner = addNodeDialog.value.owner || 'admin'
  
  // 获取reviewer
  const reviewer = addNodeDialog.value.nodeType === 'document' ? addNodeDialog.value.reviewer || '' : ''
  
  // 创建新节点
  const newNode: TreeNode = {
    id: `${targetNodeId}-${Date.now()}`,
    label: nodeName,
    type: 'folder',
    status: 'work',
    version: '(1)',
    expanded: false,
    children: undefined,
    isTerminal: false,
    createDate: new Date().toISOString().split('T')[0],
    access: 'Read',
    owner: owner,
    lastChangedBy: owner,
    lastChangedDate: new Date().toISOString().split('T')[0],
    reviewer: reviewer
  }
  
  // 根据模式添加节点
  if (mode === 'sibling') {
    // 如果没有父节点ID，说明是在根级别添加同级节点
    if (!parentNodeId) {
      // 在 mockTreeData 根级别添加
      const targetIndex = mockTreeData.value.findIndex(n => n.id === targetNodeId)
      if (targetIndex !== -1) {
        mockTreeData.value.splice(targetIndex + 1, 0, newNode)
      } else {
        mockTreeData.value.push(newNode)
      }
    } else {
      // 有父节点，在父节点的children中添加
      const parentNode = findNode(mockTreeData.value, parentNodeId)
      if (!parentNode) {
        alert('Parent node does not exist')
        return
      }
      
      if (!parentNode.children) {
        parentNode.children = []
      }
      
      // 找到目标节点在父节点中的位置
      const targetIndex = findNodeIndex(parentNode, targetNodeId)
      
      if (targetIndex !== -1) {
        // 在目标节点后插入新节点
        parentNode.children.splice(targetIndex + 1, 0, newNode)
      } else {
        // 如果没找到，添加到末尾
        parentNode.children.push(newNode)
      }
    }
  } else {
    // 添加下级节点
    if (!targetNode.children) {
      targetNode.children = []
    }
    targetNode.children.push(newNode)
    // 展开目标节点
    expandedIds.value.add(targetNodeId)
  }
  
  // 关闭对话框
  addNodeDialog.value.show = false
}

// 查找父节点的辅助函数
const findParentNode = (nodes: TreeNode[], childId: string, parent: TreeNode | null = null): TreeNode | null => {
  for (const node of nodes) {
    if (node.id === childId) {
      return parent
    }
    if (node.children) {
      const found = findParentNode(node.children, childId, node)
      if (found) return found
    }
  }
  return null
}

// 检查操作是否可用 - 基于节点类型
const isCopyEnabled = (node: TreeNode | null) => {
  return node ? canCopy(node) : false
}

const isCloneEnabled = (node: TreeNode | null) => {
  return node ? canClone(node) : false
}

const isBranchEnabled = (node: TreeNode | null) => {
  return node ? canBranch(node) : false
}

// Check if a node is in Projects tree
const isInProjects = (node: TreeNode): boolean => {
  // Find Projects root
  // Projects is usually at the top level in mockTreeData
  const projectsRoot = mockTreeData.value.find(n => n.label === 'Projects')
  if (!projectsRoot) return false
  
  // Helper to check descendant
  const isDescendant = (parent: TreeNode, targetId: string): boolean => {
    if (parent.id === targetId) return true
    if (parent.children) {
      return parent.children.some(child => isDescendant(child, targetId))
    }
    return false
  }
  
  return isDescendant(projectsRoot, node.id)
}

const isMapEnabled = (node: TreeNode | null) => {
  if (!node) return false
  // Map allowed if: is terminal AND is in Projects tree AND not already mapped
  const isMapped = node.status === 'mapped' || (node.versions && node.versions[0] && node.versions[0].author === '系统映射')
  return isTerminalNode(node) && isInProjects(node) && !isMapped
}

const handleMapTo = () => {
    if (!contextMenuNode.value || !isMapEnabled(contextMenuNode.value)) return
    
    // Select the node
    handleSelect(contextMenuNode.value.id, contextMenuNode.value)
    
    // Switch to Map view
    emit('switch-view', 'map')
    
    // Close menu
    closeContextMenu()
}

const executeOperation = () => {
  // destinationNode (Context Menu Node) is where we want to add the new node (TARGET)
  const destinationNode = findNode(mockTreeData.value, operationDialog.value.sourceNodeId)
  
  if (!destinationNode) {
     return
  }
  
  // Determine actual parent for valid insertion
  // If destination is a Terminal, we add as sibling (to its parent)
  // If destination is a Folder (or Branch), we add as child
  let targetParent = destinationNode
  if (isTerminalNode(destinationNode)) {
     const parent = findParentNode(mockTreeData.value, destinationNode.id)
     if (parent) {
       targetParent = parent
     } else {
       // Should not happen for valid tree structure unless root is terminal
       console.warn('Cannot add to terminal root node')
       return
     }
  }

  const sourceIds = operationDialog.value.selectedSourceIds
  if (sourceIds.length === 0) {
    alert('Please select at least one source node')
    return
  }

  const { mode } = operationDialog.value
  let processedCount = 0

  sourceIds.forEach(sourceId => {
      // sourceNode (Dialog Selection) is where we want to copy FROM (SOURCE)
      const sourceNode = findNode(mockTreeData.value, sourceId)
      if (!sourceNode) return
      
      // Strict constraint: Copy/Clone/Branch only allow terminal nodes as source
      // even if user selected a folder (for UI convenience).
      if (!isTerminalNode(sourceNode)) {
        return
      }

      if (mode === 'copy') {
        const newNode = cloneNode(sourceNode, `${destinationNode.id}-${Date.now()}-${processedCount}`)
        newNode.label = `${newNode.label} (Copy)`
        newNode.owner = operationDialog.value.owner
        addChildNode(targetParent, newNode)
      } else if (mode === 'clone') {
        const newNode: TreeNode = {
          ...sourceNode,
          id: `${destinationNode.id}-${Date.now()}-${processedCount}`,
          label: `${sourceNode.label} (Clone)`,
          isClone: true,
          cloneSourceId: sourceNode.id,
          owner: operationDialog.value.owner
        }
        addChildNode(targetParent, newNode)
      } else if (mode === 'branch') {
         // Even if source is terminal, "Branch" op might function like copy
        const newNode = cloneNode(sourceNode, `${destinationNode.id}-${Date.now()}-${processedCount}`)
        newNode.label = `${newNode.label} (Branch)`
        newNode.owner = operationDialog.value.owner
        addChildNode(targetParent, newNode)
      }
      processedCount++
  })

  operationDialog.value.show = false
  expandedIds.value.add(targetParent.id)
}

const flattenedNodes = computed(() => {
  const result: Array<{ node: TreeNode; level: number }> = []

  const flatten = (nodes: TreeNode[], level: number, isDialog = false) => {
    nodes.forEach(node => {
      result.push({ node, level })
      if (node.children && isExpanded(node.id, isDialog)) {
        flatten(node.children, level + 1, isDialog)
      }
    })
  }

  flatten(mockTreeData.value, 0)
  return result
})

const dialogFlattenedNodes = computed(() => {
  const result: Array<{ node: TreeNode; level: number }> = []

  const flatten = (nodes: TreeNode[], level: number) => {
    nodes.forEach(node => {
      result.push({ node, level })
      if (node.children && isExpanded(node.id, true)) {
        flatten(node.children, level + 1)
      }
    })
  }

  flatten(mockTreeData.value, 0)
  return result
})

const sourceNodeForDialog = computed(() => {
  return findNode(mockTreeData.value, operationDialog.value.sourceNodeId)
})

const contextMenuNode = computed(() => {
  return findNode(mockTreeData.value, contextMenu.value?.nodeId || '')
})

// 更新节点内容的方法
const updateNodeContent = (nodeId: string, content: any) => {
  const node = findNode(mockTreeData.value, nodeId)
  if (node) {
    node.content = content
    // 更新最后修改信息
    node.lastChangedBy = node.owner || 'admin'
    node.lastChangedDate = new Date().toISOString().split('T')[0]
    console.log('Node content updated:', nodeId)
  }
}

// 初始化review_history
const initializeReviewHistory = () => {
  const traverse = (nodes: TreeNode[]) => {
    for (const node of nodes) {
      if (node.isTerminal && node.versions && node.versions.length > 0) {
        const reviewHistoryKey = `review_history_${node.id}`
        const existingHistory = localStorage.getItem(reviewHistoryKey)
        if (!existingHistory) {
          // 使用 generateMockReviewHistory 生成完整的审核历史
          const reviewRecords = generateMockReviewHistory(node.id, node.label, node.lastChangedBy || 'zhangsan')
          localStorage.setItem(reviewHistoryKey, JSON.stringify(reviewRecords))
        }
      }
      if (node.children) {
        traverse(node.children)
      }
    }
  }
  traverse(mockTreeData.value)
}

onMounted(() => {
  initializeReviewHistory()
})

// 暴露方法给父组件
defineExpose({
  updateNodeContent
})
</script>

<template>
  <div class="tree-view" @click="closeContextMenu">
    <div class="tree-header">
      <div class="tree-header-title">
        <span class="tree-header-icon">
          <Database :size="14" />
        </span>
        <span>Vehicle level - Default(modified)</span>
      </div>
      <div class="tree-header-actions">
        <button class="tree-header-btn" title="Expand All" @click="expandAll">
          <Plus :size="12" />
        </button>
        <button class="tree-header-btn" title="Collapse All" @click="collapseAll">
          <Minus :size="12" />
        </button>
      </div>
    </div>
    <div class="tree-content">
      <div class="tree-column-headers">
        <span class="tree-col-name">Name</span>
        <span class="tree-col-status">Status</span>
        <span class="tree-col-version">Version</span>
      </div>
      <div class="tree-nodes">
        <div v-for="{ node, level } in flattenedNodes" :key="node.id"
          :class="['tree-node-wrapper', { 'has-children': hasChildren(node) }]">
          <div :class="['tree-node', { selected: isSelected(node.id) }]" :style="{ paddingLeft: `${level * 16 + 4}px` }"
            @click="handleSelect(node.id, node)" @dblclick="handleDoubleClick(node.id, node)"
            @contextmenu="handleContextMenu($event, node.id)">
            <span class="tree-node-toggle" @click.stop="handleToggle(node.id)">
              <Minus v-if="hasChildren(node) && isExpanded(node.id)" :size="12" />
              <Plus v-else-if="hasChildren(node)" :size="12" />
              <span v-else class="tree-node-spacer" />
            </span>
            <span class="tree-node-icon">
              <Link v-if="isMappedNode(node)" :size="14" class="icon-mapped" />
              <FileText v-else-if="isTerminalNode(node)" :size="14" class="icon-terminal" />
              <FolderOpen v-else-if="isExpanded(node.id)" :size="14" class="icon-folder-open" />
              <Folder v-else :size="14" class="icon-folder" />
            </span>
            <span class="tree-node-label" :title="node.label">
              {{ node.label }}
              <span v-if="node.department" class="dept-badge">[{{ node.department }}]</span>
              <span v-if="node.label === 'Inbox' && inboxTotalCount > 0" class="inbox-count">({{ inboxTotalCount }})</span>
              <span v-if="node.label === 'Map' && mappedCount > 0" class="inbox-count">({{ mappedCount }})</span>
              <span v-if="node.label === 'Review' && pendingReviewCount > 0" class="inbox-count">({{ pendingReviewCount }})</span>
              <span v-if="node.isClone" class="clone-badge">(Clone)</span>
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- 右键菜单 -->
    <div v-if="contextMenu.show" class="context-menu" :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
      @click.stop>
        <div class="menu-group">
          <div class="menu-item" @click="handleAddSibling">
            <CornerUpLeft :size="14" />
            <span>添加同级节点</span>
          </div>
          <div class="menu-item" @click="handleAddChild">
            <CornerDownLeft :size="14" />
            <span>添加下级节点</span>
          </div>
          <div class="menu-item delete" @click="handleDelete">
            <Trash2 :size="14" />
            <span>edit</span>
          </div>
          <div class="menu-item delete" @click="handleDelete">
            <Trash2 :size="14" />
            <span>Delete</span>
          </div>   
        </div>
        <div class="menu-divider"></div>
        <div class="menu-group">
          <div class="menu-item" :class="{ disabled: !isCopyEnabled(contextMenuNode) }"
            @click="isCopyEnabled(contextMenuNode) && openOperationDialog('copy')">
            <Copy :size="14" />
            <span>添加文档 (Copy From)...</span>
          </div>
          <div class="menu-item" :class="{ disabled: !isCloneEnabled(contextMenuNode) }"
            @click="isCloneEnabled(contextMenuNode) && openOperationDialog('clone')">
            <Database :size="14" />
            <span>添加文档 (Clone From)...</span>
          </div>
          <div class="menu-item" :class="{ disabled: !isBranchEnabled(contextMenuNode) }"
            @click="isBranchEnabled(contextMenuNode) && openOperationDialog('branch')">
            <GitBranch :size="14" />
            <span>Branch From...</span>
          </div>
          <div class="menu-item" :class="{ disabled: !isMapEnabled(contextMenuNode) }"
            @click="isMapEnabled(contextMenuNode) && handleMapTo()">
            <Plus :size="14" />
            <span>Map To...</span>
          </div>
        </div>
    </div>

    <!-- 添加节点对话框 -->
    <div v-if="addNodeDialog.show" class="dialog-overlay" @click="addNodeDialog.show = false">
      <div class="add-node-dialog" @click.stop>
        <div class="dialog-header">
          <h3>{{ addNodeDialog.mode === 'sibling' ? '添加同级节点' : '添加下级节点' }}</h3>
          <button class="close-btn" @click="addNodeDialog.show = false">
            <X :size="18" />
          </button>
        </div>

        <div class="dialog-body">
          <div class="input-group">
            <label for="new-node-name">节点名称:</label>
            <input 
              type="text" 
              id="new-node-name" 
              class="node-name-input"
              :placeholder="addNodeDialog.mode === 'sibling' ? '请输入同级节点名称' : '请输入子节点名称'"
              autofocus
              @keyup.enter="confirmAddNode"
            />
          </div>
          
          <div class="input-group">
            <label for="new-node-type">节点类型:</label>
            <div class="radio-group">
              <label 
                v-for="type in nodeTypes" 
                :key="type" 
                class="radio-option"
              >
                <input 
                  type="radio" 
                  :value="type" 
                  v-model="addNodeDialog.nodeType"
                  name="node-type"
                />
                <span>{{ type }}</span>
              </label>
            </div>
          </div>
          
          <div class="input-group">
            <label for="new-node-owner">Owner:</label>
            <input 
              type="text" 
              id="new-node-owner" 
              class="node-owner-input"
              v-model="addNodeDialog.owner"
              placeholder="请输入owner"
            />
          </div>
          
          <div class="input-group" v-if="addNodeDialog.nodeType === 'document'">
            <label for="new-node-reviewer">Reviewer:</label>
            <input 
              type="text" 
              id="new-node-reviewer" 
              class="node-owner-input"
              v-model="addNodeDialog.reviewer"
              placeholder="请输入reviewer"
            />
          </div>
        </div>

        <div class="dialog-footer">
          <button class="btn btn-secondary" @click="addNodeDialog.show = false">取消</button>
          <button class="btn btn-primary" @click="confirmAddNode">确定</button>
        </div>
      </div>
    </div>

    <!-- 操作选择弹窗 -->
    <div v-if="operationDialog.show" class="dialog-overlay" @click="operationDialog.show = false">
      <div class="operation-dialog" @click.stop>
        <div class="dialog-header">
          <h3>{{ operationDialog.mode === 'copy' ? 'Copy Node' : operationDialog.mode === 'clone' ? 'Clone Node' :
            'Branch Node' }}</h3>
          <button class="close-btn" @click="operationDialog.show = false">
            <X :size="18" />
          </button>
        </div>

        <div class="dialog-body">
          <div class="source-info">
            <label>Target (Destination):</label>
            <span class="source-name">{{ sourceNodeForDialog?.label }}</span>
            <span class="source-type">{{ isTerminalNode(sourceNodeForDialog!) ? '(Terminal)' : '(Branch)' }}</span>
          </div>

          <div class="target-selection">
            <label>Select Source:</label>
            <div class="target-tree">
              <div v-for="{ node, level } in dialogFlattenedNodes" :key="node.id"
                :class="['tree-node']"
                :style="{ paddingLeft: `${level * 16 + 8}px` }">
                <span class="tree-node-toggle" @click.stop="handleToggle(node.id, true)">
                  <Minus v-if="hasChildren(node) && isExpanded(node.id, true)" :size="10" />
                  <Plus v-else-if="hasChildren(node)" :size="10" />
                  <span v-else class="tree-node-spacer-small" />
                </span>
                
                <input 
                  type="checkbox" 
                  :checked="isIdsSelected(node)" 
                  :indeterminate.prop="isIdsIndeterminate(node)"
                  :disabled="!isTerminalNode(node)"
                  @change="toggleSourceSelection(node)"
                  style="margin-right: 6px;"
                />

                <span class="tree-node-icon">
                  <Link v-if="isMappedNode(node)" :size="12" class="icon-mapped" />
                  <FileText v-else-if="isTerminalNode(node)" :size="12" class="icon-terminal" />
                  <FolderOpen v-else-if="isExpanded(node.id, true)" :size="12" class="icon-folder-open" />
                  <Folder v-else :size="12" class="icon-folder" />
                </span>
                <span class="tree-node-label-small" @click="toggleSourceSelection(node)">{{ node.label }}</span>
              </div>
            </div>
          </div>
        </div>

        <div class="dialog-footer">
          <div class="owner-input-group">
            <label>Owner:</label>
            <input type="text" v-model="operationDialog.owner" class="dialog-input" />
          </div>
          <div class="dialog-actions">
            <button class="btn btn-secondary" @click="operationDialog.show = false">Cancel</button>
            <button class="btn btn-primary" @click="executeOperation" :disabled="operationDialog.selectedSourceIds.length === 0">
              {{ operationDialog.mode === 'copy' ? 'Copy' : operationDialog.mode === 'clone' ? 'Clone' : 'Branch' }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.tree-view {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  position: relative;
}

.tree-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background: linear-gradient(to bottom, #f5f5f5, #e8e8e8);
  border-bottom: 1px solid #a0a0a0;
}

.tree-header-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: #333;
}

.tree-header-icon {
  color: #0078d4;
}

.tree-header-actions {
  display: flex;
  gap: 4px;
}

.tree-header-btn {
  padding: 4px;
  background: transparent;
  border: 1px solid #c0c0c0;
  border-radius: 2px;
  cursor: pointer;
  color: #666;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tree-header-btn:hover {
  background: #d0d0d0;
  color: #333;
}

.tree-content {
  flex: 1;
  overflow: auto;
}

.tree-column-headers {
  display: flex;
  padding: 4px 8px;
  background: #e8e8e8;
  border-bottom: 1px solid #a0a0a0;
  font-size: 11px;
  font-weight: 600;
  color: #666;
  position: sticky;
  top: 0;
  z-index: 10;
}

.tree-col-name {
  flex: 1;
  min-width: 150px;
}

.tree-col-status,
.tree-col-version {
  width: 70px;
  text-align: center;
}

.tree-nodes {
  padding: 2px 0;
}

.tree-node-wrapper {
  display: flex;
  flex-direction: column;
}

.tree-node {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  cursor: pointer;
  transition: all 0.1s;
  border-bottom: 1px solid transparent;
  user-select: none;
}

.tree-node:hover {
  background: #d0d0d0;
}

.tree-node.selected {
  background: #cde8ff;
  border-bottom-color: #0078d4;
}

.tree-node-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  margin-right: 2px;
  cursor: pointer;
  color: #666;
}

.tree-node-spacer,
.tree-node-spacer-small {
  width: 14px;
}

.tree-node-spacer-small {
  width: 10px;
}

.tree-node-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-right: 4px;
}

.icon-folder,
.icon-folder-open {
  color: #daa520;
}

.icon-requirement {
  color: #0078d4;
}

.icon-subsystem {
  color: #6b8e23;
}

.icon-component {
  color: #cd853f;
}

.icon-attribute {
  color: #9370db;
}

.icon-issue {
  color: #dc3545;
}

.icon-terminal {
  color: #666;
}

.icon-mapped {
  color: #0078d4;
}

.icon-version {
  color: #17a2b8;
}

.icon-default {
  color: #999;
}

.tree-node-label,
.tree-node-label-small {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  color: #333;
}

.tree-node-label-small {
  font-size: 11px;
}

.clone-badge {
  font-size: 10px;
  color: #0078d4;
  margin-left: 4px;
}

.inbox-count {
  color: #dc3545;
  font-weight: bold;
  margin-left: 4px;
}

.dept-badge {
  color: #666;
  font-size: 0.85em;
  margin-left: 6px;
  background: #eaeaea;
  padding: 0 4px;
  border-radius: 3px;
  border: 1px solid #ddd;
}

/* 右键菜单 */
.context-menu {
  position: fixed;
  background: #fff;
  border: 1px solid #c0c0c0;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  min-width: 160px;
  padding: 4px 0;
}

.menu-group {
  padding: 0;
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  cursor: pointer;
  font-size: 13px;
  color: #333;
  transition: background 0.15s;
}

.menu-item:hover:not(.disabled) {
  background: #f0f8ff;
}

.menu-item.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.menu-item.delete {
  color: #dc3545;
}

.menu-item.delete:hover {
  background: #fff5f5;
}

.menu-divider {
  height: 1px;
  background: #e0e0e0;
  margin: 4px 0;
}

/* 操作选择弹窗 */
.dialog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}

.operation-dialog {
  background: #fff;
  border-radius: 6px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
  width: 600px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #e0e0e0;
}

.dialog-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.close-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  color: #666;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-btn:hover {
  color: #333;
}

.dialog-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1;
}

.source-info {
  margin-bottom: 20px;
  padding: 12px;
  background: #f5f5f5;
  border-radius: 4px;
}

.source-info label {
  font-size: 12px;
  color: #666;
  display: block;
  margin-bottom: 4px;
}

.source-name {
  font-weight: 600;
  color: #333;
  margin-right: 8px;
}

.source-type {
  font-size: 11px;
  color: #0078d4;
  background: #e8f4fc;
  padding: 2px 6px;
  border-radius: 3px;
}

.operation-buttons {
  display: flex;
  gap: 12px;
  margin-bottom: 24px;
}

.op-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 16px 12px;
  border: 2px solid #e0e0e0;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  transition: all 0.2s;
}

.op-btn:hover:not(.disabled) {
  border-color: #0078d4;
  background: #f0f8ff;
}

.op-btn.active {
  border-color: #0078d4;
  background: #e8f4fc;
}

.op-btn.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.op-btn span {
  font-weight: 600;
  color: #333;
}

.op-btn small {
  font-size: 11px;
  color: #666;
}

.target-selection {
  margin-top: 20px;
}

.target-selection label {
  display: block;
  font-size: 12px;
  color: #666;
  margin-bottom: 8px;
}

.target-tree {
  max-height: 250px;
  overflow-y: auto;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  background: #fafafa;
}

.target-tree .tree-node {
  padding: 3px 8px;
  border-bottom: 1px solid #f0f0f0;
}

.target-tree .tree-node:last-child {
  border-bottom: none;
}

.target-tree .tree-node:hover {
  background: #f0f0f0;
}

.target-tree .tree-node.selected {
  background: #cde8ff;
  border-bottom-color: #0078d4;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-top: 1px solid #e0e0e0;
}

.owner-input-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.owner-input-group label {
  font-size: 13px;
  font-weight: 500;
  color: #333;
}

.dialog-input {
  padding: 6px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 13px;
  width: 150px;
  outline: none;
  transition: border-color 0.2s;
}

.dialog-input:focus {
  border-color: #0078d4;
}

.dialog-actions {
  display: flex;
  gap: 12px;
}

.btn {
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 13px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all 0.2s;
}

.btn-secondary {
  background: #f5f5f5;
  border-color: #c0c0c0;
  color: #333;
}

.btn-secondary:hover {
  background: #e0e0e0;
}

.btn-primary {
  background: #0078d4;
  border-color: #0078d4;
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: #106ebe;
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 添加节点对话框 */
.add-node-dialog {
  background: #fff;
  border-radius: 6px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
  width: 400px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}

.input-group {
  margin-bottom: 20px;
}

.input-group label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: #333;
  margin-bottom: 8px;
}

.node-name-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
  color: #333;
  outline: none;
  transition: border-color 0.2s;
}

.node-name-input:focus {
  border-color: #0078d4;
  box-shadow: 0 0 0 2px rgba(0, 120, 212, 0.2);
}

.node-name-input::placeholder {
  color: #999;
}

/* 节点类型单选按钮组样式 */
.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.radio-option {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  color: #555;
  transition: all 0.2s;
  background: #fff;
}

.radio-option:hover {
  border-color: #0078d4;
  background: #f0f8ff;
}

.radio-option input[type="radio"] {
  margin: 0;
  cursor: pointer;
}

.radio-option input[type="radio"]:checked + span {
  color: #0078d4;
  font-weight: 500;
}

.radio-option:has(input[type="radio"]:checked) {
  border-color: #0078d4;
  background: #e6f2ff;
}

/* Owner输入框样式 - 与节点名称输入框统一 */
.node-owner-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
  color: #333;
  outline: none;
  transition: border-color 0.2s;
}

.node-owner-input:focus {
  border-color: #0078d4;
  box-shadow: 0 0 0 2px rgba(0, 120, 212, 0.2);
}

.node-owner-input::placeholder {
  color: #999;
}
</style>
