"use client"

import { useState, useTransition, useMemo } from "react"
import { useRouter } from "next/navigation"
import { useTranslations } from "next-intl"
import { CheckCircle2, ChevronLeft, ChevronRight, Flag, Trophy } from "lucide-react"
import { toast } from "sonner"

import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Progress } from "@/shared/components/ui/progress"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/shared/components/ui/alert-dialog"

import { QuestionCard } from "./question-card"
import { PracticeResultView } from "./practice-result-view"
import { usePracticeService, usePracticeAnalytics } from "../services/practice-service"
import type { PracticeSessionDetail } from "../types"

interface PracticeSessionViewProps {
  session: PracticeSessionDetail
  /**
   * 放弃练习后的跳转回调（由页面层注入路由跳转逻辑）。
   *
   * 解耦设计：组件本身不硬编码路由，由调用方决定跳转目标。
   * 不传则使用默认行为 `router.push("/student/practice")`（向后兼容）。
   */
  onAbandoned?: () => void
}

/**
 * 专项练习答题界面（编排层）。
 *
 * 职责：
 * 1. 管理 UI 状态（当前题目索引、答案暂存、判分结果缓存）
 * 2. 通过 `usePracticeService()` 调用数据服务（不直接 import actions）
 * 3. 组合 QuestionCard / PracticeResultView 等子组件
 *
 * 子组件：
 * - QuestionCard: 题目卡片（含内容渲染、答题输入、结果展示）
 * - PracticeResultView: 完成后的结果视图
 *
 * 提交失败支持重试（通过 submitFailed + onRetry 传递给 QuestionCard）。
 */
export function PracticeSessionView({
  session,
  onAbandoned,
}: PracticeSessionViewProps): React.ReactNode {
  const t = useTranslations("practice")
  const router = useRouter()
  const service = usePracticeService()
  const analytics = usePracticeAnalytics()
  const [isPending, startTransition] = useTransition()
  const [currentIndex, setCurrentIndex] = useState(0)
  const [answers, setAnswers] = useState<Record<string, unknown>>({})
  const [results, setResults] = useState<Record<string, { isCorrect: boolean | null; score: number | null }>>({})
  const [failedAnswerIds, setFailedAnswerIds] = useState<Set<string>>(new Set())

  const answersList = session.answers
  const total = answersList.length
  const current = answersList[currentIndex]
  const progress = total > 0 ? ((currentIndex + 1) / total) * 100 : 0

  const answeredCount = useMemo(
    () => answersList.filter((a) => a.status === "answered" || a.status === "skipped").length,
    [answersList],
  )
  const correctCount = useMemo(
    () => answersList.filter((a) => a.isCorrect === true).length,
    [answersList],
  )

  function resolveErrorMessage(
    errorCode: string | undefined,
    message: string | undefined,
    fallbackKey: string,
  ): string {
    if (errorCode) {
      return t(`errors.${errorCode}`)
    }
    return message ?? t(fallbackKey)
  }

  if (session.status !== "in_progress") {
    return <PracticeResultView session={session} />
  }

  if (total === 0) {
    return (
      <Card>
        <CardContent className="py-12 text-center text-muted-foreground">
          {t("session.empty")}
        </CardContent>
      </Card>
    )
  }

  function handleSubmit(answer: unknown, skip: boolean = false): void {
    if (!current) return

    startTransition(async () => {
      const formData = new FormData()
      formData.append(
        "json",
        JSON.stringify({
          sessionId: session.id,
          answerId: current.id,
          answer,
          skip,
        }),
      )
      const res = await service.submitAnswer(undefined, formData)
      if (res.success && res.data) {
        const data = res.data
        setResults((prev) => ({ ...prev, [current.id]: data }))
        setFailedAnswerIds((prev) => {
          const next = new Set(prev)
          next.delete(current.id)
          return next
        })
        analytics.trackAnswerSubmit(session.id, current.id, data.isCorrect)
        toast.success(res.message ?? t("toasts.submitted"))
        // 自动跳到下一题
        if (currentIndex < total - 1) {
          setCurrentIndex(currentIndex + 1)
        }
      } else {
        // 标记提交失败，显示重试按钮
        setFailedAnswerIds((prev) => new Set(prev).add(current.id))
        toast.error(resolveErrorMessage(res.errorCode, res.message, "toasts.submitFailed"))
      }
    })
  }

  function handleComplete(): void {
    startTransition(async () => {
      const formData = new FormData()
      formData.append("sessionId", session.id)
      const res = await service.completeSession(undefined, formData)
      if (res.success) {
        analytics.trackSessionComplete(session.id, session.accuracy)
        toast.success(res.message ?? t("toasts.completed"))
        router.refresh()
      } else {
        toast.error(resolveErrorMessage(res.errorCode, res.message, "toasts.completeFailed"))
      }
    })
  }

  function handleAbandon(): void {
    startTransition(async () => {
      const formData = new FormData()
      formData.append("sessionId", session.id)
      const res = await service.abandonSession(undefined, formData)
      if (res.success) {
        analytics.trackSessionAbandon(session.id)
        toast.success(res.message ?? t("toasts.abandoned"))
        // 优先使用注入的回调，否则回退到默认路由
        if (onAbandoned) {
          onAbandoned()
        } else {
          router.push("/student/practice")
        }
      } else {
        toast.error(resolveErrorMessage(res.errorCode, res.message, "toasts.abandonFailed"))
      }
    })
  }

  function handleRetry(): void {
    if (current) {
      analytics.trackErrorRetry(current.id)
    }
    handleSubmit(answers[current?.id ?? ""] ?? null)
  }

  const currentResult = current ? results[current.id] : undefined
  const isAnswered = current?.status === "answered" || current?.status === "skipped"
  const submitFailed = current ? failedAnswerIds.has(current.id) : false

  return (
    <div className="space-y-6">
      {/* 顶部进度条 */}
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <CardTitle
              className="text-lg"
              aria-label={`${t("session.progress")}: ${currentIndex + 1} / ${total}`}
            >
              {t("session.progress")}: {currentIndex + 1} / {total}
            </CardTitle>
            <div className="flex items-center gap-3 text-sm text-muted-foreground">
              <span className="flex items-center gap-1" aria-label={`${t("result.correct")}: ${correctCount}`}>
                <CheckCircle2 className="h-4 w-4 text-emerald-500" aria-hidden="true" />
                {correctCount}
              </span>
              <span aria-label={`${t("result.answered")}: ${answeredCount}/${total}`}>
                {answeredCount}/{total}
              </span>
            </div>
          </div>
          <Progress
            value={progress}
            className="mt-2"
            aria-label={`${t("session.progress")}: ${Math.round(progress)}%`}
          />
        </CardHeader>
      </Card>

      {/* 题目内容 */}
      {current ? (
        <QuestionCard
          answer={current}
          index={currentIndex}
          total={total}
          userAnswer={answers[current.id]}
          onAnswerChange={(ans) => setAnswers((prev) => ({ ...prev, [current.id]: ans }))}
          onSubmit={(ans) => handleSubmit(ans)}
          onSkip={() => handleSubmit(null, true)}
          onRetry={handleRetry}
          isAnswered={isAnswered}
          result={currentResult}
          isPending={isPending}
          submitFailed={submitFailed}
        />
      ) : null}

      {/* 底部导航 */}
      <div className="flex items-center justify-between">
        <Button
          variant="outline"
          onClick={() => setCurrentIndex(Math.max(0, currentIndex - 1))}
          disabled={currentIndex === 0}
          aria-label={t("session.previous")}
        >
          <ChevronLeft className="h-4 w-4" aria-hidden="true" />
          {t("session.previous")}
        </Button>

        <div className="flex gap-2">
          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button variant="ghost" size="sm" aria-label={t("session.abandon")}>
                <Flag className="h-4 w-4" aria-hidden="true" />
                {t("session.abandon")}
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>{t("session.abandonConfirm")}</AlertDialogTitle>
                <AlertDialogDescription>{t("session.abandonDescription")}</AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>{t("session.cancel")}</AlertDialogCancel>
                <AlertDialogAction
                  onClick={handleAbandon}
                  disabled={isPending}
                  aria-label={t("session.confirmAbandon")}
                >
                  {t("session.confirmAbandon")}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>

          {currentIndex < total - 1 ? (
            <Button
              variant="outline"
              onClick={() => setCurrentIndex(currentIndex + 1)}
              aria-label={t("session.next")}
            >
              {t("session.next")}
              <ChevronRight className="h-4 w-4" aria-hidden="true" />
            </Button>
          ) : (
            <Button
              onClick={handleComplete}
              disabled={isPending || answeredCount < total}
              aria-label={t("session.complete")}
            >
              <Trophy className="h-4 w-4" aria-hidden="true" />
              {t("session.complete")}
            </Button>
          )}
        </div>
      </div>
    </div>
  )
}
