import { useEffect, useMemo, useState } from 'react'
import {
  Bot,
  Construction,
  FileSearch,
  MoreHorizontal,
  Pencil,
  Presentation,
  Save,
  Search,
  Trash2,
  UserRound,
  Wand2,
  X
} from 'lucide-react'
import { useNavigate } from 'react-router-dom'
import { toast } from 'sonner'

import { DashboardFooter } from '@renderer/components/dashboard/DashboardFooter'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger
} from '@renderer/components/ui/alert-dialog'
import { Badge } from '@renderer/components/ui/badge'
import { Button } from '@renderer/components/ui/button'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle
} from '@renderer/components/ui/card'
import {
  Drawer,
  DrawerContent,
  DrawerDescription,
  DrawerHeader,
  DrawerTitle
} from '@renderer/components/ui/drawer'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger
} from '@renderer/components/ui/dropdown-menu'
import { Input } from '@renderer/components/ui/input'
import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious
} from '@renderer/components/ui/pagination'
import { ScrollArea } from '@renderer/components/ui/scroll-area'
import { Select } from '@renderer/components/ui/select'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow
} from '@renderer/components/ui/table'
import { getClassTypeLabel } from '@renderer/student/classes'
import type { ChildProfile, ClassProfile } from '@renderer/types/app'

function formatList(items: string[]): string {
  return items.length > 0 ? items.join('、') : '未填写'
}

function parseList(value: string): string[] {
  return value
    .split(/[、,，]/)
    .map((item) => item.trim())
    .filter(Boolean)
}

function getVisiblePages(currentPage: number, totalPages: number): Array<number | 'ellipsis'> {
  if (totalPages <= 7) {
    return Array.from({ length: totalPages }, (_, index) => index + 1)
  }

  const pages = new Set([1, totalPages, currentPage - 1, currentPage, currentPage + 1])
  const validPages = Array.from(pages)
    .filter((page) => page >= 1 && page <= totalPages)
    .sort((first, second) => first - second)
  const visiblePages: Array<number | 'ellipsis'> = []

  for (const page of validPages) {
    const previousPage = visiblePages[visiblePages.length - 1]

    if (typeof previousPage === 'number' && page - previousPage > 1) {
      visiblePages.push('ellipsis')
    }

    visiblePages.push(page)
  }

  return visiblePages
}

export function StudentPage(): React.JSX.Element {
  const navigate = useNavigate()
  const [profiles, setProfiles] = useState<ChildProfile[]>([])
  const [classes, setClasses] = useState<ClassProfile[]>([])
  const [totalProfiles, setTotalProfiles] = useState(0)
  const [studentDataReady, setStudentDataReady] = useState(false)
  const [selectedId, setSelectedId] = useState<string>('')
  const [selectedProfileIds, setSelectedProfileIds] = useState<string[]>([])
  const [generatingIds, setGeneratingIds] = useState<string[]>([])
  const [editingProfile, setEditingProfile] = useState<ChildProfile | null>(null)
  const [query, setQuery] = useState('')
  const [selectedClassFilter, setSelectedClassFilter] = useState('all')
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)

  useEffect(() => {
    async function loadStudentData(): Promise<void> {
      const response = await window.api.loadStudentData()

      if (!response.ok) {
        toast.error('读取数据库失败', { description: response.message })
        return
      }

      setClasses(response.classes)
      setStudentDataReady(true)
    }

    loadStudentData()
  }, [])

  useEffect(() => {
    async function loadPagedStudentProfiles(): Promise<void> {
      if (!studentDataReady) {
        return
      }

      const response = await window.api.listStudentProfiles({
        page,
        pageSize,
        query,
        classId: selectedClassFilter
      })

      if (!response.ok) {
        toast.error('读取学生列表失败', { description: response.message })
        return
      }

      setProfiles(response.profiles)
      setTotalProfiles(response.total)
    }

    loadPagedStudentProfiles()
  }, [page, pageSize, query, selectedClassFilter, studentDataReady])

  const classOptions = useMemo(() => {
    const classMap = new Map<string, ClassProfile>()

    for (const classItem of classes) {
      classMap.set(classItem.id, classItem)
    }

    for (const profile of profiles) {
      if (profile.classId && profile.className) {
        classMap.set(profile.classId, {
          id: profile.classId,
          name: profile.className,
          type: 'cheap'
        })
      }
    }

    return Array.from(classMap.values())
  }, [classes, profiles])

  const selectedProfile = profiles.find((profile) => profile.id === selectedId)
  const activeProfile = editingProfile ?? selectedProfile
  const selectedProfileClass = selectedProfile
    ? classOptions.find((classItem) => classItem.id === selectedProfile.classId)
    : undefined
  const totalPages = Math.max(Math.ceil(totalProfiles / pageSize), 1)
  const visiblePages = getVisiblePages(page, totalPages)
  const currentStart = totalProfiles === 0 ? 0 : (page - 1) * pageSize + 1
  const currentEnd = Math.min(page * pageSize, totalProfiles)

  function changePage(nextPage: number): void {
    setPage(Math.min(Math.max(nextPage, 1), totalPages))
  }

  function closeProfilePanel(): void {
    setSelectedId('')
    setEditingProfile(null)
  }

  function handleDrawerOpenChange(open: boolean): void {
    if (!open) {
      closeProfilePanel()
    }
  }

  function updateProfileInPage(nextProfile: ChildProfile): void {
    setProfiles((currentProfiles) =>
      currentProfiles.map((profile) => (profile.id === nextProfile.id ? nextProfile : profile))
    )
    setEditingProfile((currentProfile) =>
      currentProfile?.id === nextProfile.id ? nextProfile : currentProfile
    )
  }

  function toggleSelectedProfile(profileId: string): void {
    setSelectedProfileIds((currentIds) =>
      currentIds.includes(profileId)
        ? currentIds.filter((currentId) => currentId !== profileId)
        : [...currentIds, profileId]
    )
  }

  function toggleSelectedPageProfiles(checked: boolean): void {
    const pageProfileIds = profiles.map((profile) => profile.id)

    setSelectedProfileIds((currentIds) => {
      if (!checked) {
        return currentIds.filter((profileId) => !pageProfileIds.includes(profileId))
      }

      return Array.from(new Set([...currentIds, ...pageProfileIds]))
    })
  }

  async function handleGenerateComment(profile: ChildProfile): Promise<boolean> {
    setGeneratingIds((currentIds) => [...currentIds, profile.id])

    try {
      const response = await window.api.generateStudentComment({ profileId: profile.id })

      if (!response.ok) {
        toast.error(`生成「${profile.name || profile.englishName || '学生'}」评语失败`, {
          description: response.message
        })
        return false
      }

      updateProfileInPage(response.profile)
      toast.success(`已生成「${response.profile.name || '学生'}」评语`)
      return true
    } finally {
      setGeneratingIds((currentIds) => currentIds.filter((profileId) => profileId !== profile.id))
    }
  }

  async function handleBatchGenerateComments(): Promise<void> {
    const selectedProfiles = profiles.filter((profile) => selectedProfileIds.includes(profile.id))

    if (selectedProfiles.length === 0) {
      toast.error('请先选择要生成评语的学生')
      return
    }

    let successCount = 0
    let failedCount = 0

    for (const profile of selectedProfiles) {
      const ok = await handleGenerateComment(profile)

      if (ok) {
        successCount += 1
      } else {
        failedCount += 1
      }
    }

    toast.success('批量生成完成', {
      description: `成功 ${successCount} 个，失败 ${failedCount} 个`
    })
  }

  function hasGeneratedReport(profile: ChildProfile): boolean {
    const profileWithReport = profile as ChildProfile & {
      reportPath?: string
      reportGeneratedAt?: string
      reportFilePath?: string
    }

    return Boolean(
      profileWithReport.reportPath ||
      profileWithReport.reportGeneratedAt ||
      profileWithReport.reportFilePath
    )
  }

  function handleGenerateReport(profile: ChildProfile): void {
    navigate('/tools/reports', {
      state: {
        profileId: profile.id
      }
    })
  }

  function handleViewReport(profile: ChildProfile): void {
    if (!hasGeneratedReport(profile)) {
      return
    }

    navigate('/tools/reports', {
      state: {
        profileId: profile.id,
        mode: 'view'
      }
    })
  }

  async function handleDeleteProfile(profile: ChildProfile): Promise<void> {
    const response = await window.api.deleteStudentProfile(profile.id)

    if (!response.ok) {
      toast.error('删除学生失败', { description: response.message })
      return
    }

    setProfiles((currentProfiles) =>
      currentProfiles.filter((currentProfile) => currentProfile.id !== profile.id)
    )
    setSelectedProfileIds((currentIds) =>
      currentIds.filter((profileId) => profileId !== profile.id)
    )
    setTotalProfiles((currentTotal) => Math.max(currentTotal - 1, 0))

    if (selectedId === profile.id) {
      closeProfilePanel()
    }

    toast.success(`已删除「${profile.name || profile.englishName || '学生'}」`)
  }

  async function handleSaveProfile(): Promise<void> {
    if (!editingProfile) {
      return
    }

    const response = await window.api.updateStudentProfile(editingProfile)

    if (!response.ok) {
      toast.error('保存学生信息失败', { description: response.message })
      return
    }

    updateProfileInPage(response.profile)
    setEditingProfile(null)
    toast.success('学生信息已保存')
  }

  return (
    <>
      <section>
        <Card className="shadow-none">
          <CardHeader className="gap-3">
            <div className="flex flex-wrap items-start justify-between gap-3">
              <div className="fle flex-col gap-3">
                <CardTitle>
                  <div className="flex items-center gap-2">
                    <Construction className="size-5 text-primary" />
                    幼儿信息
                  </div>
                </CardTitle>
                <CardDescription>查看已上传的幼儿档案，按班级或关键词快速筛选。</CardDescription>
              </div>
              <Badge variant={totalProfiles > 0 ? 'success' : 'warning'}>
                {totalProfiles} 条档案
              </Badge>
            </div>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid gap-3 rounded-md border border-dashed bg-muted/30 p-4">
              <div className="grid gap-3 lg:grid-cols-[minmax(0,1fr)_220px]">
                <div className="relative min-w-0">
                  <Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                  <Input
                    className="pl-9"
                    value={query}
                    onChange={(event) => {
                      setQuery(event.target.value)
                      setPage(1)
                    }}
                    placeholder="搜索姓名、英文名、爱好、朋友或表现特征"
                  />
                </div>
                <Select
                  value={selectedClassFilter}
                  onChange={(event) => {
                    setSelectedClassFilter(event.target.value)
                    setPage(1)
                  }}
                >
                  <option value="all">全部班级</option>
                  {classOptions.map((classItem) => (
                    <option key={classItem.id} value={classItem.id}>
                      {classItem.name}
                    </option>
                  ))}
                </Select>
              </div>
              <div className="flex justify-end">
                <Button
                  size="sm"
                  disabled={selectedProfileIds.length === 0 || generatingIds.length > 0}
                  onClick={handleBatchGenerateComments}
                >
                  <Wand2 />
                  批量生成评语
                </Button>
              </div>
            </div>

            <div className="overflow-hidden rounded-md border">
              <Table className="min-w-[1080px]">
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-12">
                      <input
                        className="size-4 rounded border-input accent-primary"
                        type="checkbox"
                        checked={
                          profiles.length > 0 &&
                          profiles.every((profile) => selectedProfileIds.includes(profile.id))
                        }
                        onChange={(event) => toggleSelectedPageProfiles(event.target.checked)}
                        aria-label="选择当前页学生"
                      />
                    </TableHead>
                    <TableHead>班级</TableHead>
                    <TableHead>姓名</TableHead>
                    <TableHead>英文名</TableHead>
                    <TableHead>性别</TableHead>
                    <TableHead>生日</TableHead>
                    <TableHead>属相</TableHead>
                    <TableHead>爱好</TableHead>
                    <TableHead>评语</TableHead>
                    <TableHead className="w-36 pr-6 text-right">操作</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {profiles.map((profile) => {
                    const isGenerating = generatingIds.includes(profile.id)
                    const reportReady = hasGeneratedReport(profile)

                    return (
                      <TableRow
                        key={profile.id}
                        className={profile.id === selectedProfile?.id ? 'bg-muted/70' : undefined}
                      >
                        <TableCell>
                          <input
                            className="size-4 rounded border-input accent-primary"
                            type="checkbox"
                            checked={selectedProfileIds.includes(profile.id)}
                            onChange={() => toggleSelectedProfile(profile.id)}
                            aria-label={`选择${profile.name || profile.englishName || '学生'}`}
                          />
                        </TableCell>
                        <TableCell>{profile.className || '未分班'}</TableCell>
                        <TableCell className="font-medium">{profile.name || '未填写'}</TableCell>
                        <TableCell>{profile.englishName || '未填写'}</TableCell>
                        <TableCell>{profile.gender || '未填写'}</TableCell>
                        <TableCell>{profile.birthday || '未填写'}</TableCell>
                        <TableCell>{profile.zodiac || '未填写'}</TableCell>
                        <TableCell className="max-w-[160px] truncate">
                          {formatList(profile.hobbies)}
                        </TableCell>
                        <TableCell className="max-w-[260px] truncate">
                          {profile.comment || '未生成'}
                        </TableCell>
                        <TableCell className="pr-6 text-right">
                          <div className="flex justify-end gap-2">
                            <Button
                              size="sm"
                              variant="outline"
                              onClick={() => {
                                setSelectedId(profile.id)
                                setEditingProfile(null)
                              }}
                            >
                              查看
                            </Button>
                            <DropdownMenu>
                              <DropdownMenuTrigger asChild>
                                <Button size="sm" variant="outline">
                                  <MoreHorizontal />
                                  操作
                                </Button>
                              </DropdownMenuTrigger>
                              <DropdownMenuContent>
                                <DropdownMenuLabel>学生操作</DropdownMenuLabel>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem
                                  onSelect={() => {
                                    setSelectedId(profile.id)
                                    setEditingProfile(profile)
                                  }}
                                >
                                  <Pencil />
                                  编辑学生信息
                                </DropdownMenuItem>
                                <DropdownMenuItem
                                  disabled={isGenerating}
                                  onSelect={() => handleGenerateComment(profile)}
                                >
                                  <Bot />
                                  {isGenerating ? '生成中' : '生成评语'}
                                </DropdownMenuItem>
                                <DropdownMenuItem onSelect={() => handleGenerateReport(profile)}>
                                  <Presentation />
                                  生成报告
                                </DropdownMenuItem>
                                <DropdownMenuItem
                                  disabled={!reportReady}
                                  onSelect={() => handleViewReport(profile)}
                                >
                                  <FileSearch />
                                  查看报告
                                </DropdownMenuItem>
                                <DropdownMenuSeparator />
                                <AlertDialog>
                                  <AlertDialogTrigger asChild>
                                    <DropdownMenuItem
                                      className="text-destructive focus:text-destructive"
                                      onSelect={(event) => event.preventDefault()}
                                    >
                                      <Trash2 />
                                      删除学生
                                    </DropdownMenuItem>
                                  </AlertDialogTrigger>
                                  <AlertDialogContent>
                                    <AlertDialogHeader>
                                      <AlertDialogTitle>
                                        删除「{profile.name || profile.englishName || '学生'}」？
                                      </AlertDialogTitle>
                                      <AlertDialogDescription>
                                        确认删除后，这名学生的幼儿信息和已生成评语会从当前数据库中移除。
                                      </AlertDialogDescription>
                                    </AlertDialogHeader>
                                    <AlertDialogFooter>
                                      <AlertDialogCancel>取消</AlertDialogCancel>
                                      <AlertDialogAction
                                        onClick={() => handleDeleteProfile(profile)}
                                      >
                                        确认删除
                                      </AlertDialogAction>
                                    </AlertDialogFooter>
                                  </AlertDialogContent>
                                </AlertDialog>
                              </DropdownMenuContent>
                            </DropdownMenu>
                          </div>
                        </TableCell>
                      </TableRow>
                    )
                  })}
                  {profiles.length === 0 && (
                    <TableRow>
                      <TableCell className="h-28 text-center text-muted-foreground" colSpan={10}>
                        暂无匹配数据，请先在班级管理中上传幼儿 xlsx 表格
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            </div>

            <div className="grid gap-3 rounded-md border bg-background px-3 py-3 lg:grid-cols-[1fr_auto_1fr] lg:items-center">
              <div className="hidden lg:block" />

              <Pagination className="justify-center">
                <PaginationContent>
                  <PaginationItem>
                    <PaginationPrevious disabled={page <= 1} onClick={() => changePage(page - 1)} />
                  </PaginationItem>
                  {visiblePages.map((visiblePage, index) => (
                    <PaginationItem key={`${visiblePage}-${index}`}>
                      {visiblePage === 'ellipsis' ? (
                        <PaginationEllipsis />
                      ) : (
                        <PaginationLink
                          isActive={visiblePage === page}
                          onClick={() => changePage(visiblePage)}
                        >
                          {visiblePage}
                        </PaginationLink>
                      )}
                    </PaginationItem>
                  ))}
                  <PaginationItem>
                    <PaginationNext
                      disabled={page >= totalPages}
                      onClick={() => changePage(page + 1)}
                    />
                  </PaginationItem>
                </PaginationContent>
              </Pagination>

              <div className="flex flex-wrap items-center justify-center gap-3 text-sm text-muted-foreground lg:justify-end">
                <span>
                  显示 {currentStart}-{currentEnd} 条，共 {totalProfiles} 条
                </span>
                <label className="flex items-center gap-2">
                  每页
                  <Select
                    className="h-8 w-24"
                    value={String(pageSize)}
                    onChange={(event) => {
                      setPageSize(Number(event.target.value))
                      setPage(1)
                    }}
                  >
                    <option value="10">10 条</option>
                    <option value="20">20 条</option>
                    <option value="50">50 条</option>
                  </Select>
                </label>
              </div>
            </div>
          </CardContent>
        </Card>
      </section>

      <Drawer direction="right" open={Boolean(activeProfile)} onOpenChange={handleDrawerOpenChange}>
        <DrawerContent>
          {activeProfile && (
            <>
              <DrawerHeader>
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <div className="flex items-center gap-2">
                      <UserRound className="size-5 text-primary" />
                      <DrawerTitle>幼儿信息</DrawerTitle>
                    </div>
                    <DrawerDescription className="mt-1">查看当前幼儿的完整档案。</DrawerDescription>
                  </div>
                  <div className="flex gap-2">
                    {editingProfile ? (
                      <Button size="sm" onClick={handleSaveProfile}>
                        <Save />
                        保存
                      </Button>
                    ) : null}
                    <Button
                      size="icon"
                      variant="ghost"
                      aria-label="关闭幼儿信息"
                      onClick={closeProfilePanel}
                    >
                      <X />
                    </Button>
                  </div>
                </div>
              </DrawerHeader>
              <ScrollArea className="min-h-0 flex-1">
                <div className="space-y-5 p-6">
                  <div className="rounded-md bg-muted p-4">
                    <p className="text-2xl font-semibold">{activeProfile.name || '未填写姓名'}</p>
                    <p className="mt-1 text-sm text-muted-foreground">
                      {activeProfile.englishName || '未填写英文名'} ·{' '}
                      {activeProfile.gender || '未填写性别'} ·{' '}
                      {activeProfile.birthday || '未填写生日'}
                    </p>
                  </div>

                  {editingProfile ? (
                    <StudentProfileForm profile={editingProfile} onChange={setEditingProfile} />
                  ) : (
                    <dl className="grid gap-3 text-sm">
                      <ProfileField label="班级" value={activeProfile.className || '未分班'} />
                      <ProfileField
                        label="班级类型"
                        value={
                          selectedProfileClass
                            ? getClassTypeLabel(selectedProfileClass.type)
                            : '未记录'
                        }
                      />
                      <ProfileField label="班级 UUID" value={activeProfile.classId || '未记录'} />
                      <ProfileField label="属相" value={activeProfile.zodiac || '未填写'} />
                      <ProfileField label="我的好朋友" value={formatList(activeProfile.friends)} />
                      <ProfileField label="我的爱好" value={formatList(activeProfile.hobbies)} />
                      <ProfileField
                        label="喜欢的游戏"
                        value={formatList(activeProfile.favoriteGames)}
                      />
                      <ProfileField
                        label="喜欢吃的食物"
                        value={formatList(activeProfile.favoriteFoods)}
                      />
                      <ProfileField label="表现特征" value={activeProfile.traits || '未填写'} />
                      <ProfileField label="评语" value={activeProfile.comment || '未生成评语'} />
                      <ProfileField
                        label="评语生成时间"
                        value={activeProfile.commentGeneratedAt || '未生成'}
                      />
                      <ProfileField label="导入时间" value={activeProfile.importedAt} />
                    </dl>
                  )}
                </div>
              </ScrollArea>
            </>
          )}
        </DrawerContent>
      </Drawer>

      <DashboardFooter />
    </>
  )
}

function ProfileField({ label, value }: { label: string; value: string }): React.JSX.Element {
  return (
    <div className="grid gap-1 rounded-md border bg-background p-3">
      <dt className="text-xs font-medium text-muted-foreground">{label}</dt>
      <dd className="leading-6">{value}</dd>
    </div>
  )
}

function StudentProfileForm({
  profile,
  onChange
}: {
  profile: ChildProfile
  onChange: (profile: ChildProfile) => void
}): React.JSX.Element {
  function updateTextField(field: keyof ChildProfile, value: string): void {
    onChange({
      ...profile,
      [field]: value
    })
  }

  function updateListField(
    field: 'friends' | 'hobbies' | 'favoriteGames' | 'favoriteFoods',
    value: string
  ): void {
    onChange({
      ...profile,
      [field]: parseList(value)
    })
  }

  return (
    <div className="grid gap-4">
      <div className="grid gap-3 sm:grid-cols-2">
        <EditableField
          label="姓名"
          value={profile.name}
          onChange={(value) => updateTextField('name', value)}
        />
        <EditableField
          label="英文名"
          value={profile.englishName}
          onChange={(value) => updateTextField('englishName', value)}
        />
        <EditableField
          label="性别"
          value={profile.gender}
          onChange={(value) => updateTextField('gender', value)}
        />
        <EditableField
          label="生日"
          value={profile.birthday}
          onChange={(value) => updateTextField('birthday', value)}
        />
        <EditableField
          label="属相"
          value={profile.zodiac}
          onChange={(value) => updateTextField('zodiac', value)}
        />
        <EditableField
          label="班级"
          value={profile.className}
          onChange={(value) => updateTextField('className', value)}
        />
      </div>

      <EditableField
        label="我的好朋友"
        value={profile.friends.join('、')}
        onChange={(value) => updateListField('friends', value)}
      />
      <EditableField
        label="我的爱好"
        value={profile.hobbies.join('、')}
        onChange={(value) => updateListField('hobbies', value)}
      />
      <EditableField
        label="喜欢的游戏"
        value={profile.favoriteGames.join('、')}
        onChange={(value) => updateListField('favoriteGames', value)}
      />
      <EditableField
        label="喜欢吃的食物"
        value={profile.favoriteFoods.join('、')}
        onChange={(value) => updateListField('favoriteFoods', value)}
      />
      <EditableField
        label="表现特征"
        value={profile.traits}
        multiline
        onChange={(value) => updateTextField('traits', value)}
      />
      <EditableField
        label="评语"
        value={profile.comment}
        multiline
        onChange={(value) => updateTextField('comment', value)}
      />
    </div>
  )
}

function EditableField({
  label,
  value,
  multiline = false,
  onChange
}: {
  label: string
  value: string
  multiline?: boolean
  onChange: (value: string) => void
}): React.JSX.Element {
  return (
    <label className="grid gap-2 text-sm">
      <span className="font-medium">{label}</span>
      {multiline ? (
        <textarea
          className="min-h-24 rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus-visible:ring-1 focus-visible:ring-ring"
          value={value}
          onChange={(event) => onChange(event.target.value)}
        />
      ) : (
        <Input value={value} onChange={(event) => onChange(event.target.value)} />
      )}
    </label>
  )
}
