/**
 * 边高亮工具：鼠标进入/选中节点时，高亮相连边；离开/取消选中时，恢复原色。
 *
 * 使用：
 *   import setupEdgeHighlighter from '@/views/logicflow/utils/edgeHighlighter';
 *   setupEdgeHighlighter(graphOrLogicFlowInstance, { hoverColor: '#f56a00', selectedColor: '#1890ff' });
 *
 * 说明：尽量传入你项目中实际的 LogicFlow 实例或 graph（能响应 on/event 且能获取/更新 edge model）。
 */
export default function setupEdgeHighlighter(instance: any, options?: {
  hoverColor?: string
  selectedColor?: string
}) {
  // console.log('setupEdgeHighlighter', instance, options);
  const hoverColor = options?.hoverColor || '#155aef';
  const selectedColor = options?.selectedColor || '#155aef';

  // 兼容性：尝试找到图实例上能注册事件的对象与获取 edges 的方法
  const bus = instance || (window as any).lf || (window as any).logicflow || null;
  if (!bus) {
    console.warn('[edgeHighlighter] 未找到 LogicFlow/graph 实例');
    return;
  }

  // 读取所有边的函数
  function getAllEdges(): any[] {
    return bus.graphModel?.edges || [];
  }

  // 更新边的样式，尝试多种 update API
  function applyEdgeStyle(edgeModel: any, style: any) {
    // console.log('applyEdgeStyle', edgeModel, style, edgeModel.getProperties());
    // bus.setProperties(edgeModel.id, { color: 'red' });

    edgeModel.setProperties(style);
  }

  // 获取与指定节点相连的所有边
  function getConnectedEdgesOf(nodeId: string) {
    const edges = getAllEdges();
    return edges.filter((edge: any) => {
      // 兼容不同字段名：sourceNodeId / targetNodeId / source / target
      const s = edge.sourceNodeId ?? edge.source ?? (edge.model && (edge.model.sourceNodeId ?? edge.model.source));
      const t = edge.targetNodeId ?? edge.target ?? (edge.model && (edge.model.targetNodeId ?? edge.model.target));
      return s === nodeId || t === nodeId;
    });
  }

  // 高亮：记录原始样式并设置为指定颜色
  function highlightEdges(nodeId: string, color: string) {
    const edges = getConnectedEdgesOf(nodeId);
    edges.forEach((edge: any) => {
      applyEdgeStyle(edge.model ?? edge, { strokeColor: color });
    });
  }

  // 恢复：将边样式恢复为原始样式
  function restoreEdges(nodeId: string) {
    // console.log('restoreEdges', nodeId);
    const edges = getConnectedEdgesOf(nodeId);
    edges.forEach((edge: any) => {
      applyEdgeStyle(edge.model ?? edge, { strokeColor: '' });
    });
  }

  // 事件处理：node hover / node leave / node select / node unselect
  function onNodeEnter(payload: any) {
    // console.log('onNodeEnter', payload);
    const node = payload.node ?? payload.data ?? payload;
    const nodeId = node.id ?? (node.model && node.model.id);
    if (!nodeId) {
      return;
    }
    // console.log('nodeId', nodeId);
    highlightEdges(nodeId, hoverColor);
  }

  function onNodeLeave(payload: any) {
    const node = payload.node ?? payload.data ?? payload;
    const nodeId = node.id ?? (node.model && node.model.id);
    if (!nodeId) {
      return;
    }
    restoreEdges(nodeId);
  }

  function onNodeSelect(payload: any) {
    const node = payload.node ?? payload.data ?? payload;
    const nodeId = node.id ?? (node.model && node.model.id);
    if (!nodeId) {
      return;
    }
    highlightEdges(nodeId, selectedColor);
  }

  // function onNodeUnselect(payload: any) {
  //   const node = payload.node ?? payload.data ?? payload;
  //   const nodeId = node.id ?? (node.model && node.model.id);
  //   if (!nodeId) return;
  //   restoreEdges(nodeId);
  // }
  function onEdgeEnter(payload: any) {
    // console.log('payload-->', payload);
    const edgeId = payload.data.id;
    const edgeModel = bus.graphModel.getEdgeModelById(edgeId);
    applyEdgeStyle(edgeModel, { strokeColor: selectedColor });
  }

  function onEdgeLeave(payload: any) {
    const edgeId = payload.data.id;
    const edgeModel = bus.graphModel.getEdgeModelById(edgeId);
    applyEdgeStyle(edgeModel, { strokeColor: '' });
  }
  // 绑定事件，兼容多种事件命名
  try {
    bus.on('node:mouseenter', onNodeEnter);
    bus.on('node:mouseleave', onNodeLeave);
    bus.on('node:click', onNodeSelect);
    bus.on('edge:mouseenter', onEdgeEnter);
    bus.on('edge:mouseleave', onEdgeLeave);
  }
  catch (e) {
    console.warn('[edgeHighlighter] 绑定事件失败', e);
  }

  // 返回控制函数，方便手动触发或销毁
  return {
    highlightEdges,
    restoreEdges,
    destroy() {
      try {
        bus.off('node:mouseenter', onNodeEnter);
        bus.off('node:mouseleave', onNodeLeave);
        bus.off('node:click', onNodeSelect);
      }
      catch (e) {
        // ignore
      }
    },
  };
}
