"use client"

import { useEffect, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import Link from "next/link"
import { useTranslations } from "next-intl"
import { toast } from "sonner"

import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Card, CardHeader } from "@/shared/components/ui/card"
import { Label } from "@/shared/components/ui/label"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/shared/components/ui/alert-dialog"
import { Clock, CheckCircle2, Save, FileText, ChevronLeft, TriangleAlert, CloudUpload, CloudOff, Check, Loader2 } from "lucide-react"
import { formatDate, cn } from "@/shared/lib/utils"

import type { StudentHomeworkTakeData } from "../types"
import { saveHomeworkAnswerAction, startHomeworkSubmissionAction, submitHomeworkAction } from "../actions"
import { QuestionRenderer } from "./question-renderer"
import { parseSavedAnswer } from "../lib/question-content-utils"
import { useDebouncedAutoSave, loadOfflineCache, clearOfflineCache } from "../hooks/use-debounced-auto-save"

type HomeworkTakeViewProps = {
  assignmentId: string
  initialData: StudentHomeworkTakeData
}

export function HomeworkTakeView({ assignmentId, initialData }: HomeworkTakeViewProps) {
  const router = useRouter()
  const t = useTranslations("examHomework")
  const [submissionId, setSubmissionId] = useState<string | null>(initialData.submission?.id ?? null)
  const [submissionStatus, setSubmissionStatus] = useState<string>(initialData.submission?.status ?? "not_started")
  const [isBusy, setIsBusy] = useState(false)
  const [showSubmitConfirm, setShowSubmitConfirm] = useState(false)

  const initialAnswersByQuestionId = useMemo(() => {
    const map = new Map<string, { answer: unknown }>()
    for (const q of initialData.questions) {
      map.set(q.questionId, parseSavedAnswer(q.savedAnswer, q.questionType))
    }
    return map
  }, [initialData.questions])

  const [answersByQuestionId, setAnswersByQuestionId] = useState(() => {
    const obj: Record<string, { answer: unknown }> = {}
    for (const [k, v] of initialAnswersByQuestionId.entries()) obj[k] = v
    return obj
  })

  const isStarted = submissionStatus === "started"
  const canEdit = isStarted && Boolean(submissionId)
  const showQuestions = submissionStatus !== "not_started"

  // P2-9: 自动保存 + 离线缓存
  const offlineStorageKey = `homework-draft-${assignmentId}`
  const autoSave = useDebouncedAutoSave({
    submissionId,
    answers: answersByQuestionId,
    enabled: canEdit,
    storageKey: offlineStorageKey,
  })

  // 挂载时尝试从 localStorage 恢复未提交的答案
  useEffect(() => {
    if (!canEdit) return
    const cached = loadOfflineCache(offlineStorageKey)
    if (!cached) return
    setAnswersByQuestionId((prev) => {
      const merged: Record<string, { answer: unknown }> = { ...prev }
      let changed = false
      for (const questionId of Object.keys(cached)) {
        const cachedEntry = cached[questionId]
        if (!cachedEntry) continue
        const prevEntry = prev[questionId]
        const cachedJson = JSON.stringify(cachedEntry.answer)
        const prevJson = prevEntry ? JSON.stringify(prevEntry.answer) : ""
        if (cachedJson !== prevJson) {
          merged[questionId] = { answer: cachedEntry.answer }
          changed = true
        }
      }
      if (changed) {
        toast.success(t("homework.take.autoSaveRestored"))
      }
      return merged
    })
    // 仅恢复一次，恢复后清除缓存（避免重复提示）
    clearOfflineCache(offlineStorageKey)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [canEdit])

  // 离开警告：作答中未提交时关闭/刷新页面会丢失答案
  useEffect(() => {
    if (!canEdit) return
    const handler = (e: BeforeUnloadEvent) => {
      e.preventDefault()
      e.returnValue = ""
    }
    window.addEventListener("beforeunload", handler)
    return () => window.removeEventListener("beforeunload", handler)
  }, [canEdit])

  // 截止时间与紧急度
  const dueAt = initialData.assignment.dueAt
  const now = new Date()
  const dueDate = dueAt ? new Date(dueAt) : null
  const isOverdue = dueDate ? dueDate < now : false
  const hoursUntilDue = dueDate ? Math.floor((dueDate.getTime() - now.getTime()) / (1000 * 60 * 60)) : null
  const isUrgent = hoursUntilDue !== null && hoursUntilDue >= 0 && hoursUntilDue < 24

  // 尝试次数
  const maxAttempts = initialData.assignment.maxAttempts
  const attemptsUsed = initialData.submission?.attemptNo ?? 0
  const attemptsRemaining = Math.max(0, maxAttempts - attemptsUsed)

  const handleStart = async () => {
    setIsBusy(true)
    const fd = new FormData()
    fd.set("assignmentId", assignmentId)
    const res = await startHomeworkSubmissionAction(null, fd)
    if (res.success && res.data) {
      setSubmissionId(res.data)
      setSubmissionStatus("started")
      toast.success(t("homework.take.startSuccess"))
      router.refresh()
    } else {
      toast.error(res.message || t("homework.take.startFailed"))
    }
    setIsBusy(false)
  }

  const handleSaveQuestion = async (questionId: string) => {
    if (!submissionId) return
    // setIsBusy(true) // Don't block UI for individual saves
    const payload = answersByQuestionId[questionId]?.answer ?? null
    const fd = new FormData()
    fd.set("submissionId", submissionId)
    fd.set("questionId", questionId)
    fd.set("answerJson", JSON.stringify({ answer: payload }))
    const res = await saveHomeworkAnswerAction(null, fd)
    if (res.success) toast.success(t("homework.take.saved"))
    else toast.error(res.message || t("homework.take.saveFailed"))
    // setIsBusy(false)
  }

  const handleSubmit = async () => {
    if (!submissionId) return
    setIsBusy(true)
    // P2-9: 提交前 flush 自动保存队列，确保所有答案已落库
    await autoSave.flush()

    const submitFd = new FormData()
    submitFd.set("submissionId", submissionId)
    const submitRes = await submitHomeworkAction(null, submitFd)
    if (submitRes.success) {
      // 提交成功后清除离线缓存
      clearOfflineCache(offlineStorageKey)
      toast.success(t("homework.take.submitSuccess"))
      setSubmissionStatus("submitted")
      router.push("/student/learning/assignments")
    } else {
      toast.error(submitRes.message || t("homework.take.submitFailed"))
    }
    setIsBusy(false)
  }

  // 统计未作答题目数
  const unansweredCount = initialData.questions.filter((q) => {
    const v = answersByQuestionId[q.questionId]?.answer
    if (v === undefined || v === null) return true
    if (typeof v === "string" && v.trim() === "") return true
    if (Array.isArray(v) && v.length === 0) return true
    return false
  }).length

  return (
    <div className="grid h-[calc(100vh-10rem)] grid-cols-1 gap-6 lg:grid-cols-12">
      <div className="lg:col-span-9 flex flex-col h-full overflow-hidden rounded-md border bg-card">
        <div className="border-b p-4 flex items-center justify-between bg-muted/30">
          <div className="flex items-center gap-3">
            <Button asChild variant="ghost" size="sm" className="mr-1">
              <Link href="/student/learning/assignments">
                <ChevronLeft className="mr-1 h-4 w-4" />
                {t("homework.take.back")}
              </Link>
            </Button>
            <div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary/10">
              <FileText className="h-4 w-4 text-primary" />
            </div>
            <div>
              <h3 className="font-semibold leading-none">{t("homework.take.questions")}</h3>
              <div className="mt-1 flex items-center gap-2 text-xs text-muted-foreground">
                <Badge variant={submissionStatus === "started" ? "default" : "secondary"} className="h-5 px-1.5 text-[10px] capitalize">
                  {submissionStatus === "not_started" ? t("homework.take.notStarted") : submissionStatus}
                </Badge>
                <span>•</span>
                <span>{initialData.questions.length} {t("homework.take.questions")}</span>
              </div>
            </div>
          </div>

          {!canEdit ? (
            <Button onClick={handleStart} disabled={isBusy} size="sm">
              {isBusy ? t("homework.take.starting") : t("homework.take.startAssignment")}
            </Button>
          ) : (
            <Button onClick={() => setShowSubmitConfirm(true)} disabled={isBusy} size="sm">
              <CheckCircle2 className="mr-2 h-4 w-4" />
              {isBusy ? t("homework.take.submitting") : t("homework.take.submitAssignment")}
            </Button>
          )}
        </div>

        <ScrollArea className="flex-1 bg-muted/10">
          <div className="space-y-6 p-6 max-w-4xl mx-auto">
            {!isStarted && (
              <div className="flex flex-col items-center justify-center py-12 text-center">
                <div className="h-12 w-12 rounded-full bg-muted flex items-center justify-center mb-4">
                  <Clock className="h-6 w-6 text-muted-foreground" />
                </div>
                <h3 className="text-lg font-medium">{t("homework.take.readyToStart")}</h3>
                <p className="text-muted-foreground max-w-sm mt-2 mb-6">
                  {t("homework.take.readyDescription")}
                </p>
                <Button onClick={handleStart} disabled={isBusy}>
                  {t("homework.take.startNow")}
                </Button>
              </div>
            )}

            {showQuestions && initialData.questions.map((q, idx) => {
              const value = answersByQuestionId[q.questionId]?.answer

              return (
                <Card key={q.questionId} id={`question-${q.questionId}`} className="border-l-4 border-l-primary shadow-sm scroll-mt-4">
                  <CardHeader className="pb-2">
                    <QuestionRenderer
                      questionId={q.questionId}
                      questionType={q.questionType}
                      questionContent={q.questionContent}
                      maxScore={q.maxScore}
                      index={idx}
                      mode={submissionStatus === "graded" ? "review" : "take"}
                      value={value}
                      disabled={!canEdit}
                      onChange={(answer) =>
                        setAnswersByQuestionId((prev) => ({
                          ...prev,
                          [q.questionId]: { answer },
                        }))
                      }
                      showCorrectAnswer={submissionStatus === "graded"}
                      feedback={submissionStatus === "graded" ? q.feedback : null}
                      footerExtra={
                        canEdit ? (
                          <div className="flex justify-end pt-2">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => handleSaveQuestion(q.questionId)}
                              disabled={isBusy}
                              className="text-muted-foreground hover:text-foreground"
                            >
                              <Save className="mr-2 h-3 w-3" />
                              {t("homework.take.saveAnswer")}
                            </Button>
                          </div>
                        ) : null
                      }
                    />
                  </CardHeader>
                </Card>
              )
            })}
          </div>
        </ScrollArea>
      </div>

      <div className="lg:col-span-3 flex flex-col h-full overflow-hidden rounded-md border bg-card">
        <div className="border-b p-4 bg-muted/30">
          <h3 className="font-semibold">{t("homework.take.assignmentInfo")}</h3>
          {canEdit && (
            <div className="mt-2 flex items-center gap-1.5 text-xs text-muted-foreground" role="status" aria-live="polite">
              {autoSave.status === "saving" && <Loader2 className="h-3 w-3 animate-spin" />}
              {autoSave.status === "saved" && <Check className="h-3 w-3 text-green-500" />}
              {autoSave.status === "error" && <CloudOff className="h-3 w-3 text-destructive" />}
              {autoSave.status === "idle" && <CloudUpload className="h-3 w-3" />}
              <span className={
                autoSave.status === "saved" ? "text-green-600" :
                autoSave.status === "error" ? "text-destructive" :
                "text-muted-foreground"
              }>
                {t(`homework.take.autoSave${autoSave.status.charAt(0).toUpperCase()}${autoSave.status.slice(1)}`)}
              </span>
            </div>
          )}
        </div>
        <div className="flex-1 p-4 overflow-y-auto">
          <div className="space-y-6">
            <div>
              <Label className="text-xs text-muted-foreground uppercase tracking-wider">{t("homework.take.status")}</Label>
              <div className="mt-1 flex items-center gap-2">
                <Badge variant={submissionStatus === "started" ? "default" : "outline"} className="capitalize">
                  {submissionStatus === "not_started" ? t("homework.take.notStarted") : submissionStatus}
                </Badge>
              </div>
            </div>

            {dueAt && (
              <div>
                <Label className="text-xs text-muted-foreground uppercase tracking-wider">{t("homework.take.dueDate")}</Label>
                <div className={cn(
                  "mt-1 flex items-center gap-2 text-sm font-medium",
                  isOverdue ? "text-destructive" : isUrgent ? "text-orange-500" : "text-foreground"
                )}>
                  {(isOverdue || isUrgent) && <TriangleAlert className="h-4 w-4" />}
                  <span>{formatDate(dueAt)}</span>
                </div>
                {isOverdue && (
                  <p className="mt-1 text-xs text-destructive">{t("homework.take.overdue")}</p>
                )}
                {isUrgent && !isOverdue && hoursUntilDue !== null && (
                  <p className="mt-1 text-xs text-orange-500">
                    {hoursUntilDue === 0
                      ? t("homework.take.lessThanOneHour")
                      : t("homework.take.hoursLeft", { hours: hoursUntilDue })}
                  </p>
                )}
              </div>
            )}

            {maxAttempts > 0 && (
              <div>
                <Label className="text-xs text-muted-foreground uppercase tracking-wider">{t("homework.take.attempts")}</Label>
                <div className="mt-1 text-sm">
                  <span className="font-medium">{attemptsUsed}</span>
                  <span className="text-muted-foreground"> {t("homework.take.attemptsUsed", { used: attemptsUsed, max: maxAttempts })}</span>
                  {attemptsRemaining > 0 && (
                    <span className="text-muted-foreground"> {t("homework.take.attemptsRemaining", { remaining: attemptsRemaining })}</span>
                  )}
                </div>
              </div>
            )}

            <div>
              <Label className="text-xs text-muted-foreground uppercase tracking-wider">{t("homework.take.description")}</Label>
              <p className="mt-1 text-sm text-muted-foreground leading-relaxed">
                {initialData.assignment.description || t("homework.take.noDescription")}
              </p>
            </div>

            {showQuestions && (
              <div>
                <Label className="text-xs text-muted-foreground uppercase tracking-wider">{t("homework.take.progress")}</Label>
                <div className="mt-2 grid grid-cols-5 gap-2">
                  {initialData.questions.map((q, i) => {
                    const answer = answersByQuestionId[q.questionId]?.answer
                    const hasAnswer = answer !== undefined &&
                                    answer !== "" &&
                                    (Array.isArray(answer) ? answer.length > 0 : true)

                    return (
                      <button
                        key={q.questionId}
                        type="button"
                        onClick={() => {
                          const el = document.getElementById(`question-${q.questionId}`)
                          if (el) el.scrollIntoView({ behavior: "smooth", block: "start" })
                        }}
                        className={cn(
                          "h-8 w-8 rounded flex items-center justify-center text-xs font-medium border transition-colors hover:opacity-80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
                          hasAnswer ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground border-input"
                        )}
                        aria-label={t("homework.take.jumpToQuestion", { index: i + 1 })}
                        aria-pressed={hasAnswer}
                        title={hasAnswer ? t("homework.take.answered") : t("homework.take.unanswered")}
                      >
                        {i + 1}
                      </button>
                    )
                  })}
                </div>
              </div>
            )}
          </div>
        </div>

        {canEdit && (
          <div className="border-t p-4 bg-muted/20">
            <Button className="w-full" onClick={() => setShowSubmitConfirm(true)} disabled={isBusy}>
              {isBusy ? t("homework.take.submitting") : t("homework.take.submitAll")}
            </Button>
            <p className="mt-2 text-xs text-center text-muted-foreground">
              {t("homework.take.makeSureAnswered")}
            </p>
          </div>
        )}
      </div>

      {/* 提交二次确认对话框 */}
      <AlertDialog open={showSubmitConfirm} onOpenChange={setShowSubmitConfirm}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{t("homework.take.confirmSubmit")}</AlertDialogTitle>
            <AlertDialogDescription>
              {unansweredCount > 0
                ? t("homework.take.unansweredWarning", { count: unansweredCount })
                : t("homework.take.confirmSubmitDescription")}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isBusy}>{t("homework.take.cancel")}</AlertDialogCancel>
            <AlertDialogAction
              disabled={isBusy}
              onClick={(e) => {
                e.preventDefault()
                setShowSubmitConfirm(false)
                void handleSubmit()
              }}
            >
              {isBusy ? t("homework.take.submitting") : t("homework.take.confirmSubmitAction")}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  )
}
