"use client"

import { useEffect, useMemo, useState } from "react"
import { useTranslations } from "next-intl"
import { useQuestionService } from "../providers/lesson-plan-provider"
import type { QuestionPickerItem, QuestionPickerParams } from "../providers/lesson-plan-provider"
import { Button } from "@/shared/components/ui/button"
import { FocusTrap } from "@/shared/components/a11y/focus-trap"
import { QuestionBankSkeleton } from "./lesson-plan-skeleton"
import { useDebounce } from "@/shared/hooks/use-debounce"
import { X, ChevronDown, ChevronRight } from "lucide-react"
import { QuestionBankFilters } from "@/shared/components/question/question-bank-filters"
import type { ExerciseItem } from "../types"
import type { QuestionType } from "@/modules/questions/types"
import { isRecord } from "@/shared/lib/type-guards"

// 类型守卫：验证字符串是否为有效的 QuestionType（避免 as 断言）
function isQuestionType(v: string): v is QuestionType {
  const validTypes: readonly string[] = [
    "single_choice",
    "multiple_choice",
    "judgment",
    "text",
    "composite",
  ]
  return validTypes.includes(v)
}

interface Props {
  onPick: (items: ExerciseItem[]) => void
  onClose: () => void
  existingIds: string[]
}

export function QuestionBankPicker({ onPick, onClose, existingIds }: Props) {
  const t = useTranslations("lessonPreparation")
  // V4 P0-4 修复：通过 QuestionService 接口获取题目，不直接依赖 questions 模块
  const questionService = useQuestionService()
  const [questions, setQuestions] = useState<QuestionPickerItem[]>([])
  const [picked, setPicked] = useState<ExerciseItem[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  // P1-1 修复：ESC 键关闭对话框
  useEffect(() => {
    function handleEsc(e: KeyboardEvent) {
      if (e.key === "Escape") onClose()
    }
    document.addEventListener("keydown", handleEsc)
    return () => document.removeEventListener("keydown", handleEsc)
  }, [onClose])

  // QuestionBankFilters 使用字符串值，这里转换为 filters 对象
  const [searchValue, setSearchValue] = useState("")
  const [typeValue, setTypeValue] = useState<string>("all")
  const [difficultyValue, setDifficultyValue] = useState<string>("all")

  const filters = useMemo<QuestionPickerParams>(() => {
    const newFilters: QuestionPickerParams = {}
    if (searchValue) newFilters.q = searchValue
    // 类型守卫：仅当值为有效 QuestionType 时才赋值（避免 as 断言）
    if (typeValue !== "all" && isQuestionType(typeValue)) {
      newFilters.type = typeValue
    }
    if (difficultyValue !== "all") newFilters.difficulty = Number(difficultyValue)
    return newFilters
  }, [searchValue, typeValue, difficultyValue])

  // 修复 P1-5：搜索 debounce 300ms
  const debouncedFilters = useDebounce(filters, 300)

  useEffect(() => {
    if (!questionService) return
    let cancelled = false
    // V4 P2-3 修复：使用 async IIFE + ignore flag 替代 Promise.resolve().then()
    ;(async () => {
      setLoading(true)
      setError(null)
      try {
        const res = await questionService.getQuestions(debouncedFilters)
        if (cancelled) return
        if (res.success && res.data) {
          setQuestions(res.data.data)
        } else {
          setError(res.message ?? t("error.loadFailed"))
        }
      } catch (e) {
        if (cancelled) return
        console.error("[QuestionBankPicker] load questions failed", e)
        setError(t("error.loadFailed"))
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [debouncedFilters, t, questionService])

  function add(q: QuestionPickerItem) {
    if (existingIds.includes(q.id) || picked.some((p) => p.questionId === q.id)) return
    setPicked((prev) => [
      ...prev,
      {
        questionId: q.id,
        source: "bank",
        score: 5,
        order: prev.length,
      },
    ])
  }

  function previewText(content: unknown): string {
    if (typeof content === "string") return content.slice(0, 80)
    try {
      return JSON.stringify(content).slice(0, 80)
    } catch {
      return ""
    }
  }

  // V5-6：展开题目详情（题干/选项/答案）
  const [expandedId, setExpandedId] = useState<string | null>(null)

  function toggleExpand(id: string) {
    setExpandedId((prev) => (prev === id ? null : id))
  }

  // V5-6：从 content 中安全提取题干
  function extractStem(content: unknown): string {
    if (typeof content === "string") return content
    if (isRecord(content)) {
      const stem = content.stem
      if (typeof stem === "string") return stem
      const text = content.text
      if (typeof text === "string") return text
    }
    return ""
  }

  // V5-6：从 content 中安全提取选项列表
  function extractOptions(content: unknown): { label: string; text: string; isCorrect?: boolean }[] {
    if (!isRecord(content)) return []
    const options = content.options
    if (!Array.isArray(options)) return []
    return options
      .filter((o): o is Record<string, unknown> => isRecord(o))
      .map((o, i) => ({
        label: typeof o.label === "string" ? o.label : String.fromCharCode(65 + i),
        text: typeof o.text === "string" ? o.text : "",
        isCorrect: typeof o.isCorrect === "boolean" ? o.isCorrect : undefined,
      }))
  }

  // V5-6：从 content 中安全提取答案
  function extractAnswer(content: unknown): string {
    if (!isRecord(content)) return ""
    const answer = content.answer
    if (typeof answer === "string") return answer
    if (typeof answer === "number") return String(answer)
    if (Array.isArray(answer)) {
      return answer
        .filter((a): a is string | number => typeof a === "string" || typeof a === "number")
        .map((a) => String(a))
        .join(", ")
    }
    return ""
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30">
      <div
        role="dialog"
        aria-modal="true"
        aria-label={t("questionBank.title")}
        className="bg-surface rounded-lg shadow-xl w-[700px] max-h-[80vh] flex flex-col"
      >
        <FocusTrap className="contents">
        <div className="flex justify-between items-center p-4 border-b">
          <h3 className="font-title-md">{t("questionBank.title")}</h3>
          <button onClick={onClose} aria-label={t("action.close")}>
            <X className="w-4 h-4" aria-hidden="true" />
          </button>
        </div>
        <div className="p-4 border-b">
          <QuestionBankFilters
            search={searchValue}
            onSearchChange={setSearchValue}
            type={typeValue}
            onTypeChange={setTypeValue}
            difficulty={difficultyValue}
            onDifficultyChange={setDifficultyValue}
            layout="default"
          />
        </div>
        <div className="flex-1 overflow-y-auto p-4">
          {loading ? (
            <QuestionBankSkeleton />
          ) : error ? (
            <p className="text-error text-sm text-center py-8">{error}</p>
          ) : questions.length === 0 ? (
            <p className="text-on-surface-variant text-sm text-center py-8">
              {t("questionBank.empty")}
            </p>
          ) : (
            <div className="space-y-2">
              {questions.map((q) => {
                const isExpanded = expandedId === q.id
                const stem = extractStem(q.content)
                const options = extractOptions(q.content)
                const answer = extractAnswer(q.content)
                return (
                  <div
                    key={q.id}
                    className="border rounded p-2"
                  >
                    <div className="flex justify-between items-center">
                      <button
                        className="flex-1 text-left flex items-start gap-2 mr-2"
                        onClick={() => toggleExpand(q.id)}
                        aria-expanded={isExpanded}
                      >
                        {isExpanded ? (
                          <ChevronDown className="w-3 h-3 mt-1 flex-shrink-0" aria-hidden="true" />
                        ) : (
                          <ChevronRight className="w-3 h-3 mt-1 flex-shrink-0" aria-hidden="true" />
                        )}
                        <span className="text-sm truncate flex-1">
                          {previewText(q.content)}
                        </span>
                      </button>
                      <span className="text-xs text-on-surface-variant mr-2 whitespace-nowrap">
                        {t(`questionBank.type.${q.type}`)} · {t("questionBank.difficulty", { level: q.difficulty })}
                      </span>
                      <Button size="sm" variant="outline" onClick={() => add(q)}>
                        {t("questionBank.add")}
                      </Button>
                    </div>
                    {isExpanded && (
                      <div className="mt-2 pl-5 space-y-2 text-sm border-t pt-2">
                        {/* V5-6：题干 */}
                        {stem && (
                          <div>
                            <div className="text-xs text-on-surface-variant font-medium">
                              {t("questionBank.stemLabel")}
                            </div>
                            <div className="mt-0.5 whitespace-pre-wrap">{stem}</div>
                          </div>
                        )}
                        {/* V5-6：选项 */}
                        {options.length > 0 && (
                          <div>
                            <div className="text-xs text-on-surface-variant font-medium">
                              {t("questionBank.optionsLabel")}
                            </div>
                            <ul className="mt-0.5 space-y-0.5">
                              {options.map((opt, i) => (
                                <li
                                  key={i}
                                  className={`flex items-start gap-1 ${opt.isCorrect ? "text-primary font-medium" : ""}`}
                                >
                                  <span className="flex-shrink-0">{opt.label}.</span>
                                  <span>{opt.text}</span>
                                  {opt.isCorrect && (
                                    <span className="text-xs text-primary">✓</span>
                                  )}
                                </li>
                              ))}
                            </ul>
                          </div>
                        )}
                        {/* V5-6：答案 */}
                        {answer && (
                          <div>
                            <div className="text-xs text-on-surface-variant font-medium">
                              {t("questionBank.correctAnswer")}
                            </div>
                            <div className="mt-0.5 text-primary">{answer}</div>
                          </div>
                        )}
                        {!stem && options.length === 0 && !answer && (
                          <p className="text-xs text-on-surface-variant italic">
                            {t("questionBank.noDetail")}
                          </p>
                        )}
                      </div>
                    )}
                  </div>
                )
              })}
            </div>
          )}
        </div>
        <div className="p-4 border-t flex justify-between">
          <span className="text-sm">{t("questionBank.selected", { count: picked.length })}</span>
          <Button
            onClick={() => {
              onPick(picked)
              onClose()
            }}
          >
            {t("questionBank.insert")}
          </Button>
        </div>
        </FocusTrap>
      </div>
    </div>
  )
}
