"use client"

import { useState, useEffect } from "react"
import { useTranslations } from "next-intl"
import { useForm, type SubmitHandler } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { z } from "zod"
import { useRouter } from "next/navigation"

import { Button } from "@/shared/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/shared/components/ui/dialog"
import { Form } from "@/shared/components/ui/form"
import { SelectField } from "@/shared/components/form-fields/select-field"
import { TextareaField } from "@/shared/components/form-fields/textarea-field"
import { BaseQuestionSchema } from "../schema"
import { createQuestionAction, updateQuestionAction } from "../actions"
import { toast } from "sonner"
import type { Question } from "../types"
import {
  parseQuestionContent,
  getQuestionOptions,
  type QuestionOption,
} from "../utils/parse-content"
import { KnowledgePointSelector } from "./knowledge-point-selector"
import { OptionsEditor, type QuestionOptionInput } from "./options-editor"

const QuestionFormSchema = BaseQuestionSchema.extend({
  difficulty: z.number().min(1).max(5),
  content: z.string().min(1, "Question content is required"),
  options: z
    .array(
      z.object({
        label: z.string(),
        value: z.string(),
        isCorrect: z.boolean(),
      })
    )
    .optional(),
})

type QuestionFormValues = z.input<typeof QuestionFormSchema>

interface CreateQuestionDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  initialData?: Question | null
  defaultKnowledgePointIds?: string[]
  defaultContent?: string
  defaultType?: "single_choice" | "multiple_choice" | "text" | "judgment" | "composite"
}

/**
 * 将 QuestionOption[] 转换为 QuestionOptionInput[]（表单格式）。
 */
function optionsToFormInput(options: QuestionOption[] | undefined): QuestionOptionInput[] {
  if (!options || options.length === 0) {
    return [
      { label: "Option A", value: "A", isCorrect: true },
      { label: "Option B", value: "B", isCorrect: false },
    ]
  }
  return options.map((opt) => ({
    label: opt.text,
    value: opt.id,
    isCorrect: opt.isCorrect,
  }))
}

export function CreateQuestionDialog({
  open,
  onOpenChange,
  initialData,
  defaultKnowledgePointIds = [],
  defaultContent = "",
  defaultType = "single_choice",
}: CreateQuestionDialogProps): React.ReactNode {
  const t = useTranslations("questions")
  const router = useRouter()
  const [isPending, setIsPending] = useState(false)
  const isEdit = !!initialData
  const [selectedKnowledgePointIds, setSelectedKnowledgePointIds] = useState<string[]>([])

  const form = useForm<QuestionFormValues>({
    resolver: zodResolver(QuestionFormSchema),
    defaultValues: {
      type: initialData?.type || defaultType,
      difficulty: initialData?.difficulty || 1,
      content: parseQuestionContent(initialData?.content).text || defaultContent,
      options: optionsToFormInput(getQuestionOptions(initialData?.content)),
    },
  })

  useEffect(() => {
    if (initialData) {
      const parsed = parseQuestionContent(initialData.content)
      form.reset({
        type: initialData.type,
        difficulty: initialData.difficulty,
        content: parsed.text,
        options: optionsToFormInput(parsed.options),
      })
    } else {
      form.reset({
        type: defaultType,
        difficulty: 1,
        content: defaultContent,
        options: [
          { label: "Option A", value: "A", isCorrect: true },
          { label: "Option B", value: "B", isCorrect: false },
        ],
      })
    }
  }, [initialData, form, open, defaultContent, defaultType])

  useEffect(() => {
    if (!open) return
    if (initialData) {
      setSelectedKnowledgePointIds(initialData.knowledgePoints.map((kp) => kp.id))
      return
    }
    setSelectedKnowledgePointIds(defaultKnowledgePointIds)
  }, [open, initialData, defaultKnowledgePointIds])

  const questionType = form.watch("type")
  const formOptions = form.watch("options") ?? []

  const buildContent = (data: QuestionFormValues): unknown => {
    const text = data.content.trim()
    if (data.type === "single_choice" || data.type === "multiple_choice") {
      const rawOptions = (data.options ?? []).filter((o) => o.label.trim().length > 0)
      const base = rawOptions.map((o) => ({
        id: o.value,
        text: o.label.trim(),
        isCorrect: o.isCorrect,
      }))

      if (base.length === 0) return { text }

      if (data.type === "single_choice") {
        let selectedIndex = base.findIndex((o) => o.isCorrect)
        if (selectedIndex === -1) selectedIndex = 0
        return {
          text,
          options: base.map((o, idx) => ({ ...o, isCorrect: idx === selectedIndex })),
        }
      }

      const hasCorrect = base.some((o) => o.isCorrect)
      const options = hasCorrect ? base : [{ ...base[0], isCorrect: true }, ...base.slice(1)]
      return { text, options }
    }

    return { text }
  }

  const onSubmit: SubmitHandler<QuestionFormValues> = async (data) => {
    setIsPending(true)
    try {
      if (isEdit && !initialData?.id) {
        toast.error(t("error.missingId"))
        return
      }
      const payload = {
        ...(isEdit && initialData ? { id: initialData.id } : {}),
        type: data.type,
        difficulty: data.difficulty,
        content: buildContent(data),
        knowledgePointIds: selectedKnowledgePointIds,
      }
      const fd = new FormData()
      fd.set("json", JSON.stringify(payload))
      const res = isEdit
        ? await updateQuestionAction(undefined, fd)
        : await createQuestionAction(undefined, fd)
      if (res.success) {
        toast.success(isEdit ? t("error.updatedSuccess") : t("error.createdSuccess"))
        onOpenChange(false)
        router.refresh()
        if (!isEdit) {
          form.reset()
        }
      } else {
        toast.error(res.message || t("error.operationFailed"))
      }
    } catch (e) {
      console.error("Failed to submit question", e)
      toast.error(t("error.unexpected"))
    } finally {
      setIsPending(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px] max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>{isEdit ? t("dialog.editTitle") : t("dialog.createTitle")}</DialogTitle>
          <DialogDescription>
            {isEdit ? t("dialog.editDesc") : t("dialog.createDesc")}
          </DialogDescription>
        </DialogHeader>

        <Form {...form}>
          <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
            <div className="grid grid-cols-2 gap-4">
              <SelectField
                control={form.control}
                name="type"
                label={t("dialog.questionType")}
                placeholder={t("dialog.selectType")}
                options={[
                  { value: "single_choice", label: t("type.single_choice") },
                  { value: "multiple_choice", label: t("type.multiple_choice") },
                  { value: "judgment", label: t("type.judgment") },
                  { value: "text", label: t("type.text") },
                  { value: "composite", label: t("type.composite") },
                ]}
              />
              <SelectField
                control={form.control}
                name="difficulty"
                label={t("dialog.difficulty")}
                placeholder={t("dialog.selectDifficulty")}
                toSelectValue={(v) => String(v)}
                fromSelectValue={(val) => {
                  const n = parseInt(val, 10)
                  return Number.isFinite(n) ? n : 1
                }}
                options={[1, 2, 3, 4, 5].map((level) => ({
                  value: String(level),
                  label: `${level} - ${t(`difficulty.${level}`)}`,
                }))}
              />
            </div>

            <TextareaField
              control={form.control}
              name="content"
              label={t("dialog.questionContent")}
              placeholder={t("dialog.contentPlaceholder")}
              description={t("dialog.contentDescription")}
              textareaClassName="min-h-[100px]"
            />

            <KnowledgePointSelector
              selectedIds={selectedKnowledgePointIds}
              onChange={setSelectedKnowledgePointIds}
            />

            {(questionType === "single_choice" || questionType === "multiple_choice") && (
              <OptionsEditor
                options={formOptions}
                onChange={(next) => form.setValue("options", next)}
                singleChoice={questionType === "single_choice"}
              />
            )}

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
                {t("dialog.cancel")}
              </Button>
              <Button type="submit" disabled={isPending}>
                {isPending
                  ? (isEdit ? t("dialog.updating") : t("dialog.creating"))
                  : (isEdit ? t("dialog.update") : t("dialog.create"))}
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  )
}
