import { createId } from "@paralleldrive/cuid2";
import type {
  LessonPlanDocument,
  LessonPlanDocumentV1,
  LessonPlanEdge,
  LessonPlanNode,
  TemplateBlockSkeleton,
} from "../types";

/**
 * 纯函数模块：课案文档迁移、规范化、初始内容构建。
 * 从 data-access.ts 抽取，便于单元测试。
 */

// ---- v1 → v2 迁移：将旧 blocks 数组转换为 nodes + 线性 edges ----
export function migrateV1ToV2(doc: LessonPlanDocumentV1): LessonPlanDocument {
  const nodes: LessonPlanNode[] = doc.blocks.map((b, i) => ({
    ...b,
    position: { x: 80 + (i % 4) * 280, y: 80 + Math.floor(i / 4) * 200 },
  }));
  const edges: LessonPlanEdge[] = [];
  for (let i = 0; i < nodes.length - 1; i++) {
    edges.push({
      id: `e_${nodes[i].id}_${nodes[i + 1].id}`,
      source: nodes[i].id,
      target: nodes[i + 1].id,
    });
  }
  return { version: 2, nodes, edges };
}

// ---- 类型守卫：判断是否为 v2 文档 ----
function isV2Document(content: unknown): content is LessonPlanDocument {
  if (!content || typeof content !== "object") return false;
  const c = content as { version?: unknown; nodes?: unknown; edges?: unknown };
  return (
    c.version === 2 &&
    Array.isArray(c.nodes) &&
    Array.isArray(c.edges)
  );
}

// ---- 类型守卫：判断是否为 v1 文档 ----
function isV1Document(content: unknown): content is LessonPlanDocumentV1 {
  if (!content || typeof content !== "object") return false;
  const c = content as { version?: unknown; blocks?: unknown };
  return c.version === 1 && Array.isArray(c.blocks);
}

// ---- 规范化：确保 content 是 v2 格式（兼容旧数据）----
export function normalizeDocument(
  content: unknown,
): LessonPlanDocument {
  if (isV2Document(content)) return content;
  if (isV1Document(content)) return migrateV1ToV2(content);
  // 空文档
  return { version: 2, nodes: [], edges: [] };
}

// ---- 模板初始化：根据骨架生成初始 content（v2）----
export function buildInitialContent(
  blocks: TemplateBlockSkeleton[],
): LessonPlanDocument {
  const nodes: LessonPlanNode[] = blocks.map((b, i) => ({
    id: createId(),
    type: b.type,
    title: b.title,
    data:
      b.type === "exercise"
        ? { items: [], purpose: "class_practice", knowledgePointIds: [] }
        : b.type === "text_study"
          ? { sourceText: "", annotations: [], knowledgePointIds: [] }
          : { html: "", knowledgePointIds: [] },
    order: i,
    position: { x: 80 + (i % 4) * 280, y: 80 + Math.floor(i / 4) * 200 },
  }));
  const edges: LessonPlanEdge[] = [];
  for (let i = 0; i < nodes.length - 1; i++) {
    edges.push({
      id: `e_${nodes[i].id}_${nodes[i + 1].id}`,
      source: nodes[i].id,
      target: nodes[i + 1].id,
    });
  }
  return { version: 2, nodes, edges };
}
