import React, { useState, useEffect, useRef } from 'react';
import { BaseEdge, EdgeLabelRenderer, EdgeProps, getSmoothStepPath, useReactFlow, getEdgeCenter } from '@xyflow/react';
import EdgeAddNodeButton from '@/pages/flowEditor/components/edgeAddNodeButton';
import { getTopicList } from '@/api/event';
import { useSelector } from 'react-redux';
import { Message } from '@arco-design/web-react';

type DataDisplayEdgeData = {
  label?: string;
  value?: any;
  name?: string;
  topic?: string;
  eventId?: string;
  lineType?: string; // 添加lineType属性
};

const DataDisplayEdge: React.FC<EdgeProps> = ({
                                                id,
                                                sourceX,
                                                sourceY,
                                                targetX,
                                                targetY,
                                                sourcePosition,
                                                targetPosition,
                                                style = {},
                                                markerEnd,
                                                selected,
                                                data
                                              }) => {
  const [isOpen, setIsOpen] = useState(false);
  const [selectedValue, setSelectedValue] = useState('');
  const dropdownRef = useRef<HTMLDivElement>(null);
  const [edgePath, labelX, labelY] = getSmoothStepPath({
    sourceX,
    sourceY,
    sourcePosition,
    targetX,
    targetY,
    targetPosition,
    borderRadius: 8 // 设置圆角半径
  });
  const { info, eventTopicList } = useSelector((state: any) => state.ideContainer);

  // 从数据中获取悬停状态
  const hovered = data?.hovered || false;

  // 从数据中获取要显示的信息
  const displayData: DataDisplayEdgeData = data?.displayData || {};

  // 获取lineType
  const lineType = data?.lineType || 'data'; // 默认为data类型

  // 使用useReactFlow钩子获取setEdges方法
  const { setEdges, getEdges, getNodes } = useReactFlow();

  // 计算智能标签位置，避免重叠
  const calculateSmartLabelPosition = () => {
    const edges = getEdges();
    const nodes = getNodes();

    // 获取当前边
    const currentEdge = edges.find(e => e.id === id);
    if (!currentEdge) return { x: labelX, y: labelY };

    // 获取源节点和目标节点
    const sourceNode = nodes.find(n => n.id === currentEdge.source);
    const targetNode = nodes.find(n => n.id === currentEdge.target);
    if (!sourceNode || !targetNode) return { x: labelX, y: labelY };

    // 查找连接相同节点对的所有边（包括反向连接）
    const relatedEdges = edges.filter(edge => {
      if (edge.id === id) return false;

      // 检查是否连接相同的节点对
      return (
        (edge.source === currentEdge.source && edge.target === currentEdge.target) ||
        (edge.source === currentEdge.target && edge.target === currentEdge.source)
      );
    });

    // 如果没有相关的边，使用默认中心位置
    if (relatedEdges.length === 0) {
      return { x: labelX, y: labelY };
    }

    // 将当前边加入并排序，确保位置分配稳定
    const allRelatedEdges = [...relatedEdges, currentEdge].sort((a, b) =>
      a.id.localeCompare(b.id)
    );

    // 找到当前边的索引
    const currentIndex = allRelatedEdges.findIndex(e => e.id === id);

    // 根据索引沿着边的路径分配位置
    // 第1条边在中心(0.5)，其他边向两侧分散
    let positionRatio = 0.5;

    if (currentIndex > 0) {
      // 奇数索引向源节点方向，偶数索引向目标节点方向
      const direction = currentIndex % 2 === 1 ? -1 : 1;
      const step = Math.ceil(currentIndex / 2);
      const offset = step * 0.15 * direction; // 每次偏移15%
      positionRatio = Math.max(0.2, Math.min(0.8, 0.5 + offset));
    }

    // 计算沿边路径的实际坐标
    const actualX = sourceX + (targetX - sourceX) * positionRatio;
    const actualY = sourceY + (targetY - sourceY) * positionRatio;

    return { x: actualX, y: actualY };
  };

  // 获取智能位置（支持手动覆盖）
  const smartPosition = data?.labelPosition
    ? {
      x: sourceX + (targetX - sourceX) * (data.labelPosition as number),
      y: sourceY + (targetY - sourceY) * (data.labelPosition as number)
    }
    : calculateSmartLabelPosition();

  // 边点击处理函数
  const handleEdgeAddNode = (e) => {
    // 如果是数据类型边线，不允许添加节点
    if (lineType === 'data') {
      console.warn('数据类型边线上不允许添加节点');
      Message.warning('数据类型连接线上不允许添加节点');
      return;
    }

    // 更新边的数据，触发边上添加节点的流程
    setEdges(eds => eds.map(edge => {
      if (edge.id === id) {
        return {
          ...edge,
          data: {
            ...edge.data,
            addNodeTrigger: true,
            clientX: e.clientX,
            clientY: e.clientY
          }
        };
      }
      return edge;
    }));
  };

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, []);

  const handleSelect = (option) => {
    setSelectedValue(option.label);
    setIsOpen(false);

    // 查找所有具有相同事件ID和连接点的边并同步更新
    setEdges(eds => eds.map((edge: any) => {
      // 检查边是否有displayData且与当前选择的事件匹配
      if (edge.data?.displayData &&
        edge.data.displayData.eventId === displayData.eventId &&
        edge.data.displayData.topic === displayData.topic) {
        return {
          ...edge,
          data: {
            ...edge.data,
            displayData: {
              ...edge.data.displayData,
              name: option.label,
              topic: option.value
            }
          }
        };
      }
      return edge;
    }));
  };

  return (
    <>
      <BaseEdge
        path={edgePath}
        markerEnd={markerEnd}
        style={{
          stroke: selected ? '#1890ff' : '#b1b1b7',
          strokeWidth: selected ? 2 : 1,
          ...style
        }}
      />
      <EdgeLabelRenderer>
        <div
          style={{
            position: 'absolute',
            transform: `translate(-50%, -50%) translate(${smartPosition.x}px,${smartPosition.y}px)`,
            fontSize: 12,
            pointerEvents: 'all',
            opacity: style?.opacity || 1, // 应用透明度样式到标签容器
            zIndex: selected ? 1000 : 100 // 选中的边标签显示在最上层
          }}
          className="nodrag nopan"
        >
          {/* 数据展示框 */}
          {displayData && Object.keys(displayData).length > 0 && (
            <div
              ref={dropdownRef}
              style={{
                width: 150,
                border: isOpen ? '1px solid #1890ff' : '1px solid #d9d9d9',
                borderRadius: 4,
                backgroundColor: '#fff',
                position: 'relative',
                opacity: style?.opacity || 1 // 应用透明度样式到下拉框
              }}
            >
              <div
                onClick={() => setIsOpen(!isOpen)}
                style={{
                  padding: '4px 11px',
                  cursor: 'pointer',
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center'
                }}
              >
                <span>{selectedValue || displayData.name}</span>
                <span>{isOpen ? '▲' : '▼'}</span>
              </div>

              {isOpen && (
                <div
                  style={{
                    position: 'absolute',
                    top: '105%',
                    left: 0,
                    right: 0,
                    border: '1px solid #d9d9d9',
                    borderTop: 'none',
                    borderRadius: '0 0 4px 4px',
                    backgroundColor: '#fff',
                    zIndex: 1000,
                    maxHeight: 200,
                    overflowY: 'auto',
                    opacity: style?.opacity || 1 // 应用透明度样式到下拉列表
                  }}
                >
                  {eventTopicList.map((option: { value: string; label: string }) => (
                    <div
                      key={option.value}
                      onClick={() => handleSelect(option)}
                      style={{
                        padding: '5px 12px',
                        cursor: 'pointer',
                        borderBottom: '1px solid #f0f0f0'
                      }}
                      onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#f5f5f5'}
                      onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#fff'}
                    >
                      {option.label}
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          {hovered && Object.keys(displayData).length === 0 && lineType !== 'data' && (
            <EdgeAddNodeButton
              onClick={(e) => handleEdgeAddNode(e)}
              style={{ opacity: style?.opacity || 1 }} // 应用透明度样式到添加节点按钮
            />
          )}
        </div>
      </EdgeLabelRenderer>
    </>
  );
};

export default DataDisplayEdge;