/**
 * V5-4：课案导出/打印工具
 *
 * 将画布式 LessonPlanDocument 扁平化为线性教学环节列表，
 * 供打印视图（print-view.tsx）渲染。支持详细版/简洁版两种模式：
 * - detailed: 包含所有 11 种 Block
 * - concise:  仅包含 objective / new_teaching / exercise / homework
 */

import type {
  BlackboardBlockData,
  BlockData,
  ExerciseBlockData,
  HomeworkBlockData,
  ImportBlockData,
  KeyPointBlockData,
  LessonPlan,
  LessonPlanDocument,
  NewTeachingBlockData,
  ObjectiveBlockData,
  ReflectionBlockData,
  RichTextBlockData,
  SummaryBlockData,
  TextStudyBlockData,
  TextbookContentNode,
} from "../types";

/** 导出版本 */
export type ExportVariant = "detailed" | "concise";

/** 简洁版包含的 Block 类型 */
const CONCISE_BLOCK_TYPES = new Set([
  "objective",
  "new_teaching",
  "exercise",
  "homework",
]);

/** 扁平化后的教学环节 */
export interface PrintableSection {
  type: string;
  title: string;
  /** 已扁平化为字符串数组的内容 */
  lines: string[];
}

/** 导出元信息（页眉/页脚用） */
export interface ExportMeta {
  planTitle: string;
  textbookTitle?: string;
  chapterTitle?: string;
  teacherName?: string;
  className?: string;
  /** 备课最后保存时间 ISO */
  lastSavedAt?: string;
  /** 教学时长（分钟），来自 import 节点 durationMin 求和 */
  totalDurationMin: number;
}

/** 导出文档 */
export interface PrintableLessonPlan {
  meta: ExportMeta;
  /** 课文正文（如有 textbook_content 节点） */
  textbookContent: string | null;
  /** 教学环节列表（按 order 排序） */
  sections: PrintableSection[];
  variant: ExportVariant;
}

/**
 * 将画布式文档扁平化为可打印的线性结构。
 *
 * @param plan 课案对象
 * @param meta 元信息（教师名、班级等由调用方注入）
 * @param variant detailed | concise
 */
export function flattenLessonPlanForPrint(
  plan: LessonPlan,
  meta: Partial<ExportMeta>,
  variant: ExportVariant = "detailed",
): PrintableLessonPlan {
  const doc: LessonPlanDocument = plan.content;
  const textbookContent = extractTextbookContent(doc);
  const teachingNodes = doc.nodes
    .filter((n) => n.type !== "textbook_content")
    .filter((n) => variant === "detailed" || CONCISE_BLOCK_TYPES.has(n.type))
    .sort((a, b) => a.order - b.order);

  const sections = teachingNodes.map((node) =>
    flattenBlock(node.type, node.title, node.data as BlockData),
  );

  // V5-4：教学时长由 import 节点求和
  const totalDurationMin = doc.nodes
    .filter((n) => n.type === "import")
    .reduce((sum, n) => {
      const data = n.data as ImportBlockData;
      return sum + (data.durationMin ?? 0);
    }, 0);

  return {
    meta: {
      planTitle: plan.title,
      lastSavedAt: plan.lastSavedAt ?? undefined,
      totalDurationMin,
      ...meta,
    },
    textbookContent,
    sections,
    variant,
  };
}

function extractTextbookContent(doc: LessonPlanDocument): string | null {
  const node = doc.nodes.find(
    (n): n is TextbookContentNode => n.type === "textbook_content",
  );
  if (!node) return null;
  return node.data.content || null;
}

function flattenBlock(
  type: string,
  title: string,
  data: BlockData,
): PrintableSection {
  const lines = flattenBlockData(type, data);
  return { type, title, lines };
}

function flattenBlockData(type: string, data: BlockData): string[] {
  switch (type) {
    case "objective":
      return flattenObjective(data as ObjectiveBlockData);
    case "key_point":
      return flattenKeyPoint(data as KeyPointBlockData);
    case "import":
      return flattenImport(data as ImportBlockData);
    case "new_teaching":
      return flattenNewTeaching(data as NewTeachingBlockData);
    case "summary":
      return flattenSummary(data as SummaryBlockData);
    case "homework":
      return flattenHomework(data as HomeworkBlockData);
    case "blackboard":
      return flattenBlackboard(data as BlackboardBlockData);
    case "reflection":
      return flattenReflection(data as ReflectionBlockData);
    case "exercise":
      return flattenExercise(data as ExerciseBlockData);
    case "text_study":
      return flattenTextStudy(data as TextStudyBlockData);
    case "rich_text":
      return flattenRichText(data as RichTextBlockData);
    default:
      return [];
  }
}

function flattenObjective(data: ObjectiveBlockData): string[] {
  const dimensionLabel: Record<ObjectiveItem["dimension"], string> = {
    knowledge: "知识与技能",
    process: "过程与方法",
    emotion: "情感态度",
  };
  return data.objectives.map(
    (o) => `[${dimensionLabel[o.dimension]}] ${o.text}`,
  );
}

function flattenKeyPoint(data: KeyPointBlockData): string[] {
  return data.keyPoints.map((kp) =>
    kp.type === "key" ? `[重点] ${kp.text}` : `[难点] ${kp.text}`,
  );
}

function flattenImport(data: ImportBlockData): string[] {
  const methodLabel: Record<ImportBlockData["method"], string> = {
    question: "提问导入",
    situation: "情境导入",
    review: "复习导入",
    other: "其他",
  };
  return [
    `方式：${methodLabel[data.method]}`,
    `时长：${data.durationMin} 分钟`,
    data.prompt ? `导入语：${data.prompt}` : "",
  ].filter((s) => s.length > 0);
}

function flattenNewTeaching(data: NewTeachingBlockData): string[] {
  const lines: string[] = [];
  data.teachingPoints.forEach((p, i) => {
    lines.push(`步骤 ${i + 1}：`);
    if (p.outline) lines.push(`  提纲：${p.outline}`);
    if (p.boardNotes) lines.push(`  板书要点：${p.boardNotes}`);
  });
  return lines;
}

function flattenSummary(data: SummaryBlockData): string[] {
  const lines = data.summaryPoints.map((p, i) => `${i + 1}. ${p}`);
  if (data.homeworkPreview) lines.push(`作业预览：${data.homeworkPreview}`);
  return lines;
}

function flattenHomework(data: HomeworkBlockData): string[] {
  const typeLabel: Record<HomeworkAssignment["type"], string> = {
    exercise: "练习",
    reading: "阅读",
    writing: "写作",
  };
  return data.assignments.map(
    (a) => `[${typeLabel[a.type]}] ${a.description}`,
  );
}

function flattenBlackboard(data: BlackboardBlockData): string[] {
  const layoutLabel: Record<BlackboardBlockData["layout"], string> = {
    structure: "结构式",
    mindmap: "思维导图",
    text: "文字式",
  };
  return [`形式：${layoutLabel[data.layout]}`, data.content].filter(
    (s) => s.length > 0,
  );
}

function flattenReflection(data: ReflectionBlockData): string[] {
  const aspectLabel: Record<ReflectionItem["aspect"], string> = {
    effectiveness: "教学效果",
    problems: "存在问题",
    improvements: "改进措施",
  };
  return data.reflection.map(
    (r) => `[${aspectLabel[r.aspect]}] ${r.text}`,
  );
}

function flattenExercise(data: ExerciseBlockData): string[] {
  if (data.items.length === 0) return ["（无题目）"];
  return data.items.map((item, i) => {
    const source = item.source === "inline" ? "课案内新建" : "题库";
    return `${i + 1}. [${source}] 题目 ID: ${item.questionId} （${item.score} 分）`;
  });
}

function flattenTextStudy(data: TextStudyBlockData): string[] {
  if (data.annotations.length === 0) return ["（无文本研习标注）"];
  return data.annotations.map(
    (a, i) => `${i + 1}. [${a.title}] ${a.note}`,
  );
}

function flattenRichText(data: RichTextBlockData): string[] {
  // HTML 简易去标签，仅保留文本（打印友好）
  const text = data.html
    .replace(/<[^>]+>/g, "")
    .replace(/&nbsp;/g, " ")
    .trim();
  return text.length > 0 ? [text] : [];
}

// 仅用于类型推导的本地导入别名，避免在 switch case 中重复 import
type ObjectiveItem = ObjectiveBlockData["objectives"][number];
type HomeworkAssignment = HomeworkBlockData["assignments"][number];
type ReflectionItem = ReflectionBlockData["reflection"][number];
