"use client"

import { useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { toast } from "sonner"
import { RadioGroup, RadioGroupItem } from "@/shared/components/ui/radio-group"

import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/shared/components/ui/card"
import { Checkbox } from "@/shared/components/ui/checkbox"
import { Label } from "@/shared/components/ui/label"
import { Textarea } from "@/shared/components/ui/textarea"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { Clock, CheckCircle2, Save, FileText } from "lucide-react"

import type { StudentHomeworkTakeData } from "../types"
import { saveHomeworkAnswerAction, startHomeworkSubmissionAction, submitHomeworkAction } from "../actions"

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

type Option = { id: string; text: string }

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

const getOptions = (content: unknown): Option[] => {
  if (!isRecord(content)) return []
  const raw = content.options
  if (!Array.isArray(raw)) return []
  const out: Option[] = []
  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
    out.push({ id, text })
  }
  return out
}

const toAnswerShape = (questionType: string, v: unknown) => {
  if (questionType === "text") return { answer: typeof v === "string" ? v : "" }
  if (questionType === "judgment") return { answer: typeof v === "boolean" ? v : false }
  if (questionType === "single_choice") return { answer: typeof v === "string" ? v : "" }
  if (questionType === "multiple_choice") return { answer: Array.isArray(v) ? v.filter((x): x is string => typeof x === "string") : [] }
  return { answer: v }
}

const parseSavedAnswer = (saved: unknown, questionType: string) => {
  if (isRecord(saved) && "answer" in saved) return toAnswerShape(questionType, saved.answer)
  return toAnswerShape(questionType, saved)
}

type HomeworkTakeViewProps = {
  assignmentId: string
  initialData: StudentHomeworkTakeData
}

export function HomeworkTakeView({ assignmentId, initialData }: HomeworkTakeViewProps) {
  const router = useRouter()
  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 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"

  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("Started")
      router.refresh()
    } else {
      toast.error(res.message || "Failed to start")
    }
    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("Saved")
    else toast.error(res.message || "Failed to save")
    // setIsBusy(false)
  }

  const handleSubmit = async () => {
    if (!submissionId) return
    setIsBusy(true)
    // Save all first
    for (const q of initialData.questions) {
      const payload = answersByQuestionId[q.questionId]?.answer ?? null
      const fd = new FormData()
      fd.set("submissionId", submissionId)
      fd.set("questionId", q.questionId)
      fd.set("answerJson", JSON.stringify({ answer: payload }))
      const res = await saveHomeworkAnswerAction(null, fd)
      if (!res.success) {
        toast.error(res.message || "Failed to save")
        setIsBusy(false)
        return
      }
    }

    const submitFd = new FormData()
    submitFd.set("submissionId", submissionId)
    const submitRes = await submitHomeworkAction(null, submitFd)
    if (submitRes.success) {
      toast.success("Submitted")
      setSubmissionStatus("submitted")
      router.push("/student/learning/assignments")
    } else {
      toast.error(submitRes.message || "Failed to submit")
    }
    setIsBusy(false)
  }

  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">
            <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">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" ? "Not Started" : submissionStatus}
                </Badge>
                <span>•</span>
                <span>{initialData.questions.length} Questions</span>
              </div>
            </div>
          </div>
          
          {!canEdit ? (
            <Button onClick={handleStart} disabled={isBusy} size="sm">
              {isBusy ? "Starting..." : "Start Assignment"}
            </Button>
          ) : (
            <div className="flex items-center gap-2">
              <span className="text-xs text-muted-foreground hidden sm:inline-block">
                Auto-saving enabled
              </span>
              <Button onClick={handleSubmit} disabled={isBusy} size="sm">
                <CheckCircle2 className="mr-2 h-4 w-4" />
                {isBusy ? "Submitting..." : "Submit Assignment"}
              </Button>
            </div>
          )}
        </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">Ready to start?</h3>
                <p className="text-muted-foreground max-w-sm mt-2 mb-6">
                  Click the &quot;Start Assignment&quot; button above to begin. The timer will start once you confirm.
                </p>
                <Button onClick={handleStart} disabled={isBusy}>
                  Start Now
                </Button>
              </div>
            )}

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

              return (
                <Card key={q.questionId} className="border-l-4 border-l-primary shadow-sm">
                  <CardHeader className="pb-2">
                    <div className="flex items-start justify-between gap-4">
                      <div className="space-y-1">
                        <CardTitle className="text-base font-medium">
                          Question {idx + 1}
                        </CardTitle>
                        <CardDescription className="text-xs">
                          {q.questionType.replace("_", " ").replace(/\b\w/g, l => l.toUpperCase())} • {q.maxScore} points
                        </CardDescription>
                      </div>
                    </div>
                  </CardHeader>
                  <CardContent className="space-y-4">
                    <div className="text-sm font-medium leading-relaxed">{text || "—"}</div>

                    {q.questionType === "text" ? (
                      <div className="grid gap-2">
                        <Label className="sr-only">Your answer</Label>
                        <Textarea
                          placeholder="Type your answer here..."
                          value={typeof value === "string" ? value : ""}
                          onChange={(e) =>
                            setAnswersByQuestionId((prev) => ({
                              ...prev,
                              [q.questionId]: { answer: e.target.value },
                            }))
                          }
                          className="min-h-[120px] resize-y"
                          disabled={!canEdit}
                        />
                      </div>
                    ) : q.questionType === "judgment" ? (
                      <div className="grid gap-2">
                        <RadioGroup
                          value={typeof value === "boolean" ? (value ? "true" : "false") : ""}
                          onValueChange={(v) =>
                            setAnswersByQuestionId((prev) => ({
                              ...prev,
                              [q.questionId]: { answer: v === "true" },
                            }))
                          }
                          disabled={!canEdit}
                          className="flex flex-col gap-2"
                        >
                          <div className="flex items-center space-x-2 rounded-md border p-3 hover:bg-muted/50 transition-colors">
                            <RadioGroupItem value="true" id={`${q.questionId}-true`} />
                            <Label htmlFor={`${q.questionId}-true`} className="flex-1 cursor-pointer font-normal">True</Label>
                          </div>
                          <div className="flex items-center space-x-2 rounded-md border p-3 hover:bg-muted/50 transition-colors">
                            <RadioGroupItem value="false" id={`${q.questionId}-false`} />
                            <Label htmlFor={`${q.questionId}-false`} className="flex-1 cursor-pointer font-normal">False</Label>
                          </div>
                        </RadioGroup>
                      </div>
                    ) : q.questionType === "single_choice" ? (
                      <div className="grid gap-2">
                        <RadioGroup
                          value={typeof value === "string" ? value : ""}
                          onValueChange={(v) =>
                            setAnswersByQuestionId((prev) => ({
                              ...prev,
                              [q.questionId]: { answer: v },
                            }))
                          }
                          disabled={!canEdit}
                          className="flex flex-col gap-2"
                        >
                          {options.map((o) => (
                            <div key={o.id} className="flex items-center space-x-2 rounded-md border p-3 hover:bg-muted/50 transition-colors">
                              <RadioGroupItem value={o.id} id={`${q.questionId}-${o.id}`} />
                              <Label htmlFor={`${q.questionId}-${o.id}`} className="flex-1 cursor-pointer font-normal">
                                {o.text}
                              </Label>
                            </div>
                          ))}
                        </RadioGroup>
                      </div>
                    ) : q.questionType === "multiple_choice" ? (
                      <div className="grid gap-2">
                        <div className="flex flex-col gap-2">
                          {options.map((o) => {
                            const selected = Array.isArray(value) ? value.includes(o.id) : false
                            return (
                              <div key={o.id} className="flex items-start space-x-2 rounded-md border p-3 hover:bg-muted/50 transition-colors">
                                <Checkbox
                                  id={`${q.questionId}-${o.id}`}
                                  checked={selected}
                                  onCheckedChange={(checked) => {
                                    const isChecked = checked === true
                                    setAnswersByQuestionId((prev) => {
                                      const current = Array.isArray(prev[q.questionId]?.answer)
                                        ? (prev[q.questionId]?.answer as string[])
                                        : []
                                      const next = isChecked
                                        ? Array.from(new Set([...current, o.id]))
                                        : current.filter((x) => x !== o.id)
                                      return { ...prev, [q.questionId]: { answer: next } }
                                    })
                                  }}
                                  disabled={!canEdit}
                                />
                                <Label htmlFor={`${q.questionId}-${o.id}`} className="flex-1 cursor-pointer font-normal leading-normal">
                                  {o.text}
                                </Label>
                              </div>
                            )
                          })}
                        </div>
                      </div>
                    ) : (
                      <div className="text-sm text-muted-foreground italic">Unsupported question type</div>
                    )}

                    {submissionStatus === "graded" && (
                      <div className="mt-6 rounded-md bg-muted/40 p-4 border border-border/50">
                        {q.feedback ? (
                          <div className="text-sm space-y-1">
                            <div className="font-medium text-foreground">Teacher Feedback</div>
                            <div className="text-muted-foreground bg-background p-2 rounded border border-border/50">
                              {q.feedback}
                            </div>
                          </div>
                        ) : (
                          <div className="text-sm text-muted-foreground italic">No specific feedback provided.</div>
                        )}
                      </div>
                    )}

                    {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" />
                          Save Answer
                        </Button>
                      </div>
                    ) : null}
                  </CardContent>
                </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">Assignment Info</h3>
        </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">Status</Label>
              <div className="mt-1 flex items-center gap-2">
                <Badge variant={submissionStatus === "started" ? "default" : "outline"} className="capitalize">
                  {submissionStatus === "not_started" ? "not started" : submissionStatus}
                </Badge>
              </div>
            </div>
            
            <div>
              <Label className="text-xs text-muted-foreground uppercase tracking-wider">Description</Label>
              <p className="mt-1 text-sm text-muted-foreground leading-relaxed">
                {initialData.assignment.description || "No description provided."}
              </p>
            </div>

            {showQuestions && (
              <div>
                <Label className="text-xs text-muted-foreground uppercase tracking-wider">Progress</Label>
                <div className="mt-2 grid grid-cols-5 gap-2">
                  {initialData.questions.map((q, i) => {
                    const hasAnswer = answersByQuestionId[q.questionId]?.answer !== undefined && 
                                    answersByQuestionId[q.questionId]?.answer !== "" &&
                                    (Array.isArray(answersByQuestionId[q.questionId]?.answer) ? (answersByQuestionId[q.questionId]?.answer as unknown[]).length > 0 : true)
                    
                    return (
                      <div 
                        key={q.questionId}
                        className={`
                          h-8 w-8 rounded flex items-center justify-center text-xs font-medium border
                          ${hasAnswer ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground border-input"}
                        `}
                      >
                        {i + 1}
                      </div>
                    )
                  })}
                </div>
              </div>
            )}
          </div>
        </div>
        
        {canEdit && (
          <div className="border-t p-4 bg-muted/20">
            <Button className="w-full" onClick={handleSubmit} disabled={isBusy}>
              {isBusy ? "Submitting..." : "Submit All"}
            </Button>
            <p className="mt-2 text-xs text-center text-muted-foreground">
              Make sure you have answered all questions.
            </p>
          </div>
        )}
      </div>
    </div>
  )
}
