/**
 * 诊断脚本：检查错题本数据状态
 * 用法：npx tsx scripts/diagnose-error-book.ts
 */
import "dotenv/config"
import { db } from "../src/shared/db"
import {
  errorBookItems,
  errorBookReviews,
  examSubmissions,
  homeworkSubmissions,
  users,
  usersToRoles,
  roles,
  classes,
  classEnrollments,
  classSubjectTeachers,
  grades,
  exams,
  homeworkAssignments,
} from "../src/shared/db/schema"
import { eq, inArray, count } from "drizzle-orm"

async function diagnose() {
  console.log("🔍 错题本数据诊断开始...\n")

  // 1. 检查表是否存在且有数据
  const [itemsCount] = await db.select({ value: count() }).from(errorBookItems)
  const [reviewsCount] = await db.select({ value: count() }).from(errorBookReviews)
  console.log(`📊 错题本表数据:`)
  console.log(`  error_book_items: ${itemsCount.value} 行`)
  console.log(`  error_book_reviews: ${reviewsCount.value} 行`)

  if (Number(itemsCount.value) === 0) {
    console.log("\n❌ error_book_items 表为空！需要运行 seed-error-book.ts")
    return
  }

  // 2. 检查错题的 subjectId 分布
  const subjectDist = await db
    .select({
      subjectId: errorBookItems.subjectId,
      count: count(),
    })
    .from(errorBookItems)
    .groupBy(errorBookItems.subjectId)
  console.log(`\n📊 错题 subjectId 分布:`)
  for (const row of subjectDist) {
    console.log(`  subjectId=${row.subjectId ?? "NULL"}: ${row.count} 条`)
  }

  // 3. 检查错题的 sourceType 分布
  const sourceDist = await db
    .select({
      sourceType: errorBookItems.sourceType,
      count: count(),
    })
    .from(errorBookItems)
    .groupBy(errorBookItems.sourceType)
  console.log(`\n📊 错题 sourceType 分布:`)
  for (const row of sourceDist) {
    console.log(`  ${row.sourceType}: ${row.count} 条`)
  }

  // 4. 检查有错题的学生
  const studentsWithErrors = await db
    .select({
      studentId: errorBookItems.studentId,
      itemCount: count(),
    })
    .from(errorBookItems)
    .groupBy(errorBookItems.studentId)
  console.log(`\n📊 有错题的学生 (${studentsWithErrors.length} 名):`)
  for (const row of studentsWithErrors) {
    console.log(`  ${row.studentId}: ${row.itemCount} 条`)
  }

  // 5. 检查教师角色用户
  const teacherRole = await db.select({ id: roles.id }).from(roles).where(eq(roles.name, "teacher")).limit(1)
  if (teacherRole.length > 0) {
    const teachers = await db
      .select({ userId: usersToRoles.userId })
      .from(usersToRoles)
      .where(eq(usersToRoles.roleId, teacherRole[0].id))
    console.log(`\n📊 教师用户 (${teachers.length} 名):`)
    for (const t of teachers) {
      const user = await db.select({ name: users.name }).from(users).where(eq(users.id, t.userId)).limit(1)
      // 查询该教师能访问的班级
      const homeroomClasses = await db.select({ id: classes.id, name: classes.name }).from(classes).where(eq(classes.teacherId, t.userId))
      const subjectClasses = await db
        .select({ classId: classSubjectTeachers.classId })
        .from(classSubjectTeachers)
        .where(eq(classSubjectTeachers.teacherId, t.userId))
      const allClassIds = [...new Set([...homeroomClasses.map((c) => c.id), ...subjectClasses.map((c) => c.classId)])]

      // 查询这些班级的学生
      let studentCount = 0
      let errorCount = 0
      if (allClassIds.length > 0) {
        const students = await db
          .select({ studentId: classEnrollments.studentId })
          .from(classEnrollments)
          .where(inArray(classEnrollments.classId, allClassIds))
        const studentIds = [...new Set(students.map((s) => s.studentId))]
        studentCount = studentIds.length

        if (studentIds.length > 0) {
          const errorItems = await db
            .select({ value: count() })
            .from(errorBookItems)
            .where(inArray(errorBookItems.studentId, studentIds))
          errorCount = Number(errorItems[0]?.value ?? 0)
        }
      }

      console.log(`  ${user[0]?.name ?? t.userId} (${t.userId}): 班级=${allClassIds.length}, 学生=${studentCount}, 错题=${errorCount}`)
    }
  }

  // 6. 检查年级组长
  const gradeHeadRole = await db.select({ id: roles.id }).from(roles).where(eq(roles.name, "grade_head")).limit(1)
  if (gradeHeadRole.length > 0) {
    const gradeHeads = await db
      .select({ userId: usersToRoles.userId })
      .from(usersToRoles)
      .where(eq(usersToRoles.roleId, gradeHeadRole[0].id))
    console.log(`\n📊 年级组长 (${gradeHeads.length} 名):`)
    for (const gh of gradeHeads) {
      const user = await db.select({ name: users.name }).from(users).where(eq(users.id, gh.userId)).limit(1)
      const managedGrades = await db.select({ id: grades.id, name: grades.name }).from(grades).where(eq(grades.gradeHeadId, gh.userId))
      console.log(`  ${user[0]?.name ?? gh.userId} (${gh.userId}): 管理年级=${managedGrades.length}`)
      for (const g of managedGrades) {
        const gradeClasses = await db.select({ id: classes.id }).from(classes).where(eq(classes.gradeId, g.id))
        console.log(`    年级 ${g.name}: ${gradeClasses.length} 个班级`)
      }
    }
  }

  // 7. 检查已批改的提交数量
  const gradedExams = await db.select({ value: count() }).from(examSubmissions).where(eq(examSubmissions.status, "graded"))
  const gradedHw = await db.select({ value: count() }).from(homeworkSubmissions).where(eq(homeworkSubmissions.status, "graded"))
  console.log(`\n📊 已批改提交:`)
  console.log(`  考试提交: ${gradedExams[0]?.value ?? 0}`)
  console.log(`  作业提交: ${gradedHw[0]?.value ?? 0}`)

  // 8. 检查 exams 表的 subjectId 是否有值
  const examSubjectStats = await db
    .select({
      subjectId: exams.subjectId,
      count: count(),
    })
    .from(exams)
    .groupBy(exams.subjectId)
  console.log(`\n📊 exams 表 subjectId 分布:`)
  for (const row of examSubjectStats) {
    console.log(`  subjectId=${row.subjectId ?? "NULL"}: ${row.count} 个考试`)
  }

  // 9. 检查 homeworkAssignments 是否有 subjectId 字段（应该没有）
  console.log(`\n📊 homeworkAssignments 表结构检查:`)
  try {
    const hwRows = await db.select().from(homeworkAssignments).limit(1)
    if (hwRows.length > 0) {
      const keys = Object.keys(hwRows[0])
      console.log(`  字段列表: ${keys.join(", ")}`)
      console.log(`  是否有 subjectId 字段: ${keys.includes("subjectId") ? "是" : "否"}`)
    } else {
      console.log(`  表为空`)
    }
  } catch (e) {
    console.log(`  查询失败: ${(e as Error).message}`)
  }

  console.log("\n✅ 诊断完成")
  process.exit(0)
}

diagnose().catch((e) => {
  console.error("❌ 诊断失败:", e)
  process.exit(1)
})
