/* Board-curriculum subject reset (Bangladesh Education Board):
 *  deletes every SUBJECT academic item and recreates the approved syllabus
 *  for Primary and High School education, tagged with its levels. Existing
 *  exam schedules, optional pools and student picks are remapped to the new
 *  items by name so no demo data breaks.
 *
 *  Runs standalone (`npx tsx prisma/reset-subjects.ts`).
 */
import { PrismaClient } from "@prisma/client";


const P = ["PRIMARY"];
const H = ["HIGH_SCHOOL"];
const BOTH = ["PRIMARY", "HIGH_SCHOOL"];

/** NCTB-approved subjects — প্রাথমিক ও মাধ্যমিক শিক্ষা সিলেবাস */
const BOARD_SUBJECTS: { name: string; nameBn: string; levels: string[] }[] = [
  // — shared across primary & high school —
  { name: "Mathematics", nameBn: "গণিত", levels: BOTH },
  { name: "Science", nameBn: "বিজ্ঞান", levels: BOTH },
  { name: "Bangladesh & Global Studies", nameBn: "বাংলাদেশ ও বিশ্বপরিচয়", levels: BOTH },
  { name: "Religion & Moral Education", nameBn: "ধর্ম ও নৈতিক শিক্ষা", levels: BOTH },
  { name: "ICT", nameBn: "তথ্য ও যোগাযোগ প্রযুক্তি", levels: BOTH },
  // — primary specific —
  { name: "Bangla", nameBn: "বাংলা", levels: P },
  { name: "English", nameBn: "ইংরেজি", levels: P },
  { name: "Physical Education", nameBn: "শারীরিক শিক্ষা", levels: P },
  // — high school (SSC) —
  { name: "Bangla 1st Paper", nameBn: "বাংলা ১ম পত্র", levels: H },
  { name: "Bangla 2nd Paper", nameBn: "বাংলা ২য় পত্র", levels: H },
  { name: "English 1st Paper", nameBn: "ইংরেজি ১ম পত্র", levels: H },
  { name: "English 2nd Paper", nameBn: "ইংরেজি ২য় পত্র", levels: H },
  { name: "Higher Mathematics", nameBn: "উচ্চতর গণিত", levels: H },
  { name: "Physics", nameBn: "পদার্থবিজ্ঞান", levels: H },
  { name: "Chemistry", nameBn: "রসায়ন", levels: H },
  { name: "Biology", nameBn: "জীববিজ্ঞান", levels: H },
  { name: "Agriculture Studies", nameBn: "কৃষিশিক্ষা", levels: H },
  { name: "Geography & Environment", nameBn: "ভূগোল ও পরিবেশ", levels: H },
  { name: "History & World Civilization", nameBn: "ইতিহাস ও বিশ্বসভ্যতা", levels: H },
  { name: "Economics", nameBn: "অর্থনীতি", levels: H },
  { name: "Civics & Good Governance", nameBn: "পৌরনীতি ও নাগরিকতা", levels: H },
  { name: "Business Entrepreneurship", nameBn: "ব্যবসায় উদ্যোগ", levels: H },
  { name: "Accounting", nameBn: "হিসাববিজ্ঞান", levels: H },
  { name: "Finance & Banking", nameBn: "ফিন্যান্স ও ব্যাংকিং", levels: H },
  { name: "Home Science", nameBn: "গার্হস্থ্য বিজ্ঞান", levels: H },
];

export async function resetBoardSubjects(prisma: PrismaClient) {
  // 1) create the board subjects as global catalog items (levels-tagged)
  const nameToNew = new Map<string, number>();
  for (const def of BOARD_SUBJECTS) {
    let item = await prisma.academicItem.findFirst({
      where: { category: "SUBJECT", name: def.name, institutionId: null },
      select: { id: true },
    });
    if (item) {
      await prisma.academicItem.update({
        where: { id: item.id },
        data: { nameBn: def.nameBn, levels: def.levels },
      });
    } else {
      item = await prisma.academicItem.create({
        data: {
          category: "SUBJECT",
          name: def.name,
          nameBn: def.nameBn,
          institutionId: null,
          levels: def.levels,
        },
        select: { id: true },
      });
    }
    nameToNew.set(def.name, item.id);
  }

  // 2) remap every reference to old subject items → new ids (by name)
  const oldSubjects = await prisma.academicItem.findMany({
    where: { category: "SUBJECT" },
    select: { id: true, name: true },
  });
  const remap = new Map<number, number>();
  for (const old of oldSubjects) {
    const newName = nameToNew.get(old.name);
    if (newName && newName !== old.id) remap.set(old.id, newName);
  }
  let remapped = 0;
  if (remap.size > 0) {
    for (const [oldId, newId] of remap) {
      const r1 = await prisma.examSchedule.updateMany({
        where: { subjectItemId: oldId },
        data: { subjectItemId: newId },
      });
      const r2 = await prisma.classOptionalSubject.updateMany({
        where: { subjectItemId: oldId },
        data: { subjectItemId: newId },
      });
      const r3 = await prisma.studentOptionalSubject.updateMany({
        where: { subjectItemId: oldId },
        data: { subjectItemId: newId },
      });
      remapped += r1.count + r2.count + r3.count;
    }
  }

  // 3) delete every old SUBJECT item that is not one of the new board rows
  const keep = new Set(nameToNew.values());
  const toDelete = oldSubjects.filter((o) => !keep.has(o.id)).map((o) => o.id);
  // clear selections pointing at doomed items happens via cascade
  const del = await prisma.academicItem.deleteMany({
    where: { id: { in: toDelete }, category: "SUBJECT" },
  });

  // 4) de-dupe selections that may now repeat (institution selected both old+new)
  const sels = await prisma.academicSelection.findMany({
    where: { academicItem: { category: "SUBJECT" } },
    select: { id: true, institutionId: true, academicItemId: true },
  });
  const seen = new Set<string>();
  let dupes = 0;
  for (const s of sels) {
    const key = `${s.institutionId}:${s.academicItemId}`;
    if (seen.has(key)) {
      await prisma.academicSelection.delete({ where: { id: s.id } });
      dupes++;
    } else seen.add(key);
  }

  console.log(
    `  ✔ board subjects: ${BOARD_SUBJECTS.length} created/updated · ${del.count} old items removed · ${remapped} references remapped · ${dupes} duplicate selections cleared`
  );
}

if (process.argv[1]?.includes("reset-subjects")) {
  const client = new PrismaClient();
  resetBoardSubjects(client)
    .catch((e) => {
      console.error(e);
      process.exitCode = 1;
    })
    .finally(() => client.$disconnect());
}
