/**
 * V5-16 T2：版本对比工具（反思闭环支撑）。
 *
 * 对比两个 LessonPlanDocument，输出节点级别的差异：
 * - added: 新版本中新增的节点
 * - removed: 旧版本中有但新版本中删除的节点
 * - modified: 两版本都有但内容（title/data/stage/differentiation）变化的节点
 * - unchanged: 相同的节点
 *
 * 纯函数，无副作用，便于单测。
 */
import type { LessonPlanDocument, LessonPlanNode } from "../types";

/** 差异类型 */
export type DiffChangeType = "added" | "removed" | "modified" | "unchanged";

/** 单个节点的差异 */
export interface NodeDiff {
  type: DiffChangeType;
  /** 新版本中的节点（added/modified/unchanged 时存在） */
  newNode?: LessonPlanNode;
  /** 旧版本中的节点（removed/modified/unchanged 时存在） */
  oldNode?: LessonPlanNode;
  /** modified 时的字段级变更列表 */
  changedFields?: string[];
}

/** 文档对比结果 */
export interface VersionDiffResult {
  diffs: NodeDiff[];
  /** 统计 */
  summary: {
    added: number;
    removed: number;
    modified: number;
    unchanged: number;
  };
}

/** 安全序列化节点数据用于比较（忽略 position 等非内容字段） */
function nodeContentKey(n: LessonPlanNode): string {
  return JSON.stringify({
    title: n.title,
    data: n.data,
    stage: n.stage,
    differentiation: n.differentiation,
    type: n.type,
  });
}

/**
 * 对比两个课案文档，返回节点级差异。
 *
 * @param oldDoc 旧版本文档
 * @param newDoc 新版本文档
 */
export function diffDocuments(
  oldDoc: LessonPlanDocument,
  newDoc: LessonPlanDocument,
): VersionDiffResult {
  const oldNodes = new Map<string, LessonPlanNode>();
  const newNodes = new Map<string, LessonPlanNode>();

  for (const n of oldDoc.nodes) {
    if (n.type !== "textbook_content") oldNodes.set(n.id, n);
  }
  for (const n of newDoc.nodes) {
    if (n.type !== "textbook_content") newNodes.set(n.id, n);
  }

  const diffs: NodeDiff[] = [];
  let added = 0;
  let removed = 0;
  let modified = 0;
  let unchanged = 0;

  // 遍历新版本节点
  for (const [id, newNode] of newNodes) {
    const oldNode = oldNodes.get(id);
    if (!oldNode) {
      diffs.push({ type: "added", newNode });
      added++;
    } else {
      const oldKey = nodeContentKey(oldNode);
      const newKey = nodeContentKey(newNode);
      if (oldKey === newKey) {
        diffs.push({ type: "unchanged", oldNode, newNode });
        unchanged++;
      } else {
        const changedFields: string[] = [];
        if (oldNode.title !== newNode.title) changedFields.push("title");
        if (oldNode.stage !== newNode.stage) changedFields.push("stage");
        if (oldNode.differentiation !== newNode.differentiation) changedFields.push("differentiation");
        if (JSON.stringify(oldNode.data) !== JSON.stringify(newNode.data)) changedFields.push("data");
        diffs.push({ type: "modified", oldNode, newNode, changedFields });
        modified++;
      }
    }
  }

  // 遍历旧版本中已删除的节点
  for (const [id, oldNode] of oldNodes) {
    if (!newNodes.has(id)) {
      diffs.push({ type: "removed", oldNode });
      removed++;
    }
  }

  // 排序：added/removed/modified 优先，unchanged 靠后
  const order: Record<DiffChangeType, number> = {
    removed: 0,
    added: 1,
    modified: 2,
    unchanged: 3,
  };
  diffs.sort((a, b) => order[a.type] - order[b.type]);

  return {
    diffs,
    summary: { added, removed, modified, unchanged },
  };
}

/** 便捷函数：是否有实际变更 */
export function hasChanges(result: VersionDiffResult): boolean {
  return result.summary.added > 0 || result.summary.removed > 0 || result.summary.modified > 0;
}
