import React, { useState, useCallback, useRef, useEffect } from 'react';
import {
  ReactFlowProvider,
  useReactFlow,
  useStoreApi,
  Node,
  Edge
} from '@xyflow/react';
import { nodeTypes } from '@/components/FlowEditor/node';
import HistoryProvider from './components/historyContext';
import FlowEditorMain from './FlowEditorMain';
import { useFlowEditorState } from '@/hooks/useFlowEditorState';
import { useFlowCallbacks } from '@/hooks/useFlowCallbacks';

const FlowEditorWithProvider: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?: boolean }> = ({ initialData, useDefault, readOnly }) => {
  return (
    <div style={{ width: '100%', height: '91vh', display: 'flex' }} onContextMenu={(e) => e.preventDefault()}>
      <ReactFlowProvider>
        <FlowEditor initialData={initialData} useDefault={useDefault} readOnly={readOnly} />
      </ReactFlowProvider>
    </div>
  );
};

const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?: boolean }> = ({ initialData, useDefault, readOnly = false }) => {
  const reactFlowInstance = useReactFlow();
  const reactFlowWrapper = useRef<HTMLDivElement>(null);
  const [menu, setMenu] = useState<{
    id: string;
    type: 'node' | 'edge' | 'pane';
    top: number;
    left: number;
    position?: { x: number; y: number };
  } | null>(null);
  const store = useStoreApi();

  // 使用自定义Hook管理状态
  const {
    // State values
    nodes,
    setNodes,
    edges,
    setEdges,
    canvasDataMap,
    editingNode,
    setEditingNode,
    isEditModalOpen,
    setIsEditModalOpen,
    isDelete,
    setIsDelete,
    edgeForNodeAdd,
    setEdgeForNodeAdd,
    positionForNodeAdd,
    setPositionForNodeAdd,
    isRunning,
    historyInitialized,
    setHistoryInitialized,
    historyTimeoutRef,
    updateCanvasDataMapDebounced,

    // Redux
    dispatch,

    // Initial data
    initialData: stateInitialData
  } = useFlowEditorState(initialData, readOnly);

  // 使用自定义Hook管理回调函数
  const {
    // Event handlers
    onNodesChange,
    onEdgesChange,
    onConnect,
    onReconnect,
    onDragOver,
    onDrop,
    onNodeDrag,
    onNodeDragStop,
    onNodesDelete,

    // Menu handlers
    closeEditModal,
    saveNodeEdit,
    deleteNode,
    deleteEdge,
    editNode,
    editEdge,
    copyNode,
    pasteNode, // 添加粘贴节点功能

    // Node operations
    addNodeOnEdge,
    addNodeOnPane,
    handleAddNode,

    // Initialization
    initializeCanvasData,
    updateCanvasDataMapEffect,

    // Actions
    saveFlowDataToServer,
    handleRun,
    handlePause,
    handleReRun
  } = useFlowCallbacks(
    nodes,
    setNodes,
    edges,
    setEdges,
    useDefault,
    reactFlowInstance,
    canvasDataMap,
    dispatch,
    updateCanvasDataMapDebounced,
    initialData,
    historyTimeoutRef,
    setHistoryInitialized,
    editingNode,
    setEditingNode,
    setIsEditModalOpen,
    edgeForNodeAdd,
    setEdgeForNodeAdd,
    positionForNodeAdd,
    setPositionForNodeAdd,
    setIsDelete
  );

  // 节点右键菜单处理
  const onNodeContextMenu = useCallback(
    (event: React.MouseEvent, node: Node) => {
      event.preventDefault();

      const pane = reactFlowWrapper.current?.getBoundingClientRect();
      if (!pane) return;

      setMenu({
        id: node.id,
        type: 'node',
        top: event.clientY - pane.top,
        left: event.clientX - pane.left
      });
    },
    [setMenu]
  );

  // 节点双击处理
  const onNodeDoubleClick = useCallback(
    (event: React.MouseEvent, node: Node) => {
      if (!useDefault) return;
      // 不可编辑的类型
      if (['AND', 'OR', 'JSON2STR', 'STR2JSON', 'IMAGE', 'RESULT'].includes(node.type)) return;
      // 循环开始的节点不展示编辑框
      if (['LOOP_START'].includes(node.data.type as string)) return;
      setEditingNode(node);
      setIsEditModalOpen(true);
    },
    []
  );

  // 边右键菜单处理
  const onEdgeContextMenu = useCallback(
    (event: React.MouseEvent, edge: Edge) => {
      event.preventDefault();

      const pane = reactFlowWrapper.current?.getBoundingClientRect();
      if (!pane) return;

      setMenu({
        id: edge.id,
        type: 'edge',
        top: event.clientY - pane.top,
        left: event.clientX - pane.left
      });
    },
    [setMenu]
  );

  // 画布右键菜单处理
  const onPaneContextMenu = useCallback(
    (event: React.MouseEvent) => {
      event.preventDefault();

      const pane = reactFlowWrapper.current?.getBoundingClientRect();
      if (!pane || !reactFlowInstance) return;

      // 计算在画布中的位置
      const position = reactFlowInstance.screenToFlowPosition({
        x: event.clientX,
        y: event.clientY
      });

      setMenu({
        id: 'pane-context-menu',
        type: 'pane',
        top: event.clientY - pane.top,
        left: event.clientX - pane.left,
        position
      });
    },
    [reactFlowInstance]
  );

  // 点击画布其他区域关闭菜单
  const onPaneClick = useCallback(() => {
    setMenu(null);
  }, [setMenu]);

  // 添加处理粘贴事件的函数
  const handlePasteNode = useCallback((event: ClipboardEvent) => {
    // 检查是否是粘贴操作且在画布区域内
    if (event.clipboardData?.getData('text') === 'paste-node' && menu?.type === 'pane' && menu.position) {
      pasteNode(menu.position);
      setMenu(null);
    }
  }, [menu, pasteNode]);

  // 添加键盘事件监听
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      // 检查是否按下了 Ctrl+V (Windows/Linux) 或 Cmd+V (Mac)
      if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
        // 触发自定义粘贴事件
        const pasteEvent = new ClipboardEvent('paste', {
          clipboardData: new DataTransfer()
        });
        pasteEvent.clipboardData?.setData('text', 'paste-node');
        document.dispatchEvent(pasteEvent);
      }
    };

    // 为画布添加键盘事件监听
    const canvasElement = reactFlowWrapper.current;
    if (canvasElement) {
      canvasElement.addEventListener('keydown', handleKeyDown);
      document.addEventListener('paste', handlePasteNode);
    }

    return () => {
      if (canvasElement) {
        canvasElement.removeEventListener('keydown', handleKeyDown);
      }
      document.removeEventListener('paste', handlePasteNode);
    };
  }, [handlePasteNode]);

  // 监听边的变化，处理添加节点的触发
  useEffect(() => {
    const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger);
    const pane = reactFlowWrapper.current?.getBoundingClientRect();
    if (edgeToAddNode) {
      edgeToAddNode.data.y = (edgeToAddNode.data.clientY as number) - pane.top;
      edgeToAddNode.data.x = (edgeToAddNode.data.clientX as number) - pane.left;
      setEdgeForNodeAdd(edgeToAddNode);

      // 清除触发标志
      setEdges((eds: Edge[]) => eds.map(edge => {
        if (edge.id === edgeToAddNode.id) {
          const { addNodeTrigger, ...restData } = edge.data || {};
          return {
            ...edge,
            data: restData
          };
        }
        return edge;
      }));
    }
  }, [edges]);

  // 初始化画布数据
  useEffect(() => {
    initializeCanvasData();
  }, [initialData]);

  // 实时更新 canvasDataMap
  useEffect(() => {
    return updateCanvasDataMapEffect();
  }, [nodes, edges, initialData?.id, dispatch, canvasDataMap]);

  if (!historyInitialized) {
    return <div>Loading...</div>;
  }

  return (
    <div 
      ref={reactFlowWrapper} 
      style={{ width: '100%', height: '100%' }}
      onContextMenu={(e) => e.preventDefault()}
      tabIndex={0} // 使div可获得焦点以接收键盘事件
    >
      <HistoryProvider
        initialNodes={nodes}
        initialEdges={edges}
        onHistoryChange={(newNodes: Node[], newEdges: Edge[]) => {
          setNodes(newNodes);
          setEdges(newEdges);
        }}
      >
        <FlowEditorMain
          nodes={nodes}
          edges={edges}
          nodeTypes={nodeTypes}
          setNodes={setNodes}
          setEdges={setEdges}
          useDefault={useDefault}
          readOnly={readOnly}
          reactFlowInstance={reactFlowInstance}
          reactFlowWrapper={reactFlowWrapper}
          menu={menu}
          setMenu={setMenu}
          editingNode={editingNode}
          setEditingNode={setEditingNode}
          isEditModalOpen={isEditModalOpen}
          setIsEditModalOpen={setIsEditModalOpen}
          isDelete={isDelete}
          setIsDelete={setIsDelete}
          edgeForNodeAdd={edgeForNodeAdd}
          setEdgeForNodeAdd={setEdgeForNodeAdd}
          positionForNodeAdd={positionForNodeAdd}
          setPositionForNodeAdd={setPositionForNodeAdd}
          isRunning={isRunning}
          initialData={initialData}
          canvasDataMap={canvasDataMap}

          // Event handlers
          onNodesChange={onNodesChange}
          onEdgesChange={onEdgesChange}
          onConnect={onConnect}
          onReconnect={onReconnect}
          onDragOver={onDragOver}
          onDrop={onDrop}
          onNodeDrag={onNodeDrag}
          onNodeDragStop={onNodeDragStop}
          onNodeContextMenu={onNodeContextMenu}
          onNodeDoubleClick={onNodeDoubleClick}
          onEdgeContextMenu={onEdgeContextMenu}
          onPaneContextMenu={onPaneContextMenu}
          onPaneClick={onPaneClick}

          // Menu handlers
          closeEditModal={closeEditModal}
          saveNodeEdit={saveNodeEdit}
          deleteNode={deleteNode}
          deleteEdge={deleteEdge}
          editNode={editNode}
          editEdge={editEdge}
          copyNode={copyNode}
          pasteNode={pasteNode}

          // Node operations
          addNodeOnEdge={addNodeOnEdge}
          addNodeOnPane={addNodeOnPane}
          handleAddNode={handleAddNode}

          // Actions
          saveFlowDataToServer={saveFlowDataToServer}
          handleRun={handleRun}
          handlePause={handlePause}
          handleReRun={handleReRun}
        />
      </HistoryProvider>
    </div>
  );
};

export default FlowEditorWithProvider;