"use client"

import { useMemo, type ReactNode } from "react"
import { useTranslations } from "next-intl"
import { isRecord } from "@/shared/lib/type-guards"
import { cn } from "@/shared/lib/utils"

type ChoiceOption = {
  id: string
  text: string
}

type QuestionLike = {
  questionId: string
  questionType: string
  questionContent: unknown
  maxScore: number
}

type ExamViewerProps = {
  structure: unknown
  questions: QuestionLike[]
  className?: string
  selectedQuestionId?: string | null
  onQuestionSelect?: (questionId: string) => void
}

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

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

export function ExamViewer(props: ExamViewerProps) {
  const { structure, questions, className } = props
  const t = useTranslations("examHomework")
  const questionById = useMemo(() => new Map(questions.map((q) => [q.questionId, q] as const)), [questions])

  const questionNumberById = useMemo(() => {
    const ids: string[] = []

    const visit = (nodes: unknown) => {
      if (!Array.isArray(nodes)) return
      for (const node of nodes) {
        if (!isRecord(node)) continue
        if (node.type === "question") {
          const questionId = typeof node.questionId === "string" ? node.questionId : ""
          if (questionId) ids.push(questionId)
          continue
        }
        if (node.type === "group" || node.type === "section") {
          visit(Array.isArray(node.children) ? node.children : [])
        }
      }
    }

    if (Array.isArray(structure) && structure.length > 0) {
      visit(structure)
    } else {
      for (const q of questions) ids.push(q.questionId)
    }

    const out = new Map<string, number>()
    let n = 0
    for (const id of ids) {
      if (out.has(id)) continue
      n += 1
      out.set(id, n)
    }
    return out
  }, [structure, questions])

  const renderNodes = (rawNodes: unknown, depth: number): ReactNode => {
    if (!Array.isArray(rawNodes)) return null

    return (
      <div className={depth > 0 ? "space-y-4 pl-4 border-l" : "space-y-6"}>
        {rawNodes.map((node, idx) => {
          if (!isRecord(node)) return null
          const type = node.type

          if (type === "section") {
            const title = typeof node.title === "string" && node.title.trim().length > 0 ? node.title : t("exam.viewer.section")
            const children = Array.isArray(node.children) ? node.children : []
            return (
              <div key={`s-${depth}-${idx}`} className="space-y-3">
                <div className="text-lg font-bold border-b-2 border-foreground/30 pb-1">
                  {title}
                </div>
                {renderNodes(children, depth + 1)}
              </div>
            )
          }

          if (type === "group") {
            const title = typeof node.title === "string" && node.title.trim().length > 0 ? node.title : t("exam.viewer.group")
            const instruction = typeof node.instruction === "string" && node.instruction.trim().length > 0 ? node.instruction : null
            const children = Array.isArray(node.children) ? node.children : []
            return (
              <div key={`g-${depth}-${idx}`} className="space-y-3">
                <div className={depth === 0 ? "text-base font-semibold" : "text-sm font-semibold text-muted-foreground"}>
                  {title}
                  {instruction && <span className="ml-2 text-xs font-normal text-muted-foreground italic">{instruction}</span>}
                </div>
                {renderNodes(children, depth + 1)}
              </div>
            )
          }

          if (type === "question") {
            const questionId = typeof node.questionId === "string" ? node.questionId : ""
            if (!questionId) return null
            const questionNumber = questionNumberById.get(questionId) ?? 0
            const q = questionById.get(questionId) ?? null
            const text = getQuestionText(q?.questionContent ?? null)
            const options = getOptions(q?.questionContent ?? null)
            const scoreFromStructure = typeof node.score === "number" ? node.score : null
            const maxScore = scoreFromStructure ?? q?.maxScore ?? 0
            const isSelected = props.selectedQuestionId === questionId
            const isClickable = typeof props.onQuestionSelect === "function"

            return (
              <div
                key={`q-${questionId}`}
                className={cn(
                  "rounded-md border bg-card p-4",
                  isClickable && "cursor-pointer hover:bg-muted/30 transition-colors",
                  isSelected && "ring-2 ring-primary/30"
                )}
                role={isClickable ? "button" : undefined}
                tabIndex={isClickable ? 0 : undefined}
                onClick={isClickable ? () => props.onQuestionSelect?.(questionId) : undefined}
                onKeyDown={
                  isClickable
                    ? (e) => {
                        if (e.key === "Enter" || e.key === " ") {
                          e.preventDefault()
                          props.onQuestionSelect?.(questionId)
                        }
                      }
                    : undefined
                }
              >
                <div className="flex gap-3 min-w-0">
                  <div className="font-semibold tabular-nums">{questionNumber > 0 ? `${questionNumber}.` : "—"}</div>
                  <div className="min-w-0">
                    <div className="whitespace-pre-wrap text-sm">{text || "—"}</div>
                    <div className="mt-2 text-xs text-muted-foreground">
                      <span className="capitalize">{q?.questionType ?? t("exam.viewer.unknown")}</span>
                      <span className="mx-2">•</span>
                      <span>{t("exam.viewer.scoreLabel", { score: maxScore })}</span>
                    </div>
                  </div>
                </div>

                {(q?.questionType === "single_choice" || q?.questionType === "multiple_choice") && options.length > 0 ? (
                  <div className="mt-4 grid grid-cols-1 gap-2 md:grid-cols-2">
                    {options.map((opt) => (
                      <div key={opt.id} className="flex gap-2 text-sm text-muted-foreground">
                        <span className="font-medium">{opt.id}.</span>
                        <span className="whitespace-pre-wrap">{opt.text}</span>
                      </div>
                    ))}
                  </div>
                ) : null}
              </div>
            )
          }

          return null
        })}
      </div>
    )
  }

  if (Array.isArray(structure) && structure.length > 0) {
    return <div className={className}>{renderNodes(structure, 0)}</div>
  }

  if (questions.length > 0) {
    const flatNodes = questions.map((q) => ({ type: "question", questionId: q.questionId, score: q.maxScore }))
    return <div className={className}>{renderNodes(flatNodes, 0)}</div>
  }

  return <div className={className ?? "text-sm text-muted-foreground"}>{t("exam.viewer.noQuestions")}</div>
}
