import { type Edge, type Node, useNodesData, useStore } from '@xyflow/svelte';
import type { Parameter } from '#types';
import { getCurrentNodeId, getOptions } from '#components/utils/NodeUtils';
import { getStartNodeParameterLabel } from '#components/utils/startNodeParameterLabel';
import { nodeIcons } from '../../consts';

const fillRefNodeIds = (
  refNodeIds: string[],
  currentNodeId: string,
  edges: Edge[],
) => {
  for (const edge of edges) {
    if (edge.target === currentNodeId && edge.source) {
      refNodeIds.push(edge.source);
      fillRefNodeIds(refNodeIds, edge.source, edges);
    }
  }
};

const getChildren = (
  params: any,
  parentId: string,
  nodeIsChildren: boolean,
  nodeType: string,
  parentPathLabel = '',
  parentIsCollection = false,
) => {
  if (!params || params.length === 0) return [];
  return params.map((param: any) => {
    const isCollection = param.dataType === 'Array' && param.children && param.children.length > 0;
    const childBaseLabel = param.formLabel || param.displayName || param.name;
    const normalizedChildLabel = String(childBaseLabel || '').trim();
    const pathLabel = !parentPathLabel
      ? normalizedChildLabel
      : parentIsCollection
        ? `${parentPathLabel}.[].${normalizedChildLabel}`
        : `${parentPathLabel}.${normalizedChildLabel}`;
    const dataType = nodeIsChildren
      ? `Array<${param.dataType || 'String'}>`
      : param.dataType || 'String';
    return {
      label: pathLabel,
      dataType: dataType,
      value: parentId + '.' + param.name,
      selectable: true,
      nodeType: nodeType,
      displayLabel: pathLabel,
      pathLabel,
      itemTypeLabel: parentIsCollection ? '数组项字段' : undefined,
      isCollection,
      children: getChildren(
        param.children,
        parentId + '.' + param.name,
        nodeIsChildren,
        nodeType,
        pathLabel,
        isCollection,
      ),
    };
  });
};

const nodeToOptions = (
  node: Node,
  nodeIsChildren: boolean,
  currentNode: Node,
) => {
  const options = getOptions();
  const nodeType = node.type || '';

  let icon: string | undefined = nodeIcons[nodeType];
  if (!icon && options?.customNodes && options.customNodes[nodeType]) {
    icon = options.customNodes[nodeType].icon;
  }

  // 如果仍然获取不到，尝试使用 data.icon (作为回退)
  if (!icon && node.data && node.data.icon) {
    icon = node.data.icon as string;
  }

  const title = node.data.title;

  if (nodeType === 'startNode') {
    const parameters = node.data.parameters as Array<Parameter>;
    const children = [];
    if (parameters)
      for (const parameter of parameters) {
        const dataType = nodeIsChildren
          ? `Array<${parameter.dataType || 'String'}>`
          : parameter.dataType || 'String';
        const label = getStartNodeParameterLabel(parameter);
        children.push({
          label,
          dataType: dataType,
          value: node.id + '.' + parameter.name,
          selectable: true,
          nodeType: nodeType,
        });
      }
    return {
      label: title,
      icon: icon,
      value: node.id,
      selectable: false,
      nodeType: nodeType,
      children,
    };
  } else if (nodeType === 'loopNode' && currentNode.parentId) {
    return {
      label: title,
      icon: icon,
      value: node.id,
      selectable: false,
      nodeType: nodeType,
      children: [
        {
          label: 'loopItem',
          dataType: 'Any',
          value: node.id + '.loopItem',
          selectable: true,
          nodeType: nodeType,
        },
        {
          label: 'index',
          dataType: 'Number',
          value: node.id + '.index',
          selectable: true,
          nodeType: nodeType,
        },
      ],
    };
  } else {
    const outputDefs = node.data.outputDefs;
    if (outputDefs) {
      return {
        label: title,
        icon: icon,
        value: node.id,
        selectable: false,
        nodeType: nodeType,
        children: getChildren(outputDefs, node.id, nodeIsChildren, nodeType),
      };
    }
  }
};

export const useRefOptions: any = (
  useChildrenOnly: boolean | (() => boolean) = false,
) => {
  const currentNodeId = getCurrentNodeId();
  const currentNode = useNodesData(currentNodeId);
  const { nodes, edges, nodeLookup } = $derived(useStore());
  const isChildrenOnly = () =>
    typeof useChildrenOnly === 'function'
      ? useChildrenOnly()
      : useChildrenOnly;

  let selectItems = $derived.by(() => {
    const resultOptions = [];
    if (!currentNode.current) {
      return [];
    }

    //通过 nodeLookup.get 才会得到有 parentId 的 node
    const cNode = nodeLookup.get(currentNodeId)!;

    if (isChildrenOnly()) {
      for (const node of nodes) {
        const nodeIsChildren = node.parentId === currentNode.current.id;
        if (nodeIsChildren) {
          const nodeOptions = nodeToOptions(node, nodeIsChildren, cNode);
          nodeOptions && resultOptions.push(nodeOptions);
        }
      }
    } else {
      const refNodeIds: string[] = [];
      fillRefNodeIds(refNodeIds, currentNodeId, edges);

      for (const node of nodes) {
        if (refNodeIds.includes(node.id)) {
          const nodeIsChildren = node.parentId === currentNode.current.id;
          const nodeOptions = nodeToOptions(node, nodeIsChildren, cNode);
          nodeOptions && resultOptions.push(nodeOptions);
        }
      }
    }

    return resultOptions;
  });

  return {
    get current() {
      return selectItems;
    },
  };
};
