import { config } from "dotenv"
import { db } from "@/shared/db"
import { sql } from "drizzle-orm"

async function main() {
  config()
  // 1) add subject_id column if not exists (nullable first)
  await db.execute(sql`ALTER TABLE class_subject_teachers ADD COLUMN IF NOT EXISTS subject_id VARCHAR(128) NULL;`)

  // 2) backfill subject_id from subjects.name matching existing 'subject' column
  //    This assumes existing data uses subjects.name 值；若不匹配，将在 NOT NULL 约束处失败
  await db.execute(sql`
    UPDATE class_subject_teachers cst
    JOIN subjects s ON (
      s.name = cst.subject
      OR s.code = CASE cst.subject
        WHEN '语文' THEN 'CHINESE'
        WHEN '数学' THEN 'MATH'
        WHEN '英语' THEN 'ENG'
        WHEN '美术' THEN 'ART'
        WHEN '体育' THEN 'PE'
        WHEN '科学' THEN 'SCI'
        WHEN '社会' THEN 'SOC'
        WHEN '音乐' THEN 'MUSIC'
        ELSE NULL
      END
    )
    SET cst.subject_id = s.id
    WHERE cst.subject_id IS NULL
  `)

  // 3) enforce NOT NULL
  await db.execute(sql`ALTER TABLE class_subject_teachers MODIFY COLUMN subject_id VARCHAR(128) NOT NULL;`)

  // 4) drop old PK and create new PK (class_id, subject_id)
  try { await db.execute(sql`ALTER TABLE class_subject_teachers DROP PRIMARY KEY;`) } catch {}
  await db.execute(sql`ALTER TABLE class_subject_teachers ADD PRIMARY KEY (class_id, subject_id);`)

  // 5) drop old subject column if exists
  await db.execute(sql`ALTER TABLE class_subject_teachers DROP COLUMN IF EXISTS subject;`)

  // 6) add index and FK
  try { await db.execute(sql`CREATE INDEX class_subject_teachers_subject_id_idx ON class_subject_teachers (subject_id);`) } catch {}
  try { await db.execute(sql`ALTER TABLE class_subject_teachers DROP FOREIGN KEY cst_s_fk;`) } catch {}
  await db.execute(sql`
    ALTER TABLE class_subject_teachers
    ADD CONSTRAINT cst_s_fk
    FOREIGN KEY (subject_id) REFERENCES subjects(id)
    ON DELETE CASCADE
  `)

  console.log("Migration completed: class_subject_teachers now uses subject_id mapping.")
}

main().catch((err) => {
  console.error(err)
  process.exit(1)
})
