/**
 * 题目内容解析纯函数（共享层）
 *
 * 从 `unknown` 类型的题目内容中安全提取文本、选项、正确答案等。
 * 所有函数均为纯函数，无副作用，便于单测。
 *
 * 这些函数被 homework、error-book 等多个模块共享使用，
 * 避免各模块重复实现题目内容解析逻辑。
 */

export type QuestionOption = {
  id: string
  text: string
  isCorrect?: boolean
}

export const isRecord = (v: unknown): v is Record<string, unknown> =>
  typeof v === "object" && v !== null

export const getQuestionText = (content: unknown): string => {
  if (!isRecord(content)) return ""
  return typeof content.text === "string" ? content.text : ""
}

/**
 * 从题目内容中递归提取纯文本预览。
 *
 * 支持以下内容格式：
 * - 字符串：直接返回（可截断）
 * - 数组：递归提取每个节点的 text 和 children，拼接为纯文本
 * - 对象：提取 text 属性
 * - 其他：返回 fallback
 *
 * @param content 题目内容（unknown 类型）
 * @param fallback 无法提取时的回退文本，默认空字符串
 * @param maxLength 最大长度，0 表示不截断，默认 0
 * @returns 提取的纯文本
 */
export function extractQuestionPreview(
  content: unknown,
  fallback = "",
  maxLength = 0,
): string {
  const text = extractTextRecursive(content)
  if (text) {
    return maxLength > 0 ? text.slice(0, maxLength) : text
  }
  return fallback
}

function extractTextRecursive(content: unknown): string {
  if (typeof content === "string") return content
  if (Array.isArray(content)) {
    const parts: string[] = []
    for (const node of content) {
      const text = extractTextRecursive(node)
      if (text) parts.push(text)
    }
    return parts.join("")
  }
  if (isRecord(content)) {
    if (typeof content.text === "string") return content.text
    if (Array.isArray(content.children)) {
      return extractTextRecursive(content.children)
    }
  }
  return ""
}

export const getOptions = (content: unknown): QuestionOption[] => {
  if (!isRecord(content)) return []
  const raw = content.options
  if (!Array.isArray(raw)) return []
  const out: QuestionOption[] = []
  for (const item of raw) {
    if (!isRecord(item)) continue
    const id = typeof item.id === "string" ? item.id : ""
    const text = typeof item.text === "string" ? item.text : ""
    if (!id || !text) continue
    const isCorrect = item.isCorrect === true
    out.push({ id, text, isCorrect })
  }
  return out
}

export const getChoiceCorrectIds = (content: unknown): string[] => {
  return getOptions(content)
    .filter((o): o is QuestionOption & { isCorrect: true } => o.isCorrect === true)
    .map((o) => o.id)
}

export const getJudgmentCorrectAnswer = (content: unknown): boolean | null => {
  if (!isRecord(content)) return null
  return typeof content.correctAnswer === "boolean" ? content.correctAnswer : null
}

export const getTextCorrectAnswers = (content: unknown): string[] => {
  if (!isRecord(content)) return []
  const raw = content.correctAnswer
  if (typeof raw === "string") return [raw]
  if (Array.isArray(raw)) return raw.filter((x): x is string => typeof x === "string")
  return []
}

export type QuestionType = "single_choice" | "multiple_choice" | "judgment" | "text" | string

export const extractAnswerValue = (studentAnswer: unknown): unknown => {
  if (isRecord(studentAnswer) && "answer" in studentAnswer) return studentAnswer.answer
  return studentAnswer
}

/**
 * 从题目内容中提取正确答案，统一序列化为可存储的 JSON 格式。
 *
 * - 选择题：返回正确选项 ID 数组
 * - 判断题：返回布尔值
 * - 填空题：返回正确答案字符串数组
 * - 其他题型或无标准答案：返回 null
 *
 * @param questionType 题目类型
 * @param content 题目内容（unknown 类型）
 * @returns 序列化后的正确答案，或 null
 */
export function extractCorrectAnswer(
  questionType: string,
  content: unknown,
): unknown {
  if (questionType === "single_choice" || questionType === "multiple_choice") {
    const ids = getChoiceCorrectIds(content)
    return ids.length > 0 ? ids : null
  }

  if (questionType === "judgment") {
    const answer = getJudgmentCorrectAnswer(content)
    return answer // 可能是 true/false/null
  }

  if (questionType === "text") {
    const answers = getTextCorrectAnswers(content)
    return answers.length > 0 ? answers : null
  }

  return null
}
