import { useState, useRef, useEffect, useMemo } from 'react';
import { Node, Edge } from '@xyflow/react';
import { debounce } from 'lodash';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { updateCanvasDataMap } from '@/store/ideContainer';

import { Dispatch } from 'redux';

export const useFlowEditorState = (initialData?: any, readOnly?: boolean) => {
  const [nodes, setNodes] = useState<Node[]>([]);
  const [edges, setEdges] = useState<Edge[]>([]);

  // 使用 shallowEqual 比较器来避免不必要的重新渲染
  const ideContainerState = useSelector((state: any) => ({
    canvasDataMap: state.ideContainer.canvasDataMap,
    appRuntimeData: state.ideContainer.appRuntimeData,
    currentAppData: state.ideContainer.currentAppData,
  }), shallowEqual);

  const { canvasDataMap, appRuntimeData, currentAppData } = ideContainerState;
  const dispatch = useDispatch();

  // 辅助函数：获取当前应用/子流程的唯一标识符
  const getCurrentAppKey = (currentAppData: any) => {
    if (!currentAppData) return null;
    // 如果是子流程（key包含'sub'），使用key作为标识符
    if (currentAppData.key && currentAppData.key.includes('sub')) {
      return currentAppData.key;
    }
    // 否则使用id
    return currentAppData.id;
  };

  // 获取当前应用的运行状态
  const currentAppKey = getCurrentAppKey(currentAppData);
  const currentAppIsRunning = currentAppKey && appRuntimeData[currentAppKey]
    ? appRuntimeData[currentAppKey].isRunning
    : false;

  // 添加编辑弹窗相关状态
  const [editingNode, setEditingNode] = useState<Node | null>(null);
  const [isEditModalOpen, setIsEditModalOpen] = useState(false);
  const [isDelete, setIsDelete] = useState(false);

  // 添加节点选择弹窗状态
  const [edgeForNodeAdd, setEdgeForNodeAdd] = useState<Edge | null>(null);
  const [positionForNodeAdd, setPositionForNodeAdd] = useState<{ x: number, y: number } | null>(null);

  // 在组件顶部添加历史记录相关状态
  const [historyInitialized, setHistoryInitialized] = useState(false);
  const historyTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // 更新节点状态，将从store获取的状态应用到节点上
  useEffect(() => {
    // 获取当前应用对应的节点状态映射
    const currentNodeStatusMap = currentAppKey && appRuntimeData[currentAppKey]
      ? appRuntimeData[currentAppKey].nodeStatusMap
      : {};

    // 检查 initialData 中是否包含节点状态（用于查看历史实例）
    const hasInitialDataStatus = initialData?.components &&
      Object.values(initialData.components).some((comp: any) => comp.status);

    setNodes(prevNodes =>{
      return prevNodes.map(node => {
        // 如果是只读模式（历史实例查看），优先使用节点自身的历史状态
        // 如果是正常运行模式，只使用运行时状态
        let nodeStatus = 'waiting';
        let showStatus = false;

        if (readOnly) {
          // 只读模式：使用历史状态
          nodeStatus = node.data.status as string || 'waiting';
          showStatus = hasInitialDataStatus as boolean || node.data.isStatusVisible as boolean || false;
        } else {
          // 正常模式：只使用运行时状态
          nodeStatus = currentNodeStatusMap[node.id] || 'waiting';
          showStatus = currentAppIsRunning;
        }

        return {
          ...node,
          data: {
            ...node.data,
            status: nodeStatus,
            isStatusVisible: showStatus
          }
        };
      });

    });
  }, [appRuntimeData, currentAppKey, currentAppIsRunning, initialData?.id, initialData?.components, nodes.length, readOnly]);

  const updateCanvasDataMapDebounced = useRef(
    debounce((dispatch: Dispatch<any>, canvasDataMap: any, id: string, nodes: Node[], edges: Edge[]) => {
      dispatch(updateCanvasDataMap({
        ...canvasDataMap,
        [id]: { nodes, edges }
      }));
    }, 500)
  ).current;

  return {
    // State values
    nodes,
    setNodes,
    edges,
    setEdges,
    canvasDataMap,
    editingNode,
    setEditingNode,
    isEditModalOpen,
    setIsEditModalOpen,
    isDelete,
    setIsDelete,
    edgeForNodeAdd,
    setEdgeForNodeAdd,
    positionForNodeAdd,
    setPositionForNodeAdd,
    isRunning: currentAppIsRunning, // 使用当前应用的运行状态
    historyInitialized,
    setHistoryInitialized,
    historyTimeoutRef,
    updateCanvasDataMapDebounced,
    
    // Redux
    dispatch,
    
    // Initial data
    initialData: initialData
  };
};