"use client"

import * as React from "react"
import { useTranslations } from "next-intl"
import { toast } from "sonner"
import { Copy, Hash, Mail, GraduationCap, Clock, FileText } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { Input } from "@/shared/components/ui/input"
import { Label } from "@/shared/components/ui/label"
import { Textarea } from "@/shared/components/ui/textarea"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/components/ui/select"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/shared/components/ui/dialog"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { useActionMutation } from "@/shared/hooks/use-action-mutation"

import { generateInvitationCodesAction } from "../actions"
import { INVITATION_ROLE_VALUES } from "../schema"
import type { InvitationCodeRecord, InvitationRole } from "../types"

/**
 * 生成邀请码对话框（audit-P2-3 新增）。
 *
 * 流程：
 * 1. 用户填写表单（数量、角色、可选邮箱/班级/过期/备注）
 * 2. 提交调用 generateInvitationCodesAction
 * 3. 成功后切换到「生成结果」视图，展示明文邀请码供复制
 * 4. 关闭对话框时通过 onGenerated 回调通知父组件刷新
 *
 * 设计：
 * - 单对话框内两个状态（form / result），避免叠加多个 Dialog
 * - result 视图仅此一次展示明文，关闭后无法再获取
 */
interface GenerateInvitationCodesDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  onGenerated: () => void
}

type ViewState = "form" | "result"

export function GenerateInvitationCodesDialog({
  open,
  onOpenChange,
  onGenerated,
}: GenerateInvitationCodesDialogProps) {
  const t = useTranslations("invitationCodes")
  const [view, setView] = React.useState<ViewState>("form")
  const [generatedCodes, setGeneratedCodes] = React.useState<InvitationCodeRecord[]>([])
  const [batchId, setBatchId] = React.useState<string>("")

  // 表单状态
  const [count, setCount] = React.useState("10")
  const [role, setRole] = React.useState<InvitationRole>("student")
  const [email, setEmail] = React.useState("")
  const [classId, setClassId] = React.useState("")
  const [expiresAt, setExpiresAt] = React.useState("")
  const [notes, setNotes] = React.useState("")

  const generateMutation = useActionMutation<{ codes: InvitationCodeRecord[]; batchId: string }>({
    successMessage: false,
    errorMessage: t("generate.failed"),
    onSuccess: (data) => {
      if (data) {
        setGeneratedCodes(data.codes)
        setBatchId(data.batchId)
        setView("result")
        toast.success(t("generate.success", { count: data.codes.length }))
      }
    },
  })

  // 对话框关闭时重置状态
  const handleOpenChange = (nextOpen: boolean): void => {
    if (!nextOpen) {
      // 关闭前若已生成，通知父组件刷新
      if (view === "result") {
        onGenerated()
      }
      // 延迟重置以便关闭动画完成
      setTimeout(() => {
        setView("form")
        setGeneratedCodes([])
        setBatchId("")
      }, 200)
    }
    onOpenChange(nextOpen)
  }

  const handleSubmit = (e: React.FormEvent): void => {
    e.preventDefault()
    // datetime-local 输入无时区后缀，需转为 ISO 8601（UTC）以通过 schema 校验
    const normalizedExpiry = expiresAt
      ? new Date(expiresAt).toISOString()
      : undefined
    void generateMutation.mutate(() =>
      generateInvitationCodesAction({
        count: Number(count),
        role,
        email,
        classId,
        expiresAt: normalizedExpiry,
        notes,
      }),
    )
  }

  const handleCopyAll = async (): Promise<void> => {
    const text = generatedCodes.map((c) => c.code).join("\n")
    try {
      await navigator.clipboard.writeText(text)
      toast.success(t("actions.copied"))
    } catch {
      toast.error(t("actions.copyFailed"))
    }
  }

  const handleCopyOne = async (code: string): Promise<void> => {
    try {
      await navigator.clipboard.writeText(code)
      toast.success(t("actions.copied"))
    } catch {
      toast.error(t("actions.copyFailed"))
    }
  }

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="max-h-[90vh] max-w-2xl overflow-hidden">
        {view === "form" ? (
          <GenerateForm
            t={t}
            count={count}
            setCount={setCount}
            role={role}
            setRole={setRole}
            email={email}
            setEmail={setEmail}
            classId={classId}
            setClassId={setClassId}
            expiresAt={expiresAt}
            setExpiresAt={setExpiresAt}
            notes={notes}
            setNotes={setNotes}
            isSubmitting={generateMutation.isWorking}
            onSubmit={handleSubmit}
            onCancel={() => onOpenChange(false)}
          />
        ) : (
          <GenerateResult
            t={t}
            codes={generatedCodes}
            batchId={batchId}
            onCopyOne={handleCopyOne}
            onCopyAll={handleCopyAll}
            onClose={() => onOpenChange(false)}
          />
        )}
      </DialogContent>
    </Dialog>
  )
}

interface GenerateFormProps {
  t: ReturnType<typeof useTranslations>
  count: string
  setCount: (v: string) => void
  role: InvitationRole
  setRole: (v: InvitationRole) => void
  email: string
  setEmail: (v: string) => void
  classId: string
  setClassId: (v: string) => void
  expiresAt: string
  setExpiresAt: (v: string) => void
  notes: string
  setNotes: (v: string) => void
  isSubmitting: boolean
  onSubmit: (e: React.FormEvent) => void
  onCancel: () => void
}

function GenerateForm({
  t,
  count,
  setCount,
  role,
  setRole,
  email,
  setEmail,
  classId,
  setClassId,
  expiresAt,
  setExpiresAt,
  notes,
  setNotes,
  isSubmitting,
  onSubmit,
  onCancel,
}: GenerateFormProps) {
  return (
    <>
      <DialogHeader>
        <DialogTitle>{t("generate.title")}</DialogTitle>
        <DialogDescription>{t("generate.description")}</DialogDescription>
      </DialogHeader>
      <form onSubmit={onSubmit} className="grid gap-4">
        <div className="grid gap-2">
          <Label htmlFor="count" className="flex items-center gap-1.5">
            <Hash className="h-3.5 w-3.5" />
            {t("generate.count")}
          </Label>
          <Input
            id="count"
            type="number"
            min="1"
            max="100"
            value={count}
            onChange={(e) => setCount(e.target.value)}
            required
          />
          <p className="text-xs text-muted-foreground">{t("generate.countDescription")}</p>
        </div>

        <div className="grid gap-2">
          <Label htmlFor="role">{t("generate.role")}</Label>
          <Select
            value={role}
            onValueChange={(v) => setRole(v as InvitationRole)}
          >
            <SelectTrigger id="role">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {INVITATION_ROLE_VALUES.map((r) => (
                <SelectItem key={r} value={r}>
                  {t(`roles.${r}`)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <div className="grid gap-2">
          <Label htmlFor="email" className="flex items-center gap-1.5">
            <Mail className="h-3.5 w-3.5" />
            {t("generate.email")}
          </Label>
          <Input
            id="email"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="user@example.com"
          />
          <p className="text-xs text-muted-foreground">{t("generate.emailDescription")}</p>
        </div>

        <div className="grid gap-2">
          <Label htmlFor="classId" className="flex items-center gap-1.5">
            <GraduationCap className="h-3.5 w-3.5" />
            {t("generate.classId")}
          </Label>
          <Input
            id="classId"
            value={classId}
            onChange={(e) => setClassId(e.target.value)}
            placeholder="cls_xxxxxxxx"
          />
          <p className="text-xs text-muted-foreground">{t("generate.classIdDescription")}</p>
        </div>

        <div className="grid gap-2">
          <Label htmlFor="expiresAt" className="flex items-center gap-1.5">
            <Clock className="h-3.5 w-3.5" />
            {t("generate.expiresAt")}
          </Label>
          <Input
            id="expiresAt"
            type="datetime-local"
            value={expiresAt}
            onChange={(e) => setExpiresAt(e.target.value)}
          />
          <p className="text-xs text-muted-foreground">{t("generate.expiresAtDescription")}</p>
        </div>

        <div className="grid gap-2">
          <Label htmlFor="notes" className="flex items-center gap-1.5">
            <FileText className="h-3.5 w-3.5" />
            {t("generate.notes")}
          </Label>
          <Textarea
            id="notes"
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            maxLength={500}
            rows={2}
          />
          <p className="text-xs text-muted-foreground">{t("generate.notesDescription")}</p>
        </div>

        <DialogFooter>
          <Button type="button" variant="outline" onClick={onCancel} disabled={isSubmitting}>
            {t("actions.cancel")}
          </Button>
          <Button type="submit" disabled={isSubmitting}>
            {isSubmitting ? t("generate.generating") : t("generate.submit")}
          </Button>
        </DialogFooter>
      </form>
    </>
  )
}

interface GenerateResultProps {
  t: ReturnType<typeof useTranslations>
  codes: InvitationCodeRecord[]
  batchId: string
  onCopyOne: (code: string) => void
  onCopyAll: () => void
  onClose: () => void
}

function GenerateResult({
  t,
  codes,
  batchId,
  onCopyOne,
  onCopyAll,
  onClose,
}: GenerateResultProps) {
  return (
    <>
      <DialogHeader>
        <DialogTitle>{t("generatedList.title")}</DialogTitle>
        <DialogDescription>{t("generatedList.description")}</DialogDescription>
      </DialogHeader>
      <div className="space-y-3">
        <div className="flex items-center justify-between rounded-md bg-muted px-3 py-2">
          <span className="text-xs text-muted-foreground">
            {t("generatedList.batchId")}：<code className="ml-1 font-mono">{batchId}</code>
          </span>
          <Button size="sm" variant="outline" onClick={onCopyAll}>
            <Copy className="mr-1.5 h-3.5 w-3.5" />
            {t("generatedList.copyAll")}
          </Button>
        </div>
        <ScrollArea className="h-[40vh] rounded-md border">
          <div className="divide-y">
            {codes.map((record) => (
              <div
                key={record.id}
                className="flex items-center justify-between px-3 py-2 hover:bg-muted/50"
              >
                <code className="font-mono text-sm font-medium tracking-wider">
                  {record.code}
                </code>
                <Button
                  size="icon"
                  variant="ghost"
                  onClick={() => onCopyOne(record.code)}
                  aria-label={t("actions.copy")}
                >
                  <Copy className="h-3.5 w-3.5" />
                </Button>
              </div>
            ))}
          </div>
        </ScrollArea>
      </div>
      <DialogFooter>
        <Button onClick={onClose}>{t("generatedList.close")}</Button>
      </DialogFooter>
    </>
  )
}
