'use client'

import { ChangeEvent, useEffect, useMemo, useRef, useState } from 'react'
import {
  BadgeCheck,
  Loader2,
  MoreHorizontal,
  Palette,
  Pencil,
  Plus,
  School,
  Search,
  Trash2,
  Upload,
  UserRoundCheck
} from 'lucide-react'

import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { collectPhotos } from '@/lib/certificate-browser'
import {
  DEFAULT_ID_PHOTO_CONFIG,
  ID_PHOTO_BACKGROUND_COLORS,
  ID_PHOTO_SIZE_PRESETS,
  type IdPhotoBackground,
  type IdPhotoSize,
  idPhotoBackgroundColor,
  idPhotoBackgroundLabel,
  idPhotoSizeLabel,
  normalizeMatchName,
  resolveIdPhotoConfig
} from '@/lib/certificate-types'
import {
  type ClassItem,
  type TemplateItem,
  createId,
  ensureClassIdPhotos,
  fileList,
  generateForStudent,
  hydrateClassItem,
  hydrateClassMetadata,
  hydrateTemplate,
  loadAppState,
  persistClasses,
  persistGeneratedCertificate,
  saveAppState,
  studentsFromClassZip
} from '@/lib/certificate-page-utils'
import type { PersistedAppState } from '@/lib/storage-types'
import { cn } from '@/lib/utils'

function navigate(href: string) {
  window.history.pushState(null, '', href)
  window.dispatchEvent(new PopStateEvent('popstate'))
}

export default function ClassesPage() {
  const classZipInputRef = useRef<HTMLInputElement | null>(null)
  const studentPhotoInputRef = useRef<HTMLInputElement | null>(null)
  const [storedState, setStoredState] = useState<PersistedAppState | null>(null)
  const [classes, setClasses] = useState<ClassItem[]>([])
  const [templates, setTemplates] = useState<TemplateItem[]>([])
  const [activeClassId, setActiveClassId] = useState('')
  const [classSearchQuery, setClassSearchQuery] = useState('')
  const [isClassEditorOpen, setIsClassEditorOpen] = useState(false)
  const [editingClassId, setEditingClassId] = useState('')
  const [draftName, setDraftName] = useState('')
  const [draftZipFile, setDraftZipFile] = useState<File | null>(null)
  const [draftIdPhotoConfig, setDraftIdPhotoConfig] = useState(DEFAULT_ID_PHOTO_CONFIG)
  const [openClassMenuId, setOpenClassMenuId] = useState('')
  const [pendingClassZipImportId, setPendingClassZipImportId] = useState('')
  const [pendingStudentPhotoImportId, setPendingStudentPhotoImportId] = useState('')
  const [isWorking, setIsWorking] = useState(false)
  const [generatedCountsByClassId, setGeneratedCountsByClassId] = useState<Record<string, number>>({})
  const loadedClassPhotoIdsRef = useRef(new Set<string>())

  const activeClass = classes.find((classItem) => classItem.id === activeClassId) ?? classes[0]
  const activeTemplate = templates.find((template) => template.id === storedState?.activeTemplateId) ?? templates[0]
  const filteredClasses = useMemo(() => {
    const query = classSearchQuery.trim().toLowerCase()

    if (!query) {
      return classes
    }

    return classes.filter((classItem) => {
      const studentNames = classItem.students.map((student) => student.name).join(' ')
      return [classItem.name, classItem.id, studentNames].some((value) =>
        value.toLowerCase().includes(query)
      )
    })
  }, [classSearchQuery, classes])

  useEffect(() => {
    async function loadClasses() {
      const state = await loadAppState()
      const restoredTemplates = await Promise.all((state.templates ?? []).map(hydrateTemplate))
      const restoredClasses = (state.classes ?? []).map(hydrateClassMetadata)
      const counts = (state.certificates ?? []).reduce<Record<string, number>>((result, certificate) => {
        result[certificate.classId] = (result[certificate.classId] ?? 0) + 1
        return result
      }, {})

      setStoredState(state)
      setTemplates(restoredTemplates)
      setClasses(restoredClasses)
      setActiveClassId(
        restoredClasses.some((classItem) => classItem.id === state.activeClassId)
          ? state.activeClassId
          : restoredClasses[0]?.id ?? ''
      )
      setGeneratedCountsByClassId(counts)
    }

    loadClasses()
  }, [])

  async function persist(nextClasses: ClassItem[], nextActiveClassId = activeClassId, nextState = storedState) {
    if (!nextState) {
      return
    }

    const nextPersistedState: PersistedAppState = {
      ...nextState,
      classes: persistClasses(nextClasses, nextState),
      activeClassId: nextActiveClassId
    }
    await saveAppState(nextPersistedState)
    setStoredState(nextPersistedState)
  }

  async function ensureClassPhotosLoaded(classItem: ClassItem) {
    if (loadedClassPhotoIdsRef.current.has(classItem.id)) {
      return classItem
    }

    const persistedClass = storedState?.classes.find((item) => item.id === classItem.id)

    if (!persistedClass) {
      loadedClassPhotoIdsRef.current.add(classItem.id)
      return classItem
    }

    const hydratedClass = await hydrateClassItem(persistedClass)
    loadedClassPhotoIdsRef.current.add(classItem.id)
    setClasses((current) => current.map((item) => (item.id === hydratedClass.id ? hydratedClass : item)))

    return hydratedClass
  }

  function resetEditor() {
    setEditingClassId('')
    setDraftName('')
    setDraftZipFile(null)
    setDraftIdPhotoConfig(DEFAULT_ID_PHOTO_CONFIG)
    setIsClassEditorOpen(false)
  }

  function openNewClassEditor() {
    setEditingClassId('')
    setDraftName('')
    setDraftZipFile(null)
    setDraftIdPhotoConfig(DEFAULT_ID_PHOTO_CONFIG)
    setIsClassEditorOpen(true)
    setOpenClassMenuId('')
  }

  function openClassEditor(classItem: ClassItem) {
    setEditingClassId(classItem.id)
    setDraftName(classItem.name)
    setDraftZipFile(null)
    setDraftIdPhotoConfig(resolveIdPhotoConfig(classItem.idPhotoConfig))
    setActiveClassId(classItem.id)
    setIsClassEditorOpen(true)
    setOpenClassMenuId('')
  }

  function updateDraftSize(size: IdPhotoSize) {
    setDraftIdPhotoConfig((current) =>
      resolveIdPhotoConfig({
        ...current,
        size,
        ...ID_PHOTO_SIZE_PRESETS[size]
      })
    )
  }

  async function saveClass() {
    const className = draftName.trim()

    if (!className) {
      return
    }

    setIsWorking(true)

    try {
      const zipResult = draftZipFile ? await studentsFromClassZip(draftZipFile) : null
      const idPhotoConfig = resolveIdPhotoConfig(draftIdPhotoConfig)
      let nextActiveClassId = activeClassId
      let nextClasses: ClassItem[]

      if (editingClassId) {
        const editingClass = classes.find((classItem) => classItem.id === editingClassId)
        const hydratedClass = editingClass ? await ensureClassPhotosLoaded(editingClass) : null
        const configChanged =
          resolveIdPhotoConfig(hydratedClass?.idPhotoConfig).background !== idPhotoConfig.background ||
          resolveIdPhotoConfig(hydratedClass?.idPhotoConfig).customColor !== idPhotoConfig.customColor ||
          resolveIdPhotoConfig(hydratedClass?.idPhotoConfig).size !== idPhotoConfig.size
        const updatedClass = hydratedClass
          ? {
            ...hydratedClass,
            name: className,
            idPhotoConfig,
            students: zipResult?.students ?? hydratedClass.students.map((student) => ({
              ...student,
              idPhoto: configChanged ? undefined : student.idPhoto,
              idPhotoFileName: configChanged ? undefined : student.idPhotoFileName
            }))
          }
          : null

        nextClasses = classes.map((classItem) =>
          updatedClass && classItem.id === editingClassId ? updatedClass : classItem
        )
        nextActiveClassId = editingClassId
        loadedClassPhotoIdsRef.current.add(editingClassId)
      } else {
        const nextClass = {
          id: createId('class'),
          name: className,
          idPhotoConfig,
          students: zipResult?.students ?? [],
          createdAt: new Date().toISOString()
        }
        nextClasses = [...classes, nextClass]
        nextActiveClassId = nextClass.id
        loadedClassPhotoIdsRef.current.add(nextClass.id)
      }

      setClasses(nextClasses)
      setActiveClassId(nextActiveClassId)
      await persist(nextClasses, nextActiveClassId)
      resetEditor()
    } finally {
      setIsWorking(false)
    }
  }

  function openClassZipPicker(classId: string) {
    setPendingClassZipImportId(classId)
    setActiveClassId(classId)
    setOpenClassMenuId('')
    classZipInputRef.current?.click()
  }

  function openStudentPhotoPicker(classId: string) {
    setPendingStudentPhotoImportId(classId)
    setActiveClassId(classId)
    setOpenClassMenuId('')
    studentPhotoInputRef.current?.click()
  }

  async function importClassZip(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0]
    const targetClassId = pendingClassZipImportId || activeClass?.id
    const targetClass = classes.find((classItem) => classItem.id === targetClassId)
    event.target.value = ''

    if (!file || !targetClass) {
      return
    }

    setIsWorking(true)

    try {
      const { students } = await studentsFromClassZip(file)
      const nextClass = {
        ...targetClass,
        students
      }
      const nextClasses = classes.map((classItem) =>
        classItem.id === targetClass.id ? nextClass : classItem
      )

      loadedClassPhotoIdsRef.current.add(targetClass.id)
      setClasses(nextClasses)
      await persist(nextClasses, targetClass.id)
    } finally {
      setPendingClassZipImportId('')
      setIsWorking(false)
    }
  }

  async function importStudentPhotos(event: ChangeEvent<HTMLInputElement>) {
    const targetClassId = pendingStudentPhotoImportId || activeClass?.id
    const targetClass = classes.find((classItem) => classItem.id === targetClassId)
    const files = fileList(event.currentTarget)
    event.target.value = ''

    if (!targetClass || files.length === 0) {
      return
    }

    setIsWorking(true)

    try {
      const classWithPhotos = await ensureClassPhotosLoaded(targetClass)
      const imageFiles = files.filter((file) => !/\.zip$/i.test(file.name))
      const zipFiles = files.filter((file) => /\.zip$/i.test(file.name))
      const { photos } = await collectPhotos(imageFiles, zipFiles)
      const nextClass = {
        ...classWithPhotos,
        students: classWithPhotos.students.map((student) => {
          const matchedPhoto = photos.get(normalizeMatchName(student.name))
          return matchedPhoto
            ? {
              ...student,
              photo: matchedPhoto,
              photoFileName: matchedPhoto.fileName,
              idPhoto: undefined,
              idPhotoFileName: undefined
            }
            : student
        })
      }
      const nextClasses = classes.map((classItem) =>
        classItem.id === targetClass.id ? nextClass : classItem
      )

      loadedClassPhotoIdsRef.current.add(targetClass.id)
      setClasses(nextClasses)
      await persist(nextClasses, targetClass.id)
    } finally {
      setPendingStudentPhotoImportId('')
      setIsWorking(false)
    }
  }

  async function generateClassCertificates(classItem: ClassItem) {
    if (!activeTemplate || classItem.students.length === 0 || !storedState) {
      return
    }

    setIsWorking(true)

    try {
      const classWithIdPhotos = await ensureClassPhotosLoaded(classItem)
      const generated = (
        await Promise.all(
          classWithIdPhotos.students.map((student) =>
            generateForStudent(classWithIdPhotos, student, activeTemplate)
          )
        )
      ).filter((certificate): certificate is NonNullable<typeof certificate> => Boolean(certificate))
      const persistedGenerated = await Promise.all(generated.map(persistGeneratedCertificate))
      const nextClasses = classes.map((item) => (item.id === classWithIdPhotos.id ? classWithIdPhotos : item))
      const nextState: PersistedAppState = {
        ...storedState,
        classes: persistClasses(nextClasses, storedState),
        activeClassId: classWithIdPhotos.id,
        certificates: [
          ...(storedState.certificates ?? []).filter((certificate) => certificate.classId !== classWithIdPhotos.id),
          ...persistedGenerated
        ]
      }

      await saveAppState(nextState)
      setClasses(nextClasses)
      setStoredState(nextState)
      setGeneratedCountsByClassId((current) => ({
        ...current,
        [classWithIdPhotos.id]: generated.length
      }))
      navigate(`/generated?classId=${classWithIdPhotos.id}`)
    } finally {
      setIsWorking(false)
    }
  }

  async function generateClassIdPhotos(classItem: ClassItem) {
    if (classItem.students.length === 0 || !storedState) {
      return
    }

    setIsWorking(true)

    try {
      const classWithIdPhotos = await ensureClassIdPhotos(await ensureClassPhotosLoaded(classItem), true)
      const nextClasses = classes.map((item) => (item.id === classWithIdPhotos.id ? classWithIdPhotos : item))

      setClasses(nextClasses)
      await persist(nextClasses, classWithIdPhotos.id)
    } finally {
      setIsWorking(false)
    }
  }

  async function removeClass(classItem: ClassItem) {
    const nextClasses = classes.filter((item) => item.id !== classItem.id)
    const nextActiveClassId = nextClasses[0]?.id ?? ''
    const nextState = storedState
      ? {
        ...storedState,
        classes: persistClasses(nextClasses, storedState),
        activeClassId: nextActiveClassId,
        certificates: (storedState.certificates ?? []).filter(
          (certificate) => certificate.classId !== classItem.id
        )
      }
      : null

    setClasses(nextClasses)
    setActiveClassId(nextActiveClassId)
    setGeneratedCountsByClassId((current) => {
      const next = { ...current }
      delete next[classItem.id]
      return next
    })

    if (nextState) {
      await saveAppState(nextState)
      setStoredState(nextState)
    }
  }

  return (
    <div className="space-y-5">
      <div className="flex items-start gap-3">
        <div className="mt-1 rounded-md bg-primary/10 p-2 text-primary">
          <School className="h-5 w-5" />
        </div>
        <div>
          <h2 className="text-2xl font-semibold tracking-normal">班级管理</h2>
          <p className="text-sm text-muted-foreground">管理班级、照片和证件照规则</p>
        </div>
      </div>

      <Card className="border-dashed">
        <CardContent className="space-y-4 p-4">
          <div className="flex flex-col gap-3 lg:flex-row">
            <div className="relative flex-1">
              <Search className="pointer-events-none absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={classSearchQuery}
                onChange={(event) => setClassSearchQuery(event.target.value)}
                placeholder="搜索班级名称、学生或 UUID"
                className="h-12 rounded-xl pl-11"
              />
            </div>
            <Button type="button" className="h-12 rounded-xl px-5" onClick={openNewClassEditor}>
              <Plus />
              新建班级
            </Button>
          </div>

          <Input ref={classZipInputRef} type="file" accept=".zip" className="hidden" onChange={importClassZip} />
          <Input
            ref={studentPhotoInputRef}
            type="file"
            accept=".zip,image/jpeg,image/png"
            multiple
            className="hidden"
            onChange={importStudentPhotos}
          />
        </CardContent>
      </Card>

      {filteredClasses.length > 0 ? (
        <div className="grid gap-5 md:grid-cols-2 2xl:grid-cols-4">
          {filteredClasses.map((classItem) => {
            const count = generatedCountsByClassId[classItem.id] ?? 0
            const config = resolveIdPhotoConfig(classItem.idPhotoConfig)

            return (
              <Card
                key={classItem.id}
                className={cn(
                  'relative overflow-visible rounded-2xl border transition-all',
                  activeClass?.id === classItem.id && 'border-primary shadow-lg shadow-primary/10'
                )}
              >
                <CardContent className="space-y-5 p-4">
                  <div className="flex items-start justify-between gap-3">
                    <div className="space-y-1">
                      <div className="flex flex-wrap items-center gap-2">
                        <h3 className="text-2xl font-semibold">{classItem.name}</h3>
                        <span className="rounded-full bg-accent px-2.5 py-1 text-xs text-accent-foreground">
                          {count > 0 ? '已生成' : '待生成'}
                        </span>
                      </div>
                      <p className="break-all text-xs text-muted-foreground">{classItem.id}</p>
                    </div>
                  </div>

                  <div className="grid grid-cols-2 gap-3">
                    <div className="rounded-xl bg-muted/60 px-4 py-3">
                      <div className="text-xs text-muted-foreground">幼儿数据</div>
                      <div className="mt-2 text-3xl font-semibold">{classItem.students.length}</div>
                      <div className="text-sm text-muted-foreground">条</div>
                    </div>
                    <div className="rounded-xl bg-muted/60 px-4 py-3">
                      <div className="text-xs text-muted-foreground">生成数据</div>
                      <div className="mt-2 text-3xl font-semibold">
                        {count} / {classItem.students.length || 0}
                      </div>
                      <div className="text-sm text-muted-foreground">条</div>
                    </div>
                  </div>

                  <div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
                    <span
                      className="h-4 w-4 rounded-full border"
                      style={{ backgroundColor: idPhotoBackgroundColor(config) }}
                    />
                    <span>
                      证件照：{idPhotoSizeLabel(config.size)} / {idPhotoBackgroundLabel(config.background)}
                    </span>
                  </div>

                  <div className="flex items-center justify-end gap-3">
                    <div className="relative">
                      <Button
                        type="button"
                        variant="outline"
                        className="gap-2 rounded-xl"
                        onClick={() => {
                          setActiveClassId(classItem.id)
                          setOpenClassMenuId((current) => (current === classItem.id ? '' : classItem.id))
                        }}
                      >
                        <MoreHorizontal />
                        操作
                      </Button>
                      {openClassMenuId === classItem.id ? (
                        <div className="absolute bottom-12 right-0 z-20 w-60 rounded-2xl border bg-card p-2 shadow-2xl">
                          <button
                            type="button"
                            className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm hover:bg-accent"
                            onClick={() => openClassEditor(classItem)}
                          >
                            <Pencil className="h-4 w-4" />
                            编辑班级
                          </button>
                          <button
                            type="button"
                            className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm hover:bg-accent"
                            onClick={() => openClassZipPicker(classItem.id)}
                          >
                            <Upload className="h-4 w-4" />
                            上传幼儿信息
                          </button>
                          <button
                            type="button"
                            className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm hover:bg-accent"
                            onClick={() => openStudentPhotoPicker(classItem.id)}
                          >
                            <Upload className="h-4 w-4" />
                            批量导入学生照片
                          </button>
                          <button
                            type="button"
                            className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm hover:bg-accent disabled:opacity-50"
                            disabled={isWorking || classItem.students.length === 0}
                            onClick={() => generateClassIdPhotos(classItem)}
                          >
                            {isWorking ? <Loader2 className="h-4 w-4 animate-spin" /> : <UserRoundCheck className="h-4 w-4" />}
                            一键生成证件照
                          </button>
                          <button
                            type="button"
                            className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm hover:bg-accent"
                            onClick={() => navigate(`/students?classId=${classItem.id}`)}
                          >
                            <UserRoundCheck className="h-4 w-4" />
                            查看幼儿信息
                          </button>
                          <button
                            type="button"
                            className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm hover:bg-accent disabled:opacity-50"
                            disabled={!activeTemplate || isWorking || classItem.students.length === 0}
                            onClick={() => generateClassCertificates(classItem)}
                          >
                            {isWorking ? <Loader2 className="h-4 w-4 animate-spin" /> : <BadgeCheck className="h-4 w-4" />}
                            一键生成证书
                          </button>
                        </div>
                      ) : null}
                    </div>
                    <Button
                      type="button"
                      variant="destructive"
                      className="rounded-xl"
                      onClick={() => removeClass(classItem)}
                    >
                      <Trash2 />
                      删除
                    </Button>
                  </div>
                </CardContent>
              </Card>
            )
          })}
        </div>
      ) : (
        <Card className="border-dashed">
          <CardContent className="p-10 text-center text-muted-foreground">
            {classes.length === 0 ? '还没有班级，先点击上方“新建班级”开始。' : '没有匹配的班级。'}
          </CardContent>
        </Card>
      )}

      {isClassEditorOpen ? (
        <div className="fixed inset-0 z-50 bg-foreground/35" role="dialog" aria-modal="true">
          <button
            type="button"
            aria-label="关闭班级编辑"
            className="absolute inset-0 h-full w-full cursor-default"
            onClick={resetEditor}
          />
          <aside className="absolute right-0 top-0 flex h-full w-full max-w-md flex-col bg-card shadow-2xl">
            <div className="border-b p-5">
              <p className="text-sm text-muted-foreground">{editingClassId ? '编辑班级' : '新建班级'}</p>
              <h3 className="text-xl font-semibold">{editingClassId ? '更新班级信息' : '创建新的班级'}</h3>
            </div>

            <div className="flex-1 space-y-5 overflow-auto p-5">
              <div className="space-y-2">
                <label htmlFor="class-name" className="text-sm font-medium">
                  班级名称
                </label>
                <Input
                  id="class-name"
                  value={draftName}
                  onChange={(event) => setDraftName(event.target.value)}
                  placeholder="例如：大一班"
                  className="h-11"
                />
              </div>

              <div className="space-y-3 rounded-xl border bg-muted/30 p-4">
                <div className="flex items-center gap-2 text-sm font-medium">
                  <Palette className="h-4 w-4" />
                  证件照设置
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-2">
                    <label htmlFor="id-photo-size" className="text-sm font-medium">
                      尺寸
                    </label>
                    <select
                      id="id-photo-size"
                      className="h-10 w-full rounded-md border bg-background px-3 text-sm"
                      value={draftIdPhotoConfig.size}
                      onChange={(event) => updateDraftSize(event.target.value as IdPhotoSize)}
                    >
                      <option value="one-inch">一寸 295x413</option>
                      <option value="two-inch">二寸 413x579</option>
                    </select>
                  </div>
                  <div className="space-y-2">
                    <label htmlFor="id-photo-background" className="text-sm font-medium">
                      底色
                    </label>
                    <select
                      id="id-photo-background"
                      className="h-10 w-full rounded-md border bg-background px-3 text-sm"
                      value={draftIdPhotoConfig.background}
                      onChange={(event) =>
                        setDraftIdPhotoConfig((current) =>
                          resolveIdPhotoConfig({
                            ...current,
                            background: event.target.value as IdPhotoBackground
                          })
                        )
                      }
                    >
                      <option value="blue">蓝底</option>
                      <option value="white">白底</option>
                      <option value="red">红底</option>
                      <option value="custom">自定义</option>
                    </select>
                  </div>
                  {draftIdPhotoConfig.background === 'custom' ? (
                    <div className="col-span-2 space-y-2">
                      <label htmlFor="id-photo-custom-color" className="text-sm font-medium">
                        自定义颜色
                      </label>
                      <Input
                        id="id-photo-custom-color"
                        type="color"
                        value={draftIdPhotoConfig.customColor ?? ID_PHOTO_BACKGROUND_COLORS.blue}
                        onChange={(event) =>
                          setDraftIdPhotoConfig((current) =>
                            resolveIdPhotoConfig({
                              ...current,
                              customColor: event.target.value
                            })
                          )
                        }
                      />
                    </div>
                  ) : null}
                </div>
              </div>

              <div className="space-y-2">
                <div className="text-sm font-medium">幼儿信息</div>
                <label
                  htmlFor="class-zip"
                  className="flex min-h-40 cursor-pointer flex-col items-center justify-center rounded-xl border border-dashed bg-muted/40 px-6 text-center transition-colors hover:bg-muted"
                >
                  <div className="flex flex-col items-center gap-3 text-muted-foreground">
                    <div className="rounded-full bg-background p-3 shadow-sm">
                      <Upload className="h-6 w-6" />
                    </div>
                    <div>
                      <div className="text-sm font-medium text-foreground">
                        {draftZipFile ? draftZipFile.name : '点击上传幼儿信息 ZIP'}
                      </div>
                      <div className="mt-1 text-xs">ZIP 内包含幼儿名单和照片</div>
                    </div>
                  </div>
                </label>
                <Input
                  id="class-zip"
                  type="file"
                  accept=".zip"
                  className="hidden"
                  onChange={(event) => {
                    const file = event.target.files?.[0]
                    event.target.value = ''
                    setDraftZipFile(file && /\.zip$/i.test(file.name) ? file : null)
                  }}
                />
              </div>
            </div>

            <div className="flex justify-end gap-2 border-t p-5">
              <Button type="button" variant="outline" onClick={resetEditor}>
                取消
              </Button>
              <Button type="button" disabled={isWorking} onClick={saveClass}>
                {isWorking ? <Loader2 className="animate-spin" /> : null}
                {editingClassId ? '保存班级' : '创建班级'}
              </Button>
            </div>
          </aside>
        </div>
      ) : null}
    </div>
  )
}
