import "dotenv/config";
import { db } from "../src/shared/db";
import {
  users, roles, usersToRoles, rolePermissions,
  questions, knowledgePoints, questionsToKnowledgePoints,
  exams, examQuestions, examSubmissions, submissionAnswers,
  homeworkAssignments, homeworkAssignmentQuestions,
  homeworkAssignmentTargets, homeworkSubmissions, homeworkAnswers,
  textbooks, chapters,
  schools, grades, classes, classEnrollments, classSchedule,
  classSubjectTeachers, subjects, academicYears,
  parentStudentRelations,
  announcements,
  gradeRecords,
  coursePlans, coursePlanItems,
  attendanceRecords,
} from "../src/shared/db/schema";
import { createId } from "@paralleldrive/cuid2";
import { sql, eq } from "drizzle-orm";
import { hash } from "bcryptjs";
import { ROLE_PERMISSIONS } from "../src/shared/lib/permissions";

// ---- 内部类型定义（避免 any） ----

interface SeedOption {
  id: string;
  text: string;
  isCorrect?: boolean;
}

interface SeedQuestionContent {
  text?: string;
  options?: SeedOption[];
  correctAnswer?: string | boolean;
}

interface SeedQuestion {
  id: string;
  type: "single_choice" | "text" | "judgment";
  difficulty: number;
  content: SeedQuestionContent;
  score: number;
}

interface SeedQuestionBank {
  chineseQuestions: SeedQuestion[];
  mathQuestions: SeedQuestion[];
  engQuestions?: SeedQuestion[];
}

interface SeedGradeRecord {
  id: string;
  studentId: string;
  subjectId: string;
  classId: string;
  teacherId: string;
  score: number;
  examType: string;
  term: string;
  recordedAt: Date;
}

interface SeedAttendanceRecord {
  id: string;
  studentId: string;
  classId: string;
  date: Date;
  status: "present" | "late" | "absent";
  recorderId: string;
  remark: string | null;
}

/**
 * 小学场景初始化脚本
 *
 * 数据规模：
 * - 1 所小学
 * - 2 个年级（一年级、二年级）
 * - 每个年级 2 个班级（共 4 个班）
 * - 每班 2 个老师（1 班主任 + 1 任课），跨班凑齐语数外 3 科
 * - 每班 6 名学生（共 24 名学生）
 * - 每名学生 1 位家长（共 24 位家长）
 * - 语数外 3 科，每科 1 本教材（含第一章第一节课）
 * - 2 套试卷（语文、数学），含学生答题与批改
 * - 配套作业、成绩、考勤、公告、课程计划数据
 *
 * 所有账号密码统一为：123456
 */

// ============ 类型与常量 ============

const PASSWORD = "123456";
const NOW = new Date();

// ============ 主流程 ============

async function seed() {
  console.log("🌱 开始小学场景数据初始化...");
  const start = performance.now();

  // --- 0. 清理数据 ---
  await cleanup();

  // --- 1. 角色 + 权限 ---
  await seedRolesAndPermissions();

  // --- 2. 学科 ---
  const subjectMap = await seedSubjects();

  // --- 3. 学校 + 年级 + 学年 ---
  const { schoolId, gradeMap, academicYearId } = await seedSchoolAndGrades();

  // --- 4. 用户（admin + 老师 + 学生 + 家长）---
  const { adminId, teacherMap, studentMap, parentMap } = await seedUsers(schoolId, gradeMap);

  // --- 5. 班级 + 师生关系 ---
  const classMap = await seedClasses(schoolId, gradeMap, teacherMap);

  // --- 6. 班级-学科-老师关联（凑齐语数外）---
  await seedClassSubjectTeachers(classMap, teacherMap, subjectMap);

  // --- 7. 学生分班 + 家长-学生关联 ---
  await seedEnrollmentsAndParents(classMap, studentMap, parentMap);

  // --- 8. 教材 + 章节（每科第一章第一节课）---
  const chapterMap = await seedTextbooksAndChapters();

  // --- 9. 知识点 ---
  const kpMap = await seedKnowledgePoints(chapterMap);

  // --- 10. 课表 ---
  await seedClassSchedule(classMap);

  // --- 11. 题库 ---
  const questionBanks = await seedQuestions(teacherMap, subjectMap, kpMap);

  // --- 12. 试卷（语文、数学各 1 套）+ 学生答题与批改 ---
  await seedExamsAndSubmissions(teacherMap, classMap, studentMap, questionBanks, subjectMap, gradeMap);

  // --- 13. 作业（引用试卷）+ 学生答题与批改 ---
  await seedHomework(teacherMap, classMap, studentMap, questionBanks);

  // --- 14. 成绩记录 ---
  await seedGradeRecords(teacherMap, classMap, studentMap, subjectMap, academicYearId);

  // --- 15. 考勤记录 ---
  await seedAttendanceRecords(teacherMap, classMap, studentMap);

  // --- 16. 课程计划 ---
  await seedCoursePlans(teacherMap, classMap, subjectMap, academicYearId, chapterMap);

  // --- 17. 公告 ---
  await seedAnnouncements(adminId, gradeMap, classMap);

  const end = performance.now();
  console.log(`\n✅ 初始化完成，耗时 ${(end - start).toFixed(0)}ms`);
  console.log("\n📋 登录账号（密码统一为 123456）：");
  console.log(`  管理员: admin@xiaoxue.edu.cn`);
  console.log(`  语文老师/一年级1班班主任: t_chinese_1@xiaoxue.edu.cn`);
  console.log(`  数学老师/一年级1班任课: t_math_1@xiaoxue.edu.cn`);
  console.log(`  英语老师/一年级2班任课: t_english_1@xiaoxue.edu.cn`);
  console.log(`  学生（一年级1班）: student_g1c1_1@xiaoxue.edu.cn`);
  console.log(`  家长: parent_g1c1_1@xiaoxue.edu.cn`);
  process.exit(0);
}

// ============ 0. 清理 ============

async function cleanup() {
  console.log("🧹 清理现有数据...");
  await db.execute(sql`SET FOREIGN_KEY_CHECKS = 0;`);
  const tables = [
    "attendance_records",
    "course_plan_items", "course_plans",
    "grade_records",
    "announcements",
    "homework_answers", "homework_submissions", "homework_assignment_targets", "homework_assignment_questions", "homework_assignments",
    "submission_answers", "exam_submissions", "exam_questions", "exams",
    "questions_to_knowledge_points", "questions", "knowledge_points",
    "chapters", "textbooks",
    "class_schedule", "class_subject_teachers", "class_enrollments", "classes",
    "parent_student_relations",
    "grades", "academic_years", "schools", "subjects",
    "role_permissions", "users_to_roles", "roles", "users", "accounts", "sessions",
    "notification_preferences", "password_security", "message_notifications", "messages",
    "data_change_logs", "login_logs", "audit_logs",
    "scheduling_rules", "schedule_changes", "attendance_rules",
    "file_attachments", "ai_providers",
  ];
  for (const t of tables) {
    try {
      await db.execute(sql.raw(`TRUNCATE TABLE \`${t}\`;`));
    } catch {
      // 表可能不存在，跳过
    }
  }
  await db.execute(sql`SET FOREIGN_KEY_CHECKS = 1;`);
  console.log("✓ 清理完成");
}

// ============ 1. 角色 + 权限 ============

async function seedRolesAndPermissions() {
  console.log("👤 创建角色与权限...");

  const roleDefs = [
    { id: "role_admin", name: "admin", description: "系统管理员" },
    { id: "role_teacher", name: "teacher", description: "教师" },
    { id: "role_student", name: "student", description: "学生" },
    { id: "role_parent", name: "parent", description: "家长" },
    { id: "role_grade_head", name: "grade_head", description: "年级组长" },
    { id: "role_teaching_head", name: "teaching_head", description: "教研组长" },
  ];

  await db.insert(roles).values(roleDefs);

  // 写入角色-权限映射
  const permsData: { roleId: string; permission: string }[] = [];
  for (const role of roleDefs) {
    const perms = ROLE_PERMISSIONS[role.name] ?? [];
    for (const p of perms) {
      permsData.push({ roleId: role.id, permission: p });
    }
  }
  await db.insert(rolePermissions).values(permsData);
  console.log(`✓ 创建 ${roleDefs.length} 个角色，${permsData.length} 条权限映射`);
}

// ============ 2. 学科 ============

async function seedSubjects() {
  console.log("📚 创建学科...");
  const map: Record<string, string> = {};
  const subs = [
    { name: "语文", code: "CHINESE", order: 1 },
    { name: "数学", code: "MATH", order: 2 },
    { name: "英语", code: "ENG", order: 3 },
  ];
  for (const s of subs) {
    const id = createId();
    map[s.code] = id;
    await db.insert(subjects).values({ id, name: s.name, code: s.code, order: s.order });
  }
  console.log(`✓ 创建 ${subs.length} 个学科`);
  return map; // { CHINESE, MATH, ENG }
}

// ============ 3. 学校 + 年级 + 学年 ============

async function seedSchoolAndGrades() {
  console.log("🏫 创建学校、年级、学年...");
  const schoolId = "school_xiaoxue";
  await db.insert(schools).values({
    id: schoolId,
    name: "阳光小学",
    code: "SUNXX",
  });

  const academicYearId = createId();
  await db.insert(academicYears).values({
    id: academicYearId,
    name: "2025-2026学年",
    startDate: new Date("2025-09-01"),
    endDate: new Date("2026-07-15"),
    isActive: true,
  });

  const gradeMap: Record<string, string> = {};
  const gradeDefs = [
    { key: "G1", name: "Grade 1", order: 1 },
    { key: "G2", name: "Grade 2", order: 2 },
  ];
  for (const g of gradeDefs) {
    const id = createId();
    gradeMap[g.key] = id;
    await db.insert(grades).values({
      id,
      schoolId,
      name: g.name,
      order: g.order,
    });
  }
  console.log(`✓ 创建 1 所学校、${gradeDefs.length} 个年级、1 个学年`);
  return { schoolId, gradeMap, academicYearId };
}

// ============ 4. 用户 ============

async function seedUsers(
  schoolId: string,
  gradeMap: Record<string, string>
) {
  console.log("👥 创建用户...");
  const passwordHash = await hash(PASSWORD, 10);
  const avatar = (seed: string) => `https://api.dicebear.com/7.x/avataaars/svg?seed=${seed}`;

  // --- Admin ---
  const adminId = "user_admin";
  await db.insert(users).values({
    id: adminId,
    name: "系统管理员",
    email: "admin@xiaoxue.edu.cn",
    password: passwordHash,
    image: avatar("admin"),
    gender: "男",
    onboardedAt: NOW,
  });
  await db.insert(usersToRoles).values({ userId: adminId, roleId: "role_admin" });

  // --- 老师 ---
  // 8 个老师：每班 2 个（班主任+任课），跨班凑齐语数外
  // 一年级1班：班主任 T_C1（语文），任课 T_M1（数学），英语由 T_E1 跨班
  // 一年级2班：班主任 T_C2（语文），任课 T_E1（英语），数学由 T_M1 跨班
  // 二年级1班：班主任 T_C3（语文），任课 T_M2（数学），英语由 T_E2 跨班
  // 二年级2班：班主任 T_C4（语文），任课 T_E2（英语），数学由 T_M2 跨班
  const teacherMap: Record<string, { id: string; name: string; subject: string }> = {};
  const teacherDefs = [
    { key: "T_C1", name: "王语文", subject: "CHINESE", email: "t_chinese_1@xiaoxue.edu.cn", gender: "女" as const },
    { key: "T_M1", name: "李数学", subject: "MATH", email: "t_math_1@xiaoxue.edu.cn", gender: "男" as const },
    { key: "T_C2", name: "赵语文", subject: "CHINESE", email: "t_chinese_2@xiaoxue.edu.cn", gender: "女" as const },
    { key: "T_E1", name: "张英语", subject: "ENG", email: "t_english_1@xiaoxue.edu.cn", gender: "女" as const },
    { key: "T_C3", name: "陈语文", subject: "CHINESE", email: "t_chinese_3@xiaoxue.edu.cn", gender: "男" as const },
    { key: "T_M2", name: "刘数学", subject: "MATH", email: "t_math_2@xiaoxue.edu.cn", gender: "男" as const },
    { key: "T_C4", name: "孙语文", subject: "CHINESE", email: "t_chinese_4@xiaoxue.edu.cn", gender: "女" as const },
    { key: "T_E2", name: "周英语", subject: "ENG", email: "t_english_2@xiaoxue.edu.cn", gender: "女" as const },
  ];

  for (const t of teacherDefs) {
    const id = `user_${t.key}`;
    teacherMap[t.key] = { id, name: t.name, subject: t.subject };
    await db.insert(users).values({
      id,
      name: t.name,
      email: t.email,
      password: passwordHash,
      image: avatar(t.key),
      gender: t.gender,
      onboardedAt: NOW,
    });
    await db.insert(usersToRoles).values({ userId: id, roleId: "role_teacher" });
  }

  // 指定一年级组长 = T_C1，二年级组长 = T_C3
  await db.update(grades).set({ gradeHeadId: teacherMap.T_C1.id }).where(eq(grades.id, gradeMap.G1));
  await db.update(grades).set({ gradeHeadId: teacherMap.T_C3.id }).where(eq(grades.id, gradeMap.G2));
  // 同时给年级组长角色
  await db.insert(usersToRoles).values({ userId: teacherMap.T_C1.id, roleId: "role_grade_head" });
  await db.insert(usersToRoles).values({ userId: teacherMap.T_C3.id, roleId: "role_grade_head" });

  // --- 学生 ---
  // 每班 6 名学生，共 24 名
  const studentMap: Record<string, { id: string; name: string; classKey: string }> = {};
  const classKeys = ["G1C1", "G1C2", "G2C1", "G2C2"];
  const surnames = ["小明", "小红", "小华", "小亮", "小芳", "小强", "小丽", "小军", "小燕", "小杰", "小琳", "小涛"];
  let studentIdx = 0;
  for (const ck of classKeys) {
    for (let i = 0; i < 6; i++) {
      const key = `S_${ck}_${i + 1}`;
      const id = `user_${key.toLowerCase()}`;
      const name = surnames[studentIdx % surnames.length] + (studentIdx >= surnames.length ? "2" : "");
      studentIdx++;
      studentMap[key] = { id, name, classKey: ck };
      await db.insert(users).values({
        id,
        name,
        email: `student_${ck.toLowerCase()}_${i + 1}@xiaoxue.edu.cn`,
        password: passwordHash,
        image: avatar(key),
        gender: i % 2 === 0 ? "男" : "女",
        birthDate: new Date(`201${ck.startsWith("G1") ? 8 : 7}-0${(i % 9) + 1}-15`),
        phone: "1380000" + String(studentIdx).padStart(4, "0"),
        guardianName: "家长" + name,
        guardianPhone: "1380000" + String(studentIdx).padStart(4, "0"),
        guardianRelation: i % 2 === 0 ? "父亲" : "母亲",
        onboardedAt: NOW,
      });
      await db.insert(usersToRoles).values({ userId: id, roleId: "role_student" });
    }
  }

  // --- 家长 ---
  // 每名学生 1 位家长
  const parentMap: Record<string, { id: string; name: string; childKey: string }> = {};
  for (const [sKey, sInfo] of Object.entries(studentMap)) {
    const pKey = `P_${sKey}`;
    const id = `user_${pKey.toLowerCase()}`;
    const name = "家长" + sInfo.name;
    parentMap[pKey] = { id, name, childKey: sKey };
    await db.insert(users).values({
      id,
      name,
      email: `parent_${sInfo.classKey.toLowerCase()}_${sKey.split("_")[2]}@xiaoxue.edu.cn`,
      password: passwordHash,
      image: avatar(pKey),
      gender: sInfo.name.includes("明") || sInfo.name.includes("华") || sInfo.name.includes("亮") || sInfo.name.includes("强") || sInfo.name.includes("军") || sInfo.name.includes("涛") ? "男" : "女",
      onboardedAt: NOW,
    });
    await db.insert(usersToRoles).values({ userId: id, roleId: "role_parent" });
  }

  console.log(`✓ 创建 1 管理员、${teacherDefs.length} 老师、${Object.keys(studentMap).length} 学生、${Object.keys(parentMap).length} 家长`);
  return { adminId, teacherMap, studentMap, parentMap };
}

// ============ 5. 班级 ============

async function seedClasses(
  schoolId: string,
  gradeMap: Record<string, string>,
  teacherMap: Record<string, { id: string; name: string; subject: string }>
) {
  console.log("🏫 创建班级...");
  const classMap: Record<string, { id: string; gradeKey: string; homeroomTeacherKey: string }> = {};

  const classDefs = [
    { key: "G1C1", name: "一年级1班", gradeKey: "G1", homeroom: "T_C1", room: "1号楼101", code: "G1C101" },
    { key: "G1C2", name: "一年级2班", gradeKey: "G1", homeroom: "T_C2", room: "1号楼102", code: "G1C102" },
    { key: "G2C1", name: "二年级1班", gradeKey: "G2", homeroom: "T_C3", room: "2号楼101", code: "G2C101" },
    { key: "G2C2", name: "二年级2班", gradeKey: "G2", homeroom: "T_C4", room: "2号楼102", code: "G2C102" },
  ];

  for (const c of classDefs) {
    const id = `class_${c.key}`;
    classMap[c.key] = { id, gradeKey: c.gradeKey, homeroomTeacherKey: c.homeroom };
    await db.insert(classes).values({
      id,
      schoolName: "阳光小学",
      schoolId,
      name: c.name,
      grade: c.gradeKey === "G1" ? "Grade 1" : "Grade 2",
      gradeId: gradeMap[c.gradeKey],
      homeroom: c.code,
      room: c.room,
      invitationCode: c.code,
      teacherId: teacherMap[c.homeroom].id,
    });
  }
  console.log(`✓ 创建 ${classDefs.length} 个班级`);
  return classMap;
}

// ============ 6. 班级-学科-老师关联 ============

async function seedClassSubjectTeachers(
  classMap: Record<string, { id: string; gradeKey: string; homeroomTeacherKey: string }>,
  teacherMap: Record<string, { id: string; name: string; subject: string }>,
  subjectMap: Record<string, string>
) {
  console.log("🔗 建立班级-学科-老师关联...");
  // 每班 3 科（语数外），由跨班老师凑齐
  // G1C1: 语文 T_C1, 数学 T_M1, 英语 T_E1
  // G1C2: 语文 T_C2, 数学 T_M1, 英语 T_E1
  // G2C1: 语文 T_C3, 数学 T_M2, 英语 T_E2
  // G2C2: 语文 T_C4, 数学 T_M2, 英语 T_E2
  const mapping: Record<string, { CHINESE: string; MATH: string; ENG: string }> = {
    G1C1: { CHINESE: "T_C1", MATH: "T_M1", ENG: "T_E1" },
    G1C2: { CHINESE: "T_C2", MATH: "T_M1", ENG: "T_E1" },
    G2C1: { CHINESE: "T_C3", MATH: "T_M2", ENG: "T_E2" },
    G2C2: { CHINESE: "T_C4", MATH: "T_M2", ENG: "T_E2" },
  };

  const rows: { classId: string; subjectId: string; teacherId: string }[] = [];
  for (const [ck, teachers] of Object.entries(mapping)) {
    for (const [subCode, tKey] of Object.entries(teachers)) {
      rows.push({
        classId: classMap[ck].id,
        subjectId: subjectMap[subCode],
        teacherId: teacherMap[tKey].id,
      });
    }
  }
  await db.insert(classSubjectTeachers).values(rows);
  console.log(`✓ 创建 ${rows.length} 条班级-学科-老师关联`);
}

// ============ 7. 学生分班 + 家长-学生关联 ============

async function seedEnrollmentsAndParents(
  classMap: Record<string, { id: string }>,
  studentMap: Record<string, { id: string; classKey: string }>,
  parentMap: Record<string, { id: string; childKey: string }>
) {
  console.log("👨‍🎓 学生分班 + 家长关联...");
  const enrollments: { classId: string; studentId: string; status: "active" }[] = [];
  for (const s of Object.values(studentMap)) {
    enrollments.push({
      classId: classMap[s.classKey].id,
      studentId: s.id,
      status: "active",
    });
  }
  await db.insert(classEnrollments).values(enrollments);

  const parentRelations: { parentId: string; studentId: string; relation: string }[] = [];
  for (const p of Object.values(parentMap)) {
    const child = studentMap[p.childKey];
    parentRelations.push({
      parentId: p.id,
      studentId: child.id,
      relation: child.name.includes("明") || child.name.includes("华") || child.name.includes("亮") || child.name.includes("强") || child.name.includes("军") || child.name.includes("涛") ? "父亲" : "母亲",
    });
  }
  await db.insert(parentStudentRelations).values(parentRelations);
  console.log(`✓ ${enrollments.length} 条分班记录、${parentRelations.length} 条家长关联`);
}

// ============ 8. 教材 + 章节 ============

async function seedTextbooksAndChapters() {
  console.log("📖 创建教材与章节...");
  // 每科 1 本教材（一年级语文、一年级数学、一年级英语）
  // 只实现第一章第一节课
  const chapterMap: Record<string, string> = {};

  const textbookDefs = [
    {
      subjectCode: "CHINESE",
      subjectName: "Chinese",
      title: "一年级语文（上册）",
      publisher: "人民教育出版社",
      chapterTitle: "第一课 秋天",
      chapterContent: "# 第一课 秋天\n\n秋天来了，天气凉了，树叶黄了，一片片叶子从树上落下来。\n\n天空那么蓝，那么高。一群大雁往南飞，一会儿排成个\"人\"字，一会儿排成个\"一\"字。\n\n啊！秋天来了！",
    },
    {
      subjectCode: "MATH",
      subjectName: "Mathematics",
      title: "一年级数学（上册）",
      publisher: "人民教育出版社",
      chapterTitle: "第一课 1-5 的认识",
      chapterContent: "# 第一课 1-5 的认识\n\n## 数一数\n\n1 像铅笔细又长\n2 像小鸭水上漂\n3 像耳朵听声音\n4 像小旗迎风飘\n5 像秤钩来买菜\n\n## 练习\n\n数一数图中有几只小鸟？有几朵花？",
    },
    {
      subjectCode: "ENG",
      subjectName: "English",
      title: "一年级英语（上册）",
      publisher: "外语教学与研究出版社",
      chapterTitle: "Unit 1 Hello",
      chapterContent: "# Unit 1 Hello\n\n## Let's talk\n\n- Hello! I'm Mike.\n- Hi! I'm Sarah.\n- Goodbye!\n- Bye!\n\n## Words\n\n- hello 你好\n- goodbye 再见\n- I'm = I am 我是",
    },
  ];

  for (const tb of textbookDefs) {
    const tbId = `tb_${tb.subjectCode}_g1`;
    await db.insert(textbooks).values({
      id: tbId,
      title: tb.title,
      subject: tb.subjectName,
      grade: "Grade 1",
      publisher: tb.publisher,
    });

    // 第一章
    const ch1Id = `ch_${tb.subjectCode}_g1_1`;
    await db.insert(chapters).values({
      id: ch1Id,
      textbookId: tbId,
      title: `第一章 ${tb.subjectName === "Chinese" ? "课文" : tb.subjectName === "Mathematics" ? "数一数" : "Greetings"}`,
      order: 1,
      parentId: null,
      content: `# 第一章\n\n${tb.subjectName}第一章导引内容。`,
    });

    // 第一课
    const ch1_1Id = `ch_${tb.subjectCode}_g1_1_1`;
    chapterMap[tb.subjectCode] = ch1_1Id;
    await db.insert(chapters).values({
      id: ch1_1Id,
      textbookId: tbId,
      title: tb.chapterTitle,
      order: 1,
      parentId: ch1Id,
      content: tb.chapterContent,
    });
  }
  console.log(`✓ 创建 ${textbookDefs.length} 本教材，每本含第一章第一课`);
  return chapterMap; // { CHINESE, MATH, ENG }
}

// ============ 9. 知识点 ============

async function seedKnowledgePoints(chapterMap: Record<string, string>) {
  console.log("🧠 创建知识点...");
  const map: Record<string, string> = {};

  const kpDefs = [
    { key: "KP_CHINESE_READ", name: "朗读", chapterCode: "CHINESE", desc: "正确流利地朗读课文" },
    { key: "KP_CHINESE_CHAR", name: "生字认读", chapterCode: "CHINESE", desc: "认识课文中的生字" },
    { key: "KP_MATH_COUNT", name: "数数", chapterCode: "MATH", desc: "能数出 1-5 的数量" },
    { key: "KP_MATH_WRITE", name: "数字书写", chapterCode: "MATH", desc: "正确书写 1-5" },
    { key: "KP_ENG_GREET", name: "问候语", chapterCode: "ENG", desc: "掌握 hello/goodbye" },
    { key: "KP_ENG_INTRO", name: "自我介绍", chapterCode: "ENG", desc: "使用 I'm... 介绍自己" },
  ];

  for (const kp of kpDefs) {
    const id = `kp_${kp.key.toLowerCase()}`;
    map[kp.key] = id;
    await db.insert(knowledgePoints).values({
      id,
      name: kp.name,
      description: kp.desc,
      level: 1,
      order: 1,
      chapterId: chapterMap[kp.chapterCode],
    });
  }
  console.log(`✓ 创建 ${kpDefs.length} 个知识点`);
  return map;
}

// ============ 10. 课表 ============

async function seedClassSchedule(
  classMap: Record<string, { id: string }>
) {
  console.log("📅 创建课表...");
  // 每班每天安排语数外，简化为周一三五各 2 节
  const rows: { id: string; classId: string; weekday: number; startTime: string; endTime: string; course: string; location: string }[] = [];
  const subjectNames: Record<string, string> = { CHINESE: "语文", MATH: "数学", ENG: "英语" };
  const slots = [
    { weekday: 1, start: "08:00", end: "08:40", sub: "CHINESE" },
    { weekday: 1, start: "08:50", end: "09:30", sub: "MATH" },
    { weekday: 3, start: "08:00", end: "08:40", sub: "ENG" },
    { weekday: 3, start: "08:50", end: "09:30", sub: "CHINESE" },
    { weekday: 5, start: "08:00", end: "08:40", sub: "MATH" },
    { weekday: 5, start: "08:50", end: "09:30", sub: "ENG" },
  ];
  for (const [ck, cInfo] of Object.entries(classMap)) {
    for (let i = 0; i < slots.length; i++) {
      const s = slots[i];
      rows.push({
        id: `cs_${ck}_${i}`,
        classId: cInfo.id,
        weekday: s.weekday,
        startTime: s.start,
        endTime: s.end,
        course: subjectNames[s.sub],
        location: "教室",
      });
    }
  }
  await db.insert(classSchedule).values(rows);
  console.log(`✓ 创建 ${rows.length} 条课表记录`);
}

// ============ 11. 题库 ============

async function seedQuestions(
  teacherMap: Record<string, { id: string }>,
  subjectMap: Record<string, string>,
  kpMap: Record<string, string>
) {
  console.log("❓ 创建题库...");

  // 语文题（作者 T_C1）
  const chineseAuthorId = teacherMap.T_C1.id;
  const chineseQuestions = [
    {
      id: createId(),
      type: "single_choice" as const,
      difficulty: 1,
      content: {
        text: "\"秋天来了\"中，哪个字表示季节？",
        options: [
          { id: "A", text: "秋", isCorrect: true },
          { id: "B", text: "天", isCorrect: false },
          { id: "C", text: "来", isCorrect: false },
          { id: "D", text: "了", isCorrect: false },
        ],
      },
      score: 10,
    },
    {
      id: createId(),
      type: "single_choice" as const,
      difficulty: 2,
      content: {
        text: "课文中大雁往南飞是因为？",
        options: [
          { id: "A", text: "春天来了", isCorrect: false },
          { id: "B", text: "秋天来了", isCorrect: true },
          { id: "C", text: "夏天来了", isCorrect: false },
          { id: "D", text: "冬天来了", isCorrect: false },
        ],
      },
      score: 10,
    },
    {
      id: createId(),
      type: "text" as const,
      difficulty: 1,
      content: { text: "写出\"天\"的笔顺（用文字描述）。", correctAnswer: "横、横、撇、捺" },
      score: 10,
    },
    {
      id: createId(),
      type: "judgment" as const,
      difficulty: 1,
      content: { text: "\"一片片叶子从树上落下来\"说明秋天来了。", correctAnswer: true },
      score: 10,
    },
    {
      id: createId(),
      type: "text" as const,
      difficulty: 2,
      content: { text: "用\"一会儿...一会儿...\"造句。", correctAnswer: "一会儿...一会儿..." },
      score: 10,
    },
  ];

  // 数学题（作者 T_M1）
  const mathAuthorId = teacherMap.T_M1.id;
  const mathQuestions = [
    {
      id: createId(),
      type: "single_choice" as const,
      difficulty: 1,
      content: {
        text: "哪个数字表示\"3\"？",
        options: [
          { id: "A", text: "1", isCorrect: false },
          { id: "B", text: "2", isCorrect: false },
          { id: "C", text: "3", isCorrect: true },
          { id: "D", text: "4", isCorrect: false },
        ],
      },
      score: 10,
    },
    {
      id: createId(),
      type: "single_choice" as const,
      difficulty: 2,
      content: {
        text: "2 + 3 = ?",
        options: [
          { id: "A", text: "4", isCorrect: false },
          { id: "B", text: "5", isCorrect: true },
          { id: "C", text: "6", isCorrect: false },
          { id: "D", text: "3", isCorrect: false },
        ],
      },
      score: 10,
    },
    {
      id: createId(),
      type: "text" as const,
      difficulty: 1,
      content: { text: "数一数：🍎🍎🍎🍎 有几个苹果？（填数字）", correctAnswer: "4" },
      score: 10,
    },
    {
      id: createId(),
      type: "judgment" as const,
      difficulty: 1,
      content: { text: "数字 5 比 3 大。", correctAnswer: true },
      score: 10,
    },
    {
      id: createId(),
      type: "text" as const,
      difficulty: 2,
      content: { text: "小红有 2 支铅笔，妈妈又给她 2 支，现在有几支？（列式计算）", correctAnswer: "2+2=4" },
      score: 10,
    },
  ];

  // 英语题（作者 T_E1）
  const engAuthorId = teacherMap.T_E1.id;
  const engQuestions = [
    {
      id: createId(),
      type: "single_choice" as const,
      difficulty: 1,
      content: {
        text: "How do you say \"你好\" in English?",
        options: [
          { id: "A", text: "Goodbye", isCorrect: false },
          { id: "B", text: "Hello", isCorrect: true },
          { id: "C", text: "Bye", isCorrect: false },
          { id: "D", text: "Thanks", isCorrect: false },
        ],
      },
      score: 10,
    },
    {
      id: createId(),
      type: "single_choice" as const,
      difficulty: 2,
      content: {
        text: "\"I'm Mike.\" means:",
        options: [
          { id: "A", text: "我是 Mike", isCorrect: true },
          { id: "B", text: "再见 Mike", isCorrect: false },
          { id: "C", text: "你好 Mike", isCorrect: false },
          { id: "D", text: "谢谢 Mike", isCorrect: false },
        ],
      },
      score: 10,
    },
    {
      id: createId(),
      type: "text" as const,
      difficulty: 1,
      content: { text: "Fill in the blank: _____! I'm Sarah. (你好)", correctAnswer: "Hello" },
      score: 10,
    },
    {
      id: createId(),
      type: "judgment" as const,
      difficulty: 1,
      content: { text: "\"Goodbye\" means 再见.", correctAnswer: true },
      score: 10,
    },
    {
      id: createId(),
      type: "text" as const,
      difficulty: 2,
      content: { text: "Introduce yourself in English. (用英语介绍自己)", correctAnswer: "Hello! I'm ..." },
      score: 10,
    },
  ];

  const allQs = [
    ...chineseQuestions.map(q => ({ ...q, authorId: chineseAuthorId })),
    ...mathQuestions.map(q => ({ ...q, authorId: mathAuthorId })),
    ...engQuestions.map(q => ({ ...q, authorId: engAuthorId })),
  ];

  await db.insert(questions).values(
    allQs.map(q => ({
      id: q.id,
      type: q.type,
      difficulty: q.difficulty,
      content: q.content,
      authorId: q.authorId,
    }))
  );

  // 关联知识点
  const q2kp: { questionId: string; knowledgePointId: string }[] = [];
  chineseQuestions.forEach((q, i) => {
    q2kp.push({ questionId: q.id, knowledgePointId: i % 2 === 0 ? kpMap.KP_CHINESE_READ : kpMap.KP_CHINESE_CHAR });
  });
  mathQuestions.forEach((q, i) => {
    q2kp.push({ questionId: q.id, knowledgePointId: i % 2 === 0 ? kpMap.KP_MATH_COUNT : kpMap.KP_MATH_WRITE });
  });
  engQuestions.forEach((q, i) => {
    q2kp.push({ questionId: q.id, knowledgePointId: i % 2 === 0 ? kpMap.KP_ENG_GREET : kpMap.KP_ENG_INTRO });
  });
  await db.insert(questionsToKnowledgePoints).values(q2kp);

  console.log(`✓ 创建 ${allQs.length} 道题目（语${chineseQuestions.length}/数${mathQuestions.length}/英${engQuestions.length}）`);
  return { chineseQuestions, mathQuestions, engQuestions };
}

// ============ 12. 试卷 + 学生答题与批改 ============

async function seedExamsAndSubmissions(
  teacherMap: Record<string, { id: string }>,
  classMap: Record<string, { id: string }>,
  studentMap: Record<string, { id: string; classKey: string }>,
  questionBanks: SeedQuestionBank,
  subjectMap: Record<string, string>,
  gradeMap: Record<string, string>
) {
  console.log("📝 创建试卷与学生答题...");

  const makeGroup = (title: string, children: SeedQuestion[]) => ({
    id: createId(),
    type: "group" as const,
    title,
    children,
  });
  const makeQNode = (questionId: string, score: number) => ({
    id: createId(),
    type: "question" as const,
    questionId,
    score,
  });

  // --- 试卷1：一年级语文第一单元测验 ---
  const chineseExamId = "exam_chinese_g1_unit1";
  const cnQs = questionBanks.chineseQuestions;
  const cnStructure = [
    makeGroup("一、选择题（每题10分）", [makeQNode(cnQs[0].id, 10), makeQNode(cnQs[1].id, 10)]),
    makeGroup("二、填空题（每题10分）", [makeQNode(cnQs[2].id, 10), makeQNode(cnQs[4].id, 10)]),
    makeGroup("三、判断题（每题10分）", [makeQNode(cnQs[3].id, 10)]),
  ];
  const cnOrderedIds = [cnQs[0].id, cnQs[1].id, cnQs[2].id, cnQs[4].id, cnQs[3].id];
  const cnScoreMap = new Map(cnQs.map(q => [q.id, q.score] as const));

  await db.insert(exams).values({
    id: chineseExamId,
    title: "一年级语文第一单元测验",
    description: JSON.stringify({ subject: "Chinese", grade: "Grade 1", totalScore: 50, durationMin: 40, questionCount: 5 }),
    creatorId: teacherMap.T_C1.id,
    subjectId: subjectMap.CHINESE,
    gradeId: gradeMap.G1,
    status: "published",
    startTime: NOW,
    structure: cnStructure,
  });
  await db.insert(examQuestions).values(
    cnOrderedIds.map((qid, i) => ({
      examId: chineseExamId,
      questionId: qid,
      score: cnScoreMap.get(qid) ?? 10,
      order: i,
    }))
  );

  // --- 试卷2：一年级数学第一单元测验 ---
  const mathExamId = "exam_math_g1_unit1";
  const mQs = questionBanks.mathQuestions;
  const mStructure = [
    makeGroup("一、选择题（每题10分）", [makeQNode(mQs[0].id, 10), makeQNode(mQs[1].id, 10)]),
    makeGroup("二、填空题（每题10分）", [makeQNode(mQs[2].id, 10), makeQNode(mQs[4].id, 10)]),
    makeGroup("三、判断题（每题10分）", [makeQNode(mQs[3].id, 10)]),
  ];
  const mOrderedIds = [mQs[0].id, mQs[1].id, mQs[2].id, mQs[4].id, mQs[3].id];
  const mScoreMap = new Map(mQs.map(q => [q.id, q.score] as const));

  await db.insert(exams).values({
    id: mathExamId,
    title: "一年级数学第一单元测验",
    description: JSON.stringify({ subject: "Mathematics", grade: "Grade 1", totalScore: 50, durationMin: 40, questionCount: 5 }),
    creatorId: teacherMap.T_M1.id,
    subjectId: subjectMap.MATH,
    gradeId: gradeMap.G1,
    status: "published",
    startTime: NOW,
    structure: mStructure,
  });
  await db.insert(examQuestions).values(
    mOrderedIds.map((qid, i) => ({
      examId: mathExamId,
      questionId: qid,
      score: mScoreMap.get(qid) ?? 10,
      order: i,
    }))
  );

  // --- 学生答题与批改 ---
  // 一年级两个班的学生都参加这两套试卷
  const g1Students = Object.values(studentMap).filter(s => s.classKey.startsWith("G1"));
  let submissionCount = 0;
  let answerCount = 0;

  for (const exam of [
    { id: chineseExamId, qIds: cnOrderedIds, qs: cnQs },
    { id: mathExamId, qIds: mOrderedIds, qs: mQs },
  ]) {
    for (let si = 0; si < g1Students.length; si++) {
      const student = g1Students[si];
      const submissionId = createId();
      const submittedAt = new Date(NOW.getTime() - (si + 1) * 3600_000);
      // 前 6 个学生已批改，后 6 个已提交未批改
      const isGraded = si < 6;
      const status = isGraded ? "graded" : "submitted";

      // 模拟答题：前 3 题答对，后 2 题部分对
      const perScores = exam.qIds.map((_, idx) => {
        if (!isGraded) return null;
        if (idx < 3) return 10;
        if (idx === 3) return 6;
        return 8;
      });
      const totalScore = isGraded ? perScores.reduce<number>((s, v) => s + Number(v ?? 0), 0) : null;

      await db.insert(examSubmissions).values({
        id: submissionId,
        examId: exam.id,
        studentId: student.id,
        score: totalScore,
        status,
        submittedAt,
      });
      submissionCount++;

      // 答案
      const buildAnswer = (q: SeedQuestion, idx: number) => {
        if (q.type === "single_choice") {
          // 前 3 题选正确项，后 2 题选错误项
          const correct = q.content.options?.find((o) => o.isCorrect);
          const wrong = q.content.options?.find((o) => !o.isCorrect);
          return { answer: idx < 3 ? correct?.id : wrong?.id };
        }
        if (q.type === "judgment") return { answer: idx < 3 };
        return { answer: idx < 3 ? "标准答案" : "学生答案" };
      };

      await db.insert(submissionAnswers).values(
        exam.qIds.map((qid, idx) => {
          const q = exam.qs.find((x) => x.id === qid)!;
          const score = isGraded ? (perScores[idx] ?? 0) : null;
          return {
            id: createId(),
            submissionId,
            questionId: qid,
            answerContent: buildAnswer(q, idx),
            score,
            feedback: isGraded ? (score === 10 ? "回答正确！" : "还需努力") : null,
          };
        })
      );
      answerCount += exam.qIds.length;
    }
  }
  console.log(`✓ 创建 2 套试卷，${submissionCount} 份提交，${answerCount} 条答案`);
}

// ============ 13. 作业 ============

async function seedHomework(
  teacherMap: Record<string, { id: string }>,
  classMap: Record<string, { id: string }>,
  studentMap: Record<string, { id: string; classKey: string }>,
  questionBanks: SeedQuestionBank
) {
  console.log("📚 创建作业...");
  // 1 个语文作业（引用语文题）+ 1 个数学作业（引用数学题）
  const now = new Date();
  const dueAt = new Date(now.getTime() + 7 * 86400_000);
  const lateDueAt = new Date(now.getTime() + 9 * 86400_000);

  const assignments: { id: string; title: string; creatorId: string; qIds: string[]; qs: SeedQuestion[]; targetClassKey: string }[] = [
    {
      id: "hw_chinese_g1",
      title: "一年级语文第一课作业",
      creatorId: teacherMap.T_C1.id,
      qIds: questionBanks.chineseQuestions.map(q => q.id),
      qs: questionBanks.chineseQuestions,
      targetClassKey: "G1C1",
    },
    {
      id: "hw_math_g1",
      title: "一年级数学第一课作业",
      creatorId: teacherMap.T_M1.id,
      qIds: questionBanks.mathQuestions.map(q => q.id),
      qs: questionBanks.mathQuestions,
      targetClassKey: "G1C1",
    },
  ];

  let hwSubmissionCount = 0;
  let hwAnswerCount = 0;

  for (const hw of assignments) {
    // 引用一份"虚拟试卷"作为 sourceExamId —— 但 homeworkAssignments 要求 sourceExamId notNull
    // 我们复用已创建的试卷 ID
    const sourceExamId = hw.id.includes("chinese") ? "exam_chinese_g1_unit1" : "exam_math_g1_unit1";

    const structure = [
      {
        id: createId(),
        type: "group" as const,
        title: "作业题",
        children: hw.qIds.map(qid => ({ id: createId(), type: "question" as const, questionId: qid, score: 10 })),
      },
    ];

    await db.insert(homeworkAssignments).values({
      id: hw.id,
      sourceExamId,
      title: hw.title,
      description: "自动生成的课后作业",
      structure,
      status: "published",
      creatorId: hw.creatorId,
      availableAt: now,
      dueAt,
      allowLate: true,
      lateDueAt,
      maxAttempts: 2,
    });

    await db.insert(homeworkAssignmentQuestions).values(
      hw.qIds.map((qid, i) => ({
        assignmentId: hw.id,
        questionId: qid,
        score: 10,
        order: i,
      }))
    );

    // 目标学生：一年级1班
    const targets = Object.values(studentMap).filter(s => s.classKey === hw.targetClassKey);
    await db.insert(homeworkAssignmentTargets).values(
      targets.map(t => ({ assignmentId: hw.id, studentId: t.id }))
    );

    // 前 3 个学生提交作业并批改
    for (let i = 0; i < Math.min(3, targets.length); i++) {
      const student = targets[i];
      const submissionId = createId();
      const submittedAt = new Date(now.getTime() - (i + 1) * 86400_000);
      const isGraded = i < 2;
      const status = isGraded ? "graded" : "submitted";

      const perScores = hw.qIds.map((_, idx) => {
        if (!isGraded) return null;
        if (idx < 3) return 10;
        return 6;
      });
      const totalScore = isGraded ? perScores.reduce<number>((s, v) => s + Number(v ?? 0), 0) : null;

      await db.insert(homeworkSubmissions).values({
        id: submissionId,
        assignmentId: hw.id,
        studentId: student.id,
        attemptNo: 1,
        score: totalScore,
        status,
        startedAt: new Date(submittedAt.getTime() - 3600_000),
        submittedAt,
        isLate: false,
      });
      hwSubmissionCount++;

      const buildAnswer = (q: SeedQuestion, idx: number) => {
        if (q.type === "single_choice") {
          const correct = q.content.options?.find((o) => o.isCorrect);
          const wrong = q.content.options?.find((o) => !o.isCorrect);
          return { answer: idx < 3 ? correct?.id : wrong?.id };
        }
        if (q.type === "judgment") return { answer: idx < 3 };
        return { answer: idx < 3 ? "标准答案" : "学生答案" };
      };

      await db.insert(homeworkAnswers).values(
        hw.qIds.map((qid, idx) => {
          const q = hw.qs.find((x) => x.id === qid)!;
          const score = isGraded ? (perScores[idx] ?? 0) : null;
          return {
            id: createId(),
            submissionId,
            questionId: qid,
            answerContent: buildAnswer(q, idx),
            score,
            feedback: isGraded ? (score === 10 ? "很好" : "继续努力") : null,
            createdAt: submittedAt,
            updatedAt: submittedAt,
          };
        })
      );
      hwAnswerCount += hw.qIds.length;
    }
  }
  console.log(`✓ 创建 ${assignments.length} 个作业，${hwSubmissionCount} 份提交，${hwAnswerCount} 条答案`);
}

// ============ 14. 成绩记录 ============

async function seedGradeRecords(
  teacherMap: Record<string, { id: string }>,
  classMap: Record<string, { id: string }>,
  studentMap: Record<string, { id: string; classKey: string }>,
  subjectMap: Record<string, string>,
  academicYearId: string
) {
  console.log("📊 创建成绩记录...");
  // 为一年级1班学生录入语数外成绩
  const g1c1Students = Object.values(studentMap).filter(s => s.classKey === "G1C1");
  const subjectTeacher: Record<string, string> = {
    CHINESE: teacherMap.T_C1.id,
    MATH: teacherMap.T_M1.id,
    ENG: teacherMap.T_E1.id,
  };

  const records: SeedGradeRecord[] = [];
  for (const s of g1c1Students) {
    for (const [subCode, sid] of Object.entries(subjectMap)) {
      records.push({
        id: createId(),
        studentId: s.id,
        classId: classMap.G1C1.id,
        subjectId: sid,
        examId: null,
        academicYearId,
        title: `${subCode === "CHINESE" ? "语文" : subCode === "MATH" ? "数学" : "英语"}第一单元测验`,
        score: String(80 + Math.floor(Math.random() * 20)),
        fullScore: "100",
        type: "exam" as const,
        semester: "1" as const,
        recordedBy: subjectTeacher[subCode],
      });
    }
  }
  await db.insert(gradeRecords).values(records);
  console.log(`✓ 创建 ${records.length} 条成绩记录`);
}

// ============ 15. 考勤记录 ============

async function seedAttendanceRecords(
  teacherMap: Record<string, { id: string }>,
  classMap: Record<string, { id: string }>,
  studentMap: Record<string, { id: string; classKey: string }>
) {
  console.log("📋 创建考勤记录...");
  // 为一年级1班最近 5 天的考勤
  const g1c1Students = Object.values(studentMap).filter(s => s.classKey === "G1C1");
  const recorder = teacherMap.T_C1.id;
  const records: SeedAttendanceRecord[] = [];
  const statuses = ["present", "present", "present", "present", "late", "absent"] as const;

  for (let d = 0; d < 5; d++) {
    const date = new Date(NOW.getTime() - d * 86400_000);
    for (let i = 0; i < g1c1Students.length; i++) {
      const s = g1c1Students[i];
      records.push({
        id: createId(),
        studentId: s.id,
        classId: classMap.G1C1.id,
        date,
        status: statuses[i % statuses.length],
        remark: statuses[i % statuses.length] === "late" ? "迟到10分钟" : null,
        recordedBy: recorder,
      });
    }
  }
  await db.insert(attendanceRecords).values(records);
  console.log(`✓ 创建 ${records.length} 条考勤记录`);
}

// ============ 16. 课程计划 ============

async function seedCoursePlans(
  teacherMap: Record<string, { id: string }>,
  classMap: Record<string, { id: string }>,
  subjectMap: Record<string, string>,
  academicYearId: string,
  chapterMap: Record<string, string>
) {
  console.log("📝 创建课程计划...");
  // 一年级1班的语数外课程计划
  const plans: { id: string; classKey: string; subjectCode: string; teacherKey: string }[] = [
    { id: "cp_g1c1_chinese", classKey: "G1C1", subjectCode: "CHINESE", teacherKey: "T_C1" },
    { id: "cp_g1c1_math", classKey: "G1C1", subjectCode: "MATH", teacherKey: "T_M1" },
    { id: "cp_g1c1_eng", classKey: "G1C1", subjectCode: "ENG", teacherKey: "T_E1" },
  ];

  let itemCount = 0;
  for (const p of plans) {
    await db.insert(coursePlans).values({
      id: p.id,
      classId: classMap[p.classKey].id,
      subjectId: subjectMap[p.subjectCode],
      teacherId: teacherMap[p.teacherKey].id,
      academicYearId,
      semester: "1",
      totalHours: 36,
      completedHours: 4,
      weeklyHours: 3,
      startDate: new Date("2025-09-01"),
      endDate: new Date("2026-01-15"),
      syllabus: "一年级上学期教学大纲",
      objectives: "掌握基础知识，培养学习兴趣",
      status: "active",
      createdBy: teacherMap[p.teacherKey].id,
    });

    // 第一周课程项
    await db.insert(coursePlanItems).values([
      {
        id: createId(),
        planId: p.id,
        week: 1,
        topic: "第一课",
        content: "导入新课，讲解基础知识",
        hours: 2,
        textbookChapter: chapterMap[p.subjectCode],
        notes: "注意课堂互动",
        isCompleted: true,
        completedAt: new Date("2025-09-02"),
      },
      {
        id: createId(),
        planId: p.id,
        week: 2,
        topic: "第一课练习",
        content: "巩固练习，答疑解惑",
        hours: 1,
        textbookChapter: chapterMap[p.subjectCode],
        notes: "",
        isCompleted: true,
        completedAt: new Date("2025-09-09"),
      },
      {
        id: createId(),
        planId: p.id,
        week: 3,
        topic: "第二课",
        content: "新授课",
        hours: 2,
        textbookChapter: null,
        notes: "",
        isCompleted: false,
      },
    ]);
    itemCount += 3;
  }
  console.log(`✓ 创建 ${plans.length} 个课程计划，${itemCount} 条课程项`);
}

// ============ 17. 公告 ============

async function seedAnnouncements(
  adminId: string,
  gradeMap: Record<string, string>,
  classMap: Record<string, { id: string }>
) {
  console.log("📢 创建公告...");
  await db.insert(announcements).values([
    {
      id: "ann_school_1",
      title: "2025-2026学年开学通知",
      content: "尊敬的各位老师、家长、同学：\n\n新学期开始了！请同学们按时到校，做好上课准备。\n\n阳光小学",
      type: "school",
      status: "published",
      authorId: adminId,
      publishedAt: NOW,
    },
    {
      id: "ann_grade_g1",
      title: "一年级家长会通知",
      content: "一年级家长会将于本周五下午 3 点在各班教室召开，请家长准时参加。",
      type: "grade",
      status: "published",
      targetGradeId: gradeMap.G1,
      authorId: adminId,
      publishedAt: NOW,
    },
    {
      id: "ann_class_g1c1",
      title: "一年级1班作业提醒",
      content: "请同学们按时完成语文、数学作业，周一上交。",
      type: "class",
      status: "published",
      targetClassId: classMap.G1C1.id,
      authorId: adminId,
      publishedAt: NOW,
    },
  ]);
  console.log("✓ 创建 3 条公告");
}

// ============ 启动 ============

seed().catch((err) => {
  console.error("❌ 初始化失败:", err);
  process.exit(1);
});
