"use client"

import * as React from "react"
import { useRouter } from "next/navigation"
import { useTranslations } from "next-intl"
import { TicketPlus, Copy, Trash2, CheckCircle2, XCircle, Clock } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { Card, CardContent } from "@/shared/components/ui/card"
import { Badge } from "@/shared/components/ui/badge"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/shared/components/ui/table"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/shared/components/ui/alert-dialog"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { StatCard } from "@/shared/components/ui/stat-card"
import { useActionMutation } from "@/shared/hooks/use-action-mutation"
import { formatDateTime } from "@/shared/lib/utils"
import { toast } from "sonner"

import { deleteInvitationCodeAction } from "../actions"
import type { InvitationCodeRecord, InvitationRole } from "../types"
import { GenerateInvitationCodesDialog } from "./generate-invitation-codes-dialog"

/**
 * 邀请码管理视图（audit-P2-3 新增）。
 *
 * 由 admin/invitation-codes/page.tsx 的 Server Component 通过
 * listInvitationCodesAction 获取初始数据后注入，避免本组件内部直接调用
 * Server Action 影响首屏 SSR。后续生成/删除通过 router.refresh() 触发
 * 服务端重新渲染并更新 initialCodes。
 *
 * `now` 由 Server Component 计算后传入，避免在 Client render 阶段调用
 * Date.now()（react-hooks/purity 规则）。
 */
interface InvitationCodesViewProps {
  initialCodes: InvitationCodeRecord[]
  /** Server Component 计算的「当前时间戳」（ms），用于过期判断 */
  now: number
}

const ROLE_LABEL_KEYS: Record<InvitationRole, string> = {
  student: "roles.student",
  teacher: "roles.teacher",
  parent: "roles.parent",
  admin: "roles.admin",
}

export function InvitationCodesView({ initialCodes, now }: InvitationCodesViewProps) {
  const router = useRouter()
  const t = useTranslations("invitationCodes")
  const [isGenerateOpen, setIsGenerateOpen] = React.useState(false)
  const [deleteTarget, setDeleteTarget] = React.useState<InvitationCodeRecord | null>(null)

  // 统计：依赖传入的 now，不调用 Date.now()
  const stats = React.useMemo(() => {
    const used = initialCodes.filter((c) => c.usedBy !== null).length
    const expired = initialCodes.filter(
      (c) => c.usedBy === null && c.expiresAt !== null && c.expiresAt.getTime() < now,
    ).length
    const unused = initialCodes.length - used - expired
    return {
      total: initialCodes.length,
      unused,
      used,
      expired,
    }
  }, [initialCodes, now])

  const deleteMutation = useActionMutation<null>({
    successMessage: t("actions.deleted"),
    onSuccess: () => {
      setDeleteTarget(null)
      router.refresh()
    },
  })

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

  const handleDelete = (): void => {
    if (!deleteTarget) return
    void deleteMutation.mutate(() => deleteInvitationCodeAction(deleteTarget.id))
  }

  const handleGenerated = (): void => {
    setIsGenerateOpen(false)
    router.refresh()
  }

  return (
    <div className="flex h-full flex-col space-y-6 p-8">
      {/* 头部 + 生成按钮 */}
      <div className="flex flex-col justify-between gap-4 md:flex-row md:items-center">
        <div className="space-y-1">
          <div className="flex items-center gap-2">
            <TicketPlus className="h-7 w-7 text-muted-foreground" />
            <h1 className="text-3xl font-bold tracking-tight">{t("title")}</h1>
          </div>
          <p className="text-sm text-muted-foreground">{t("description")}</p>
        </div>
        <Button onClick={() => setIsGenerateOpen(true)}>
          <TicketPlus className="mr-2 h-4 w-4" />
          {t("generate.title")}
        </Button>
      </div>

      {/* 统计卡片 */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <StatCard
          title={t("stats.total")}
          value={stats.total}
          icon={TicketPlus}
        />
        <StatCard
          title={t("stats.unused")}
          value={stats.unused}
          icon={CheckCircle2}
          color="text-emerald-500"
        />
        <StatCard
          title={t("stats.used")}
          value={stats.used}
          icon={XCircle}
          color="text-blue-500"
        />
        <StatCard
          title={t("stats.expired")}
          value={stats.expired}
          icon={Clock}
          color="text-amber-500"
        />
      </div>

      {/* 邀请码表格 */}
      <Card className="shadow-none">
        <CardContent className="pt-6">
          {initialCodes.length === 0 ? (
            <EmptyState
              icon={TicketPlus}
              title={t("empty.title")}
              description={t("empty.description")}
              action={{
                label: t("generate.title"),
                onClick: () => setIsGenerateOpen(true),
                variant: "default",
              }}
            />
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="font-mono">{t("columns.code")}</TableHead>
                  <TableHead>{t("columns.role")}</TableHead>
                  <TableHead>{t("columns.email")}</TableHead>
                  <TableHead>{t("columns.status")}</TableHead>
                  <TableHead>{t("columns.expiresAt")}</TableHead>
                  <TableHead>{t("columns.createdAt")}</TableHead>
                  <TableHead>{t("columns.usedBy")}</TableHead>
                  <TableHead className="text-right">{t("columns.actions")}</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {initialCodes.map((record) => (
                  <InvitationCodeRow
                    key={record.id}
                    record={record}
                    now={now}
                    onCopy={() => handleCopy(record.code)}
                    onDelete={() => setDeleteTarget(record)}
                    roleLabel={t(ROLE_LABEL_KEYS[record.role])}
                    t={t}
                  />
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {/* 生成对话框 */}
      <GenerateInvitationCodesDialog
        open={isGenerateOpen}
        onOpenChange={setIsGenerateOpen}
        onGenerated={handleGenerated}
      />

      {/* 删除确认 */}
      <AlertDialog
        open={!!deleteTarget}
        onOpenChange={(open) => !open && setDeleteTarget(null)}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{t("actions.deleteConfirmTitle")}</AlertDialogTitle>
            <AlertDialogDescription>
              {t("actions.deleteConfirmDescription")}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={deleteMutation.isWorking}>
              {t("actions.cancel")}
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={handleDelete}
              disabled={deleteMutation.isWorking}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              {deleteMutation.isWorking
                ? t("actions.deleting")
                : t("actions.confirmDelete")}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  )
}

interface InvitationCodeRowProps {
  record: InvitationCodeRecord
  now: number
  onCopy: () => void
  onDelete: () => void
  roleLabel: string
  t: ReturnType<typeof useTranslations>
}

function InvitationCodeRow({ record, now, onCopy, onDelete, roleLabel, t }: InvitationCodeRowProps) {
  const isUsed = record.usedBy !== null
  const isExpired =
    !isUsed && record.expiresAt !== null && record.expiresAt.getTime() < now
  const statusKey = isUsed ? "used" : isExpired ? "expired" : "unused"
  const statusVariant = isUsed ? "secondary" : isExpired ? "outline" : "default"

  return (
    <TableRow>
      <TableCell className="font-mono font-medium tracking-wider">
        {record.code}
      </TableCell>
      <TableCell>
        <Badge variant="outline">{roleLabel}</Badge>
      </TableCell>
      <TableCell className="max-w-[180px] truncate text-sm text-muted-foreground">
        {record.email ?? "—"}
      </TableCell>
      <TableCell>
        <Badge variant={statusVariant as "default" | "secondary" | "outline"}>
          {t(`status.${statusKey}`)}
        </Badge>
      </TableCell>
      <TableCell className="text-sm text-muted-foreground">
        {record.expiresAt ? formatDateTime(record.expiresAt) : "—"}
      </TableCell>
      <TableCell className="text-sm text-muted-foreground">
        {formatDateTime(record.createdAt)}
      </TableCell>
      <TableCell className="max-w-[120px] truncate text-sm text-muted-foreground">
        {record.usedBy ?? "—"}
      </TableCell>
      <TableCell className="text-right">
        <div className="flex justify-end gap-1">
          <Button
            variant="ghost"
            size="icon"
            onClick={onCopy}
            aria-label={t("actions.copy")}
          >
            <Copy className="h-4 w-4" />
          </Button>
          {!isUsed && (
            <Button
              variant="ghost"
              size="icon"
              onClick={onDelete}
              aria-label={t("actions.delete")}
            >
              <Trash2 className="h-4 w-4 text-destructive" />
            </Button>
          )}
        </div>
      </TableCell>
    </TableRow>
  )
}
