/**
 * 过程关系图页面 (Force Graph)
 * 展示所有实体（过程、工件、工具）及其相互关系
 */
import { useEffect, useRef, useState, useMemo } from 'react'
import G6, { Graph, INode } from '@antv/g6'
import { motion } from 'framer-motion'
import {
  ZoomIn, ZoomOut, Maximize2,
  Activity, FileText, Wrench,
  ChevronRight, ChevronLeft
} from 'lucide-react'
import {
  processes,
  artifacts,
  tools,
  knowledgeAreaMap,
  getProcessDetail,
  getArtifactUsage,
  getToolUsage,
  extractId,
} from '@/data'

export function ProcessGraphPage() {
  const containerRef = useRef<HTMLDivElement>(null)
  const graphRef = useRef<Graph | null>(null)
  const [selectedNode, setSelectedNode] = useState<any>(null)
  const [details, setDetails] = useState<any>(null)
  const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false)

  // 更新详情数据
  useEffect(() => {
    if (!selectedNode) {
      setDetails(null)
      setIsSidebarCollapsed(false)
      return
    }
    
    // 选中新节点时自动展开
    setIsSidebarCollapsed(false)

    if (selectedNode.type === 'process') {
      setDetails(getProcessDetail(selectedNode.id))
    } else if (selectedNode.type === 'artifact') {
      setDetails({
        ...selectedNode,
        usage: getArtifactUsage(selectedNode.id)
      })
    } else if (selectedNode.type === 'tool') {
      setDetails({
        ...selectedNode,
        usage: getToolUsage(selectedNode.id)
      })
    }
  }, [selectedNode])

  // 构建全量数据
  const graphData = useMemo(() => {
    const nodes: any[] = []
    const edges: any[] = []
    const addedNodeIds = new Set<string>()

    // 1. 添加过程节点
    processes.forEach(p => {
      const ka = knowledgeAreaMap.get(p.knowledgeAreaId)
      nodes.push({
        id: p.id,
        label: `${p.code}\n${p.name}`, // 添加编号
        type: 'circle',
        size: 50, // 过程节点最大
        style: {
          fill: ka?.color || '#6366F1',
          stroke: '#fff',
          lineWidth: 3,
          shadowColor: 'rgba(0,0,0,0.2)',
          shadowBlur: 5,
        },
        labelCfg: {
          position: 'center', // 文字居中
          style: {
            fontSize: 12,
            fill: '#fff', // 白色文字
            fontWeight: 700,
            stroke: '#000', // 黑色描边
            lineWidth: 2,
          }
        },
        data: { ...p, type: 'process' },
      })
      addedNodeIds.add(p.id)
    })

    // 2. 添加工件节点和关系
    const usedArtifacts = new Set<string>()
    processes.forEach(p => {
      p.inputs.forEach(ref => usedArtifacts.add(extractId(ref)))
      p.outputs.forEach(ref => usedArtifacts.add(extractId(ref)))
    })

    artifacts.forEach(a => {
      if (usedArtifacts.has(a.id)) {
        nodes.push({
          id: a.id,
          label: a.name,
          type: 'rect', // 工件使用矩形
          size: [80, 30],
          style: {
            fill: '#10B981', // Green
            stroke: '#fff',
            lineWidth: 1,
            radius: 4,
          },
          labelCfg: {
            position: 'center',
            style: {
              fontSize: 11,
              fill: '#fff',
              stroke: '#000',
              lineWidth: 2,
            }
          },
          data: { ...a, type: 'artifact' },
        })
        addedNodeIds.add(a.id)
      }
    })

    // 3. 添加工具节点和关系
    const usedTools = new Set<string>()
    processes.forEach(p => {
      p.tools.forEach(ref => usedTools.add(extractId(ref)))
    })

    tools.forEach(t => {
      if (usedTools.has(t.id)) {
        nodes.push({
          id: t.id,
          label: t.name,
          type: 'diamond', // 工具使用菱形
          size: [80, 40],
          style: {
            fill: '#8B5CF6', // Purple
            stroke: '#fff',
            lineWidth: 1,
          },
          labelCfg: {
            position: 'center',
            style: {
              fontSize: 11,
              fill: '#fff',
              stroke: '#000',
              lineWidth: 2,
            }
          },
          data: { ...t, type: 'tool' },
        })
        addedNodeIds.add(t.id)
      }
    })

    // 4. 构建边
    processes.forEach(p => {
      // 输入关系: Artifact -> Process
      p.inputs.forEach(inputRef => {
        const inputId = extractId(inputRef)
        if (addedNodeIds.has(inputId)) {
          edges.push({
            source: inputId,
            target: p.id,
            type: 'line',
            style: {
              stroke: '#94a3b8',
              opacity: 0.3,
              endArrow: true,
            }
          })
        }
      })

      // 输出关系: Process -> Artifact
      p.outputs.forEach(outputRef => {
        const outputId = extractId(outputRef)
        if (addedNodeIds.has(outputId)) {
          edges.push({
            source: p.id,
            target: outputId,
            type: 'line',
            style: {
              stroke: '#94a3b8',
              opacity: 0.3,
              endArrow: true,
            }
          })
        }
      })

      // 工具关系: Tool -> Process
      p.tools.forEach(toolRef => {
        const toolId = extractId(toolRef)
        if (addedNodeIds.has(toolId)) {
          edges.push({
            source: toolId,
            target: p.id,
            type: 'line',
            style: {
              stroke: '#a78bfa',
              opacity: 0.3,
              lineDash: [4, 2],
            }
          })
        }
      })
    })

    return { nodes, edges }
  }, [])

  useEffect(() => {
    if (!containerRef.current) return

    if (graphRef.current) {
      graphRef.current.destroy()
    }

    const width = containerRef.current.offsetWidth
    const height = containerRef.current.offsetHeight || 800

    const graph = new G6.Graph({
      container: containerRef.current,
      width,
      height,
      fitView: true,
      modes: {
        default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 移除 activate-relations，改为手动控制
      },
      layout: {
        type: 'gForce',
        preventOverlap: true,
        nodeSize: 50,
        linkDistance: () => {
          // 过程节点之间的距离远一点，工件和工具近一点
          return 140
        },
        nodeStrength: 1200,
        edgeStrength: 200,
        gpuEnabled: true,
      },
      defaultNode: {
        size: 30,
        style: {
          lineWidth: 2,
          stroke: '#5B8FF9',
          fill: '#C6E5FF',
          cursor: 'pointer',
        },
        labelCfg: {
          style: {
            fontSize: 11,
            fontWeight: 600,
            fill: '#fff',
            stroke: '#000',
            lineWidth: 2, // 文字描边，增加对比度
          }
        }
      },
      defaultEdge: {
        size: 1,
        color: '#e2e2e2',
        style: {
          cursor: 'pointer',
        }
      },
      nodeStateStyles: {
        active: {
          opacity: 1,
          shadowColor: 'rgba(0,0,0,0.5)',
          shadowBlur: 10,
        },
        inactive: {
          opacity: 0.1,
        },
        selected: {
          lineWidth: 4,
          stroke: '#F59E0B', // 选中时金色边框
          shadowColor: '#F59E0B',
          shadowBlur: 15,
          opacity: 1,
        }
      },
      edgeStateStyles: {
        active: {
          opacity: 1,
          stroke: '#333',
          lineWidth: 2,
        },
        inactive: {
          opacity: 0.05,
        },
      },
    })

    graph.data(graphData)
    graph.render()

    // 监听节点点击
    graph.on('node:click', (e) => {
      const item = e.item as INode
      const model = item.getModel()

      // 更新选中状态
      setSelectedNode({
        ...model.data as any,
        type: (model.data as any).type
      })

      // 高亮逻辑
      const nodes = graph.getNodes()
      const edges = graph.getEdges()

      // 1. 重置所有状态
      nodes.forEach(n => {
        graph.clearItemStates(n, ['active', 'inactive', 'selected'])
        graph.setItemState(n, 'inactive', true) // 默认全部变暗
      })
      edges.forEach(e => {
        graph.clearItemStates(e, ['active', 'inactive'])
        graph.setItemState(e, 'inactive', true) // 默认全部变暗
      })

      // 2. 高亮当前节点
      graph.setItemState(item, 'inactive', false)
      graph.setItemState(item, 'selected', true)

      // 3. 高亮邻居节点和边
      item.getNeighbors().forEach(neighbor => {
        graph.setItemState(neighbor, 'inactive', false)
        graph.setItemState(neighbor, 'active', true)
      })

      item.getEdges().forEach(edge => {
        graph.setItemState(edge, 'inactive', false)
        graph.setItemState(edge, 'active', true)
      })
    })

    // 画布点击清除选中
    graph.on('canvas:click', () => {
      setSelectedNode(null)
      // 恢复所有节点和边
      const nodes = graph.getNodes()
      const edges = graph.getEdges()
      nodes.forEach(n => {
        graph.clearItemStates(n, ['active', 'inactive', 'selected'])
      })
      edges.forEach(e => {
        graph.clearItemStates(e, ['active', 'inactive'])
      })
    })

    graphRef.current = graph

    const handleResize = () => {
      if (containerRef.current && graphRef.current) {
        graphRef.current.changeSize(
          containerRef.current.offsetWidth,
          containerRef.current.offsetHeight
        )
      }
    }
    window.addEventListener('resize', handleResize)

    return () => {
      window.removeEventListener('resize', handleResize)
      if (graphRef.current) {
        graphRef.current.destroy()
      }
    }
  }, [graphData])

  return (
    <div className="flex h-[calc(100vh-100px)] bg-gray-50 dark:bg-gray-900 rounded-xl overflow-hidden border border-gray-200 dark:border-gray-700 relative">
      
      {/* 图例 */}
      <div className="absolute top-4 left-4 bg-white/90 dark:bg-gray-800/90 p-3 rounded-lg shadow-md border border-gray-100 dark:border-gray-700 z-10 flex flex-col gap-2">
        <div className="flex items-center gap-2 text-xs font-medium">
          <div className="w-3 h-3 rounded-full bg-indigo-500"></div>
          <span>过程 (Process) - 圆形</span>
        </div>
        <div className="flex items-center gap-2 text-xs font-medium">
          <div className="w-3 h-3 rounded bg-emerald-500"></div>
          <span>工件 (Artifact) - 矩形</span>
        </div>
        <div className="flex items-center gap-2 text-xs font-medium">
          <div className="w-3 h-3 rotate-45 bg-purple-500"></div>
          <span>工具 (Tool) - 菱形</span>
        </div>
      </div>

      {/* 画布 */}
      <div ref={containerRef} className="w-full h-full" />

      {/* 缩放控制 */}
      <div className="absolute bottom-4 left-4 flex flex-col gap-2 bg-white dark:bg-gray-800 p-1 rounded-lg shadow-md border border-gray-200 dark:border-gray-700">
        <button onClick={() => graphRef.current?.zoom(1.2)} className="p-2 hover:bg-gray-100 rounded"><ZoomIn size={18}/></button>
        <button onClick={() => graphRef.current?.zoom(0.8)} className="p-2 hover:bg-gray-100 rounded"><ZoomOut size={18}/></button>
        <button onClick={() => graphRef.current?.fitView()} className="p-2 hover:bg-gray-100 rounded"><Maximize2 size={18}/></button>
      </div>

      {/* 右侧详情面板 */}
      {selectedNode && details && (
        <>
          {/* 折叠/展开按钮 */}
          <motion.button
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            onClick={() => setIsSidebarCollapsed(!isSidebarCollapsed)}
            className={`absolute top-1/2 -translate-y-1/2 z-30 p-1.5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-lg rounded-l-lg text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-all ${
              isSidebarCollapsed ? 'right-0' : 'right-96'
            }`}
          >
            {isSidebarCollapsed ? <ChevronLeft size={20} /> : <ChevronRight size={20} />}
          </motion.button>

          <motion.div
            initial={{ x: '100%' }}
            animate={{ x: isSidebarCollapsed ? '100%' : 0 }}
            exit={{ x: '100%' }}
            transition={{ type: 'spring', damping: 25, stiffness: 200 }}
            className="absolute right-0 top-0 bottom-0 w-96 bg-white dark:bg-gray-800 border-l border-gray-200 dark:border-gray-700 shadow-2xl z-20 flex flex-col"
          >
            {/* Header */}
            <div className="p-6 border-b border-gray-100 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50">
              <div className="flex items-center gap-2 mb-3">
                {selectedNode.type === 'process' && <Activity className="text-indigo-600 dark:text-indigo-400" size={20} />}
                {selectedNode.type === 'artifact' && <FileText className="text-emerald-600 dark:text-emerald-400" size={20} />}
                {selectedNode.type === 'tool' && <Wrench className="text-purple-600 dark:text-purple-400" size={20} />}
                <span className="text-xs font-bold uppercase text-gray-500 dark:text-gray-400 tracking-wider">
                  {selectedNode.type === 'process' ? '过程 Process' : selectedNode.type === 'artifact' ? '工件 Artifact' : '工具 Tool'}
                </span>
              </div>
              <h2 className="text-xl font-bold text-gray-900 dark:text-white mb-1 leading-tight">{selectedNode.name}</h2>
              <div className="text-sm text-gray-500 dark:text-gray-400 font-medium">{selectedNode.nameEn}</div>
              
              {selectedNode.type === 'process' && (
                <div className="mt-3 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800 dark:bg-indigo-900/30 dark:text-indigo-300">
                  {selectedNode.code}
                </div>
              )}
            </div>

            {/* Content */}
            <div className="flex-1 overflow-y-auto p-6 space-y-6">
            
            {/* Process Details */}
            {selectedNode.type === 'process' && details.inputDetails && (
              <>
                <div>
                  <h3 className="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                    <span className="w-1.5 h-1.5 rounded-full bg-emerald-500"></span>
                    输入 (Inputs)
                  </h3>
                  <div className="space-y-2">
                    {details.inputDetails.length > 0 ? (
                      details.inputDetails.map((item: any) => (
                        <div key={item.id} className="p-3 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700 hover:border-emerald-200 dark:hover:border-emerald-800 transition-colors">
                          <div className="text-sm font-medium text-gray-800 dark:text-gray-200">{item.name}</div>
                        </div>
                      ))
                    ) : <div className="text-sm text-gray-400 italic">无输入</div>}
                  </div>
                </div>

                <div>
                  <h3 className="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                    <span className="w-1.5 h-1.5 rounded-full bg-purple-500"></span>
                    工具与技术 (Tools)
                  </h3>
                  <div className="space-y-2">
                    {details.toolDetails.length > 0 ? (
                      details.toolDetails.map((item: any) => (
                        <div key={item.id} className="p-3 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700 hover:border-purple-200 dark:hover:border-purple-800 transition-colors">
                          <div className="text-sm font-medium text-gray-800 dark:text-gray-200">{item.name}</div>
                        </div>
                      ))
                    ) : <div className="text-sm text-gray-400 italic">无工具</div>}
                  </div>
                </div>

                <div>
                  <h3 className="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                    <span className="w-1.5 h-1.5 rounded-full bg-blue-500"></span>
                    输出 (Outputs)
                  </h3>
                  <div className="space-y-2">
                    {details.outputDetails.length > 0 ? (
                      details.outputDetails.map((item: any) => (
                        <div key={item.id} className="p-3 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700 hover:border-blue-200 dark:hover:border-blue-800 transition-colors">
                          <div className="text-sm font-medium text-gray-800 dark:text-gray-200">{item.name}</div>
                        </div>
                      ))
                    ) : <div className="text-sm text-gray-400 italic">无输出</div>}
                  </div>
                </div>
              </>
            )}

            {/* Artifact Details */}
            {selectedNode.type === 'artifact' && details.usage && (
              <>
                <div>
                  <h3 className="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                    <span className="w-1.5 h-1.5 rounded-full bg-indigo-500"></span>
                    作为输入 (Used By)
                  </h3>
                  <div className="space-y-2">
                    {details.usage.asInput.length > 0 ? (
                      details.usage.asInput.map((p: any) => (
                        <div key={p.id} className="p-3 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700">
                          <div className="flex items-center justify-between mb-1">
                            <span className="text-xs font-bold text-indigo-600 dark:text-indigo-400">{p.code}</span>
                          </div>
                          <div className="text-sm font-medium text-gray-800 dark:text-gray-200">{p.name}</div>
                        </div>
                      ))
                    ) : <div className="text-sm text-gray-400 italic">无引用</div>}
                  </div>
                </div>

                <div>
                  <h3 className="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                    <span className="w-1.5 h-1.5 rounded-full bg-blue-500"></span>
                    作为输出 (Produced By)
                  </h3>
                  <div className="space-y-2">
                    {details.usage.asOutput.length > 0 ? (
                      details.usage.asOutput.map((p: any) => (
                        <div key={p.id} className="p-3 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700">
                          <div className="flex items-center justify-between mb-1">
                            <span className="text-xs font-bold text-blue-600 dark:text-blue-400">{p.code}</span>
                          </div>
                          <div className="text-sm font-medium text-gray-800 dark:text-gray-200">{p.name}</div>
                        </div>
                      ))
                    ) : <div className="text-sm text-gray-400 italic">无来源</div>}
                  </div>
                </div>
              </>
            )}

            {/* Tool Details */}
            {selectedNode.type === 'tool' && details.usage && (
              <>
                <div>
                  <h3 className="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                    <span className="w-1.5 h-1.5 rounded-full bg-indigo-500"></span>
                    使用于 (Used In)
                  </h3>
                  <div className="space-y-2">
                    {details.usage.length > 0 ? (
                      details.usage.map((p: any) => (
                        <div key={p.id} className="p-3 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700">
                          <div className="flex items-center justify-between mb-1">
                            <span className="text-xs font-bold text-indigo-600 dark:text-indigo-400">{p.code}</span>
                          </div>
                          <div className="text-sm font-medium text-gray-800 dark:text-gray-200">{p.name}</div>
                        </div>
                      ))
                    ) : <div className="text-sm text-gray-400 italic">未使用</div>}
                  </div>
                </div>
              </>
            )}

            </div>
          </motion.div>
        </>
      )}
    </div>
  )
}
