/**
 * 题目内容类型定义与类型守卫。
 *
 * 题目 content 存储为 JSON（unknown），实际结构为：
 * - { text: string } — 简答题/判断题
 * - { text: string, options: QuestionOption[] } — 选择题
 * - { text: string, options: QuestionOption[], answer?: string, explanation?: string } — 完整结构
 *
 * 所有从 unknown 到具体类型的转换必须使用本文件的类型守卫函数，
 * 禁止使用 `as` 断言。
 */

/** 选择题选项 */
export interface QuestionOption {
  id: string
  text: string
  isCorrect: boolean
}

/** 题目内容结构化类型 */
export interface QuestionContent {
  text: string
  options?: QuestionOption[]
  answer?: string
  explanation?: string
}

/** 类型守卫：判断值是否为字符串 */
function isString(value: unknown): value is string {
  return typeof value === "string"
}

/** 类型守卫：判断值是否为非 null 对象 */
function isNonNullObject(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null
}

/** 类型守卫：判断值是否为 QuestionOption */
function isQuestionOption(value: unknown): value is QuestionOption {
  if (!isNonNullObject(value)) return false
  const id = value.id
  const text = value.text
  const isCorrect = value.isCorrect
  return (
    (isString(id) || id === undefined) &&
    isString(text) &&
    typeof isCorrect === "boolean"
  )
}

/** 类型守卫：判断值是否为 QuestionOption 数组 */
function isQuestionOptionArray(value: unknown): value is QuestionOption[] {
  return Array.isArray(value) && value.every(isQuestionOption)
}

/**
 * 从 unknown 安全解析为 QuestionContent。
 *
 * 处理以下情况：
 * - 字符串：转为 { text: string }
 * - 对象：提取 text/options/answer/explanation 字段
 * - null/undefined：返回 { text: "" }
 * - 其他：JSON.stringify 后转为 { text }
 *
 * @example
 * const content = parseQuestionContent(question.content)
 * console.log(content.text)        // 题干文本
 * console.log(content.options)      // 选项列表（选择题）
 */
export function parseQuestionContent(raw: unknown): QuestionContent {
  if (isString(raw)) {
    return { text: raw }
  }

  if (isNonNullObject(raw)) {
    const text = isString(raw.text) ? raw.text : ""
    const optionsRaw = raw.options
    const options = isQuestionOptionArray(optionsRaw)
      ? optionsRaw.map((opt) => ({
          id: opt.id ?? opt.text,
          text: opt.text,
          isCorrect: opt.isCorrect,
        }))
      : undefined
    const answer = isString(raw.answer) ? raw.answer : undefined
    const explanation = isString(raw.explanation) ? raw.explanation : undefined

    return { text, options, answer, explanation }
  }

  if (raw == null) {
    return { text: "" }
  }

  try {
    return { text: JSON.stringify(raw) }
  } catch {
    return { text: "" }
  }
}

/**
 * 从 QuestionContent 提取纯文本预览（截断到指定长度）。
 *
 * @param raw - 原始 content（unknown）
 * @param maxLength - 最大长度，默认 80
 */
export function getQuestionPreview(raw: unknown, maxLength = 80): string {
  const content = parseQuestionContent(raw)
  return content.text.slice(0, maxLength)
}

/**
 * 从 QuestionContent 提取选项列表（用于表单回填）。
 *
 * @returns 选项数组，无选项时返回 undefined
 */
export function getQuestionOptions(raw: unknown): QuestionOption[] | undefined {
  const content = parseQuestionContent(raw)
  return content.options
}

/**
 * 从 QuestionContent 提取纯文本（用于 AI 变体生成等场景）。
 */
export function getQuestionText(raw: unknown): string {
  return parseQuestionContent(raw).text
}
