/**
 * Adaptive Practice 自动判分纯函数。
 *
 * 从 data-access.ts 抽取为独立模块，便于单测与复用。
 *
 * 支持题型：
 * - single_choice: 比对选中选项 ID
 * - multiple_choice: 比对选中选项 ID 集合（顺序无关）
 * - judgment: 比对布尔值
 * - text: 不自动判分（返回 null）
 */

import { isRecord } from "@/shared/lib/type-guards"

/**
 * 自动判分：比对学生答案与正确答案。
 *
 * @param questionType 题目类型
 * @param content 题目内容（或变式题内容）
 * @param studentAnswer 学生答案
 * @returns 是否正确（null 表示无法自动判分）
 */
export function autoGradeAnswer(
  questionType: string,
  content: unknown,
  studentAnswer: unknown,
): boolean | null {
  if (questionType === "single_choice" || questionType === "multiple_choice") {
    const correctIds = extractChoiceCorrectIds(content)
    if (correctIds.length === 0) return null

    const studentIds = normalizeAnswerToIds(studentAnswer)
    if (studentIds.length === 0) return false

    if (questionType === "single_choice") {
      return studentIds.length === 1 && studentIds[0] === correctIds[0]
    }

    // multiple_choice: 集合比对
    if (studentIds.length !== correctIds.length) return false
    const correctSet = new Set(correctIds)
    return studentIds.every((id) => correctSet.has(id))
  }

  if (questionType === "judgment") {
    const correctAnswer = extractJudgmentCorrectAnswer(content)
    if (correctAnswer === null) return null

    const studentBool = normalizeAnswerToBool(studentAnswer)
    if (studentBool === null) return null

    return studentBool === correctAnswer
  }

  // text 题型不自动判分
  return null
}

/**
 * 从题目内容中提取选择题正确选项 ID 列表。
 */
export function extractChoiceCorrectIds(content: unknown): string[] {
  if (!isRecord(content)) return []

  const options = content.options
  if (!Array.isArray(options)) return []

  return options
    .filter((opt: unknown): opt is Record<string, unknown> =>
      isRecord(opt) && opt.isCorrect === true,
    )
    .map((opt) => {
      const id = opt.id
      return typeof id === "string" ? id : ""
    })
    .filter((id) => id.length > 0)
}

/**
 * 从题目内容中提取判断题正确答案。
 */
export function extractJudgmentCorrectAnswer(content: unknown): boolean | null {
  if (!isRecord(content)) return null

  const answer = content.answer
  if (typeof answer === "boolean") return answer
  if (typeof answer === "string") {
    const lower = answer.toLowerCase()
    if (lower === "true" || lower === "correct" || lower === "对" || lower === "正确") return true
    if (lower === "false" || lower === "incorrect" || lower === "wrong" || lower === "错" || lower === "错误") return false
  }
  return null
}

/**
 * 将学生答案归一化为选项 ID 列表。
 */
export function normalizeAnswerToIds(answer: unknown): string[] {
  if (typeof answer === "string") return [answer]
  if (Array.isArray(answer)) {
    return answer.filter((v): v is string => typeof v === "string")
  }
  if (isRecord(answer)) {
    const ids = answer.selectedIds
    if (Array.isArray(ids)) {
      return ids.filter((v): v is string => typeof v === "string")
    }
    if (typeof answer.id === "string") return [answer.id]
  }
  return []
}

/**
 * 将学生答案归一化为布尔值。
 */
export function normalizeAnswerToBool(answer: unknown): boolean | null {
  if (typeof answer === "boolean") return answer
  if (typeof answer === "string") {
    const lower = answer.toLowerCase()
    if (lower === "true" || lower === "correct" || lower === "对" || lower === "正确") return true
    if (lower === "false" || lower === "incorrect" || lower === "wrong" || lower === "错" || lower === "错误") return false
  }
  return null
}

/**
 * 从题目内容中提取选项列表（用于 UI 渲染）。
 */
export function extractOptions(content: unknown): Array<{ id: string; text: string }> {
  if (!isRecord(content)) return []
  const options = content.options
  if (!Array.isArray(options)) return []

  return options
    .filter((opt): opt is Record<string, unknown> =>
      typeof opt === "object" && opt !== null && typeof opt.id === "string",
    )
    .map((opt) => ({
      id: opt.id as string,
      text: typeof opt.text === "string" ? opt.text : String(opt.text ?? ""),
    }))
}
