import { type Edge, type Node } from '@xyflow/svelte';

import type { TinyflowData } from '#types';

/**
 * 清理节点中不适合序列化或预览的运行时字段。
 */
export function sanitizeNode(node: Node): Node {
  const { id, type, position, data, parentId } = node;
  return {
    id,
    type,
    position: {
      x: position?.x ?? 0,
      y: position?.y ?? 0,
    },
    data: data ? JSON.parse(JSON.stringify(data)) : {},
    ...(parentId !== undefined && { parentId }),
  };
}

/**
 * 清理边中不适合序列化或预览的运行时字段。
 */
export function sanitizeEdge(edge: Edge): Edge {
  const { id, source, target, sourceHandle, targetHandle, type, data } = edge;
  return {
    id,
    source,
    target,
    ...(sourceHandle !== undefined && { sourceHandle }),
    ...(targetHandle !== undefined && { targetHandle }),
    ...(type !== undefined && { type }),
    data: data ? JSON.parse(JSON.stringify(data)) : {},
  };
}

function sanitizeReadonlyNode(node: Node): Node {
  const sanitized = sanitizeNode(node);
  const nextData =
    sanitized.data && typeof sanitized.data === 'object'
      ? {
          ...sanitized.data,
          expand: false,
        }
      : {};
  return {
    ...sanitized,
    data: nextData,
  };
}

/**
 * 为只读预览重建 tinyflow 数据，移除 viewport 和节点运行时几何状态。
 */
export function sanitizeTinyflowDataForReadonlyPreview(
  input: TinyflowData | string,
): null | TinyflowData | undefined {
  let parsed: TinyflowData | undefined;
  if (typeof input === 'string') {
    const raw = input.trim();
    if (!raw) {
      return null;
    }
    try {
      parsed = JSON.parse(raw);
    } catch {
      return undefined;
    }
  } else {
    parsed = input;
  }

  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
    return undefined;
  }

  const nodes = Array.isArray(parsed.nodes)
    ? parsed.nodes.map((node) => sanitizeReadonlyNode(node as Node))
    : [];
  const edges = Array.isArray(parsed.edges)
    ? parsed.edges.map((edge) => sanitizeEdge(edge as Edge))
    : [];

  return {
    nodes,
    edges,
  };
}
