"use client"

import { useEffect, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { useSession } from "next-auth/react"
import { toast } from "sonner"

import { Button } from "@/shared/components/ui/button"
import { Checkbox } from "@/shared/components/ui/checkbox"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/shared/components/ui/dialog"
import { Input } from "@/shared/components/ui/input"
import { Label } from "@/shared/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/shared/components/ui/select"
import { Textarea } from "@/shared/components/ui/textarea"
import { cn } from "@/shared/lib/utils"
import { Permissions } from "@/shared/types/permissions"

type Role = "student" | "teacher" | "parent" | "admin"

const TEACHER_SUBJECTS = ["语文", "数学", "英语", "美术", "体育", "科学", "社会", "音乐"] as const
type TeacherSubject = (typeof TEACHER_SUBJECTS)[number]

function isRecord(v: unknown): v is Record<string, unknown> {
  return typeof v === "object" && v !== null
}

export function OnboardingGate() {
  const router = useRouter()
  const { status, data: session, update } = useSession()
  const [required, setRequired] = useState(false)
  const [open, setOpen] = useState(false)
  const [step, setStep] = useState(0)
  const [isSubmitting, setIsSubmitting] = useState(false)

  const [role, setRole] = useState<Role>("student")
  const [name, setName] = useState("")
  const [phone, setPhone] = useState("")
  const [address, setAddress] = useState("")

  const [classCodes, setClassCodes] = useState("")
  const [teacherSubjects, setTeacherSubjects] = useState<TeacherSubject[]>([])

  const canClose = useMemo(() => !required, [required])

  useEffect(() => {
    if (status !== "authenticated") return
    let cancelled = false
    ;(async () => {
      const res = await fetch("/api/onboarding/status", { cache: "no-store" }).catch(() => null)
      const json = res ? await res.json().catch(() => null) : null
      if (cancelled) return
      if (isRecord(json)) {
        const required = Boolean(json.required)
        const role = String(json.role ?? "student") as Role
        setRequired(required)
        setRole(role === "admin" ? "admin" : role)
        setName(String(session?.user?.name ?? "").trim())
        if (required) {
          setOpen(true)
          setStep(0)
        }
      }
    })()

    return () => {
      cancelled = true
    }
  }, [status, session?.user?.name])

  useEffect(() => {
    if (!open) return
    if (!required) return
    setOpen(true)
  }, [open, required])

  const title =
    step === 0 ? "角色选择" : step === 1 ? "通用信息" : step === 2 ? "角色信息（可跳过）" : "完成"
  const description =
    step === 0
      ? "请选择你在系统中的角色"
      : step === 1
        ? "填写姓名、电话、住址等信息"
        : step === 2
          ? "不同角色可配置班级代码、教学科目等"
          : "配置完成，可以进入系统"

  const canNextFromStep0 = role.length > 0
  const canNextFromStep1 = name.trim().length > 0 && phone.trim().length > 0

  const permissions = (session?.user?.permissions ?? []) as string[]
  const isAdmin = permissions.includes(Permissions.SETTINGS_ADMIN)
  const isTeacher = permissions.includes(Permissions.EXAM_CREATE)
  const isStudent = permissions.includes(Permissions.HOMEWORK_SUBMIT) && !permissions.includes(Permissions.EXAM_CREATE)
  const isParent = !permissions.includes(Permissions.EXAM_CREATE) && !permissions.includes(Permissions.HOMEWORK_SUBMIT) && permissions.includes(Permissions.EXAM_READ)

  const onNext = async () => {
    if (step === 0) {
      if (!canNextFromStep0) return
      setStep(1)
      return
    }
    if (step === 1) {
      if (!canNextFromStep1) {
        toast.error("请填写姓名与电话")
        return
      }
      if (isAdmin) {
        setStep(3)
      } else {
        setStep(2)
      }
      return
    }
    if (step === 2) {
      setStep(3)
      return
    }
  }

  const onBack = () => {
    if (step === 0) return
    setStep((s) => Math.max(0, s - 1))
  }

  const toggleSubject = (subject: TeacherSubject) => {
    setTeacherSubjects((prev) => (prev.includes(subject) ? prev.filter((s) => s !== subject) : [...prev, subject]))
  }

  const onFinish = async () => {
    setIsSubmitting(true)
    try {
      const res = await fetch("/api/onboarding/complete", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          role,
          name,
          phone,
          address,
          classCodes,
          teacherSubjects,
        }),
      })
      const json = await res.json().catch(() => null)
      if (!res.ok || !isRecord(json) || json.success !== true) {
        const msg = isRecord(json) ? String(json.message ?? "") : ""
        throw new Error(msg || "提交失败")
      }

      await update?.()
      toast.success("配置完成")
      setRequired(false)
      setOpen(false)
      router.push("/dashboard")
      router.refresh()
    } catch (e) {
      const msg = e instanceof Error ? e.message : "提交失败"
      toast.error(msg)
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <Dialog
      open={open}
      onOpenChange={(v) => {
        if (canClose) setOpen(v)
        else setOpen(true)
      }}
    >
      <DialogContent className="sm:max-w-[720px]">
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>

        <div className="grid gap-4">
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <div className={cn("h-1 flex-1 rounded", step >= 0 ? "bg-primary" : "bg-muted")} />
            <div className={cn("h-1 flex-1 rounded", step >= 1 ? "bg-primary" : "bg-muted")} />
            <div className={cn("h-1 flex-1 rounded", step >= 2 ? "bg-primary" : "bg-muted")} />
            <div className={cn("h-1 flex-1 rounded", step >= 3 ? "bg-primary" : "bg-muted")} />
          </div>

          {step === 0 ? (
            <div className="grid gap-2">
              <Label>Role</Label>
              {isAdmin ? (
                <div className="rounded-md border px-3 py-2 text-sm">admin</div>
              ) : (
                <Select value={role} onValueChange={(v) => setRole(v as Role)}>
                  <SelectTrigger>
                    <SelectValue placeholder="Select role" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="student">student</SelectItem>
                    <SelectItem value="teacher">teacher</SelectItem>
                    <SelectItem value="parent">parent</SelectItem>
                  </SelectContent>
                </Select>
              )}
            </div>
          ) : null}

          {step === 1 ? (
            <div className="grid gap-4">
              <div className="grid gap-2">
                <Label htmlFor="onb_name">姓名</Label>
                <Input id="onb_name" value={name} onChange={(e) => setName(e.target.value)} />
              </div>
              <div className="grid gap-2">
                <Label htmlFor="onb_phone">电话</Label>
                <Input id="onb_phone" value={phone} onChange={(e) => setPhone(e.target.value)} />
              </div>
              <div className="grid gap-2">
                <Label htmlFor="onb_address">住址</Label>
                <Input id="onb_address" value={address} onChange={(e) => setAddress(e.target.value)} />
              </div>
            </div>
          ) : null}

          {step === 2 ? (
            <div className="grid gap-4">
              {isTeacher ? (
                <>
                  <div className="grid gap-2">
                    <Label htmlFor="onb_codes_teacher">班级代码（可多个）</Label>
                    <Textarea
                      id="onb_codes_teacher"
                      value={classCodes}
                      onChange={(e) => setClassCodes(e.target.value)}
                      placeholder="每行一个或用逗号分隔"
                    />
                  </div>
                  <div className="grid gap-2">
                    <Label>教学科目</Label>
                    <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
                      {TEACHER_SUBJECTS.map((s) => (
                        <label key={s} className="flex items-center gap-2 text-sm">
                          <Checkbox checked={teacherSubjects.includes(s)} onCheckedChange={() => toggleSubject(s)} />
                          {s}
                        </label>
                      ))}
                    </div>
                  </div>
                </>
              ) : null}

              {isStudent ? (
                <div className="grid gap-2">
                  <Label htmlFor="onb_codes_student">班级代码</Label>
                  <Textarea
                    id="onb_codes_student"
                    value={classCodes}
                    onChange={(e) => setClassCodes(e.target.value)}
                    placeholder="每行一个或用逗号分隔"
                  />
                </div>
              ) : null}

              {isParent ? (
                <div className="rounded-md border px-3 py-2 text-sm text-muted-foreground">
                  家长角色暂不需要配置，可跳过
                </div>
              ) : null}
            </div>
          ) : null}

          {step === 3 ? (
            <div className="rounded-md border px-3 py-3 text-sm">
              <div className="font-medium">已准备完成</div>
              <div className="text-muted-foreground">点击完成后进入系统。</div>
            </div>
          ) : null}
        </div>

        <DialogFooter>
          <div className="flex w-full flex-col-reverse gap-2 sm:flex-row sm:justify-between">
            <div className="flex gap-2">
              <Button type="button" variant="outline" onClick={onBack} disabled={step === 0 || isSubmitting}>
                上一步
              </Button>
              {step === 2 ? (
                <Button
                  type="button"
                  variant="secondary"
                  onClick={() => setStep(3)}
                  disabled={isSubmitting}
                >
                  跳过
                </Button>
              ) : null}
            </div>

            <div className="flex gap-2 justify-end">
              {step < 3 ? (
                <Button type="button" onClick={onNext} disabled={isSubmitting}>
                  下一步
                </Button>
              ) : (
                <Button type="button" onClick={onFinish} disabled={isSubmitting}>
                  完成
                </Button>
              )}
            </div>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

