import { useEffect, useMemo, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  Eye,
  Loader2,
  Pencil,
  Power,
  PowerOff,
  Plus,
  RotateCcw,
  SearchIcon,
  ShoppingCart,
  SwitchCamera,
  Trash2,
} from 'lucide-react'
import { toast } from 'sonner'
import { getApiErrorMessage } from '@/lib/api'
import { hasPermission } from '@/lib/permissions'
import { useAuthStore } from '@/stores/auth-store'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { ConfirmDialog } from '@/components/confirm-dialog'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { ScrollArea } from '@/components/ui/scroll-area'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet'
import { Switch } from '@/components/ui/switch'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Textarea } from '@/components/ui/textarea'
import { AdminPage } from '@/features/admin/components/admin-page'
import { ListPagination } from '@/features/admin/components/list-pagination'
import { formatDateTime } from '@/features/admin/utils'
import {
  createCatalogProduct,
  deleteCatalogProduct,
  listCatalogCategories,
  listCatalogProducts,
  syncCatalogThirdPartyProducts,
  updateCatalogProduct,
  updateCatalogProductEnabled,
  type CatalogCategory,
  type CatalogProduct,
  type FulfillmentType,
  type OrderFormField,
  type OrderFormFieldType,
  type ProductPayload,
} from './api'

const FILTER_ALL = 'all'
const CATEGORY_NONE = 'none'

type ProductDrawerMode = 'view' | 'edit'

const defaultForm: ProductPayload = {
  categoryId: null,
  name: '',
  price: '0.00',
  coverUrl: null,
  content: null,
  stock: null,
  salesLimit: null,
  fulfillmentType: 'local_only',
  afterSalesNote: null,
  orderFormSchema: [],
  sortOrder: 0,
  enabled: true,
}

const orderFieldTypeLabels: Record<OrderFormFieldType, string> = {
  text: '文本',
  password: '密码',
  phone: '手机号',
  number: '数字',
  textarea: '多行文本',
  select: '下拉选择',
  checkbox: '勾选项',
}

const fulfillmentLabels: Record<FulfillmentType, string> = {
  third_party_api: '第三方接口',
  local_only: '本地交付',
  manual: '人工处理',
}

function sourceLabel(sourceType: CatalogProduct['sourceType']) {
  return sourceType === 'third_party' ? '第三方' : '自营'
}

function InfoItem({
  label,
  value,
}: {
  label: string
  value?: string | null
}) {
  return (
    <div className='grid gap-1'>
      <div className='text-xs text-muted-foreground'>{label}</div>
      <div className='min-h-8 rounded-md border bg-muted/30 px-3 py-2 text-sm break-all'>
        {value || '-'}
      </div>
    </div>
  )
}

function ProductRowActions({
  product,
  canWrite,
  canOrder,
  actionPending,
  onView,
  onOrder,
  onEdit,
  onDelete,
  onToggleEnabled,
}: {
  product: CatalogProduct
  canWrite: boolean
  canOrder: boolean
  actionPending: boolean
  onView: () => void
  onOrder: () => void
  onEdit: () => void
  onDelete: () => void
  onToggleEnabled: () => void
}) {
  return (
    <DropdownMenu modal={false}>
      <DropdownMenuTrigger asChild>
        <Button
          type='button'
          size='sm'
          variant='ghost'
          className='h-8 px-2 data-[state=open]:bg-muted'
        >
          操作
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align='end' className='w-36'>
        <DropdownMenuItem onClick={onView}>
          <Eye />
          查看
        </DropdownMenuItem>
        {canOrder && product.enabled && product.syncStatus === 'active' && (
          <DropdownMenuItem onClick={onOrder}>
            <ShoppingCart />
            下单
          </DropdownMenuItem>
        )}
        {canWrite && product.sourceType === 'self_owned' && (
          <DropdownMenuItem onClick={onEdit}>
            <Pencil />
            编辑
          </DropdownMenuItem>
        )}
        {canWrite && (
          <DropdownMenuItem
            disabled={actionPending}
            onClick={onToggleEnabled}
          >
            {product.enabled ? <PowerOff /> : <Power />}
            {product.enabled ? '下架' : '上架'}
          </DropdownMenuItem>
        )}
        {canWrite && (
          <>
            <DropdownMenuSeparator />
            <DropdownMenuItem variant='destructive' onClick={onDelete}>
              <Trash2 />
              删除
            </DropdownMenuItem>
          </>
        )}
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

function toForm(product: CatalogProduct): ProductPayload {
  return {
    categoryId: product.categoryId,
    name: product.name,
    price: product.price,
    coverUrl: product.coverUrl,
    content: product.content,
    stock: product.stock,
    salesLimit: product.salesLimit,
    fulfillmentType: product.fulfillmentType,
    afterSalesNote: product.afterSalesNote,
    orderFormSchema: product.orderFormSchema ?? [],
    sortOrder: product.sortOrder,
    enabled: product.enabled,
  }
}

function formatPrice(value: string) {
  const numberValue = Number(value)
  return Number.isFinite(numberValue) ? `¥${numberValue.toFixed(2)}` : value
}

export function CatalogProductsPage() {
  const queryClient = useQueryClient()
  const currentUser = useAuthStore((state) => state.auth.user)
  const canWrite = hasPermission(
    currentUser?.permissions,
    'catalog/products',
    'write'
  )
  const canCreateOrder = hasPermission(
    currentUser?.permissions,
    'orders',
    'write'
  )
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)
  const [keywordInput, setKeywordInput] = useState('')
  const [keyword, setKeyword] = useState('')
  const [sourceType, setSourceType] = useState(FILTER_ALL)
  const [enabled, setEnabled] = useState(FILTER_ALL)
  const [categoryId, setCategoryId] = useState(FILTER_ALL)
  const [syncRemoteCategoryId, setSyncRemoteCategoryId] = useState(FILTER_ALL)
  const [createOpen, setCreateOpen] = useState(false)
  const [createForm, setCreateForm] = useState<ProductPayload>(defaultForm)
  const [selectedProduct, setSelectedProduct] = useState<CatalogProduct | null>(
    null
  )
  const [productDrawerMode, setProductDrawerMode] =
    useState<ProductDrawerMode>('view')
  const [deleteProduct, setDeleteProduct] = useState<CatalogProduct | null>(null)
  const [editForm, setEditForm] = useState<ProductPayload | null>(null)

  const productsQuery = useQuery({
    queryKey: [
      'catalog-products',
      page,
      pageSize,
      keyword,
      sourceType,
      enabled,
      categoryId,
    ],
    queryFn: () =>
      listCatalogProducts({
        page,
        pageSize,
        keyword,
        sourceType: sourceType === FILTER_ALL ? undefined : sourceType,
        enabled: enabled === FILTER_ALL ? undefined : enabled,
        categoryId: categoryId === FILTER_ALL ? undefined : categoryId,
      }),
  })

  const categoriesQuery = useQuery({
    queryKey: ['catalog-categories-for-products'],
    queryFn: () =>
      listCatalogCategories({
        page: 1,
        pageSize: 100,
        enabled: 'true',
      }),
  })

  const selfOwnedCategories = useMemo(
    () =>
      (categoriesQuery.data?.list ?? []).filter(
        (category) => category.sourceType === 'self_owned'
      ),
    [categoriesQuery.data?.list]
  )
  const thirdPartyCategories = useMemo(
    () =>
      (categoriesQuery.data?.list ?? []).filter(
        (category) => category.sourceType === 'third_party'
      ),
    [categoriesQuery.data?.list]
  )

  const refresh = () => {
    void queryClient.invalidateQueries({ queryKey: ['catalog-products'] })
    void queryClient.invalidateQueries({
      queryKey: ['catalog-categories-for-products'],
    })
  }

  const createMutation = useMutation({
    mutationFn: createCatalogProduct,
    onSuccess: () => {
      toast.success('自营商品已创建')
      setCreateOpen(false)
      setCreateForm(defaultForm)
      refresh()
    },
    onError: (error) => toast.error(getApiErrorMessage(error, '创建商品失败')),
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: ProductPayload }) =>
      updateCatalogProduct(id, data),
    onSuccess: (product) => {
      toast.success('商品已保存')
      setSelectedProduct(product)
      setEditForm(toForm(product))
      refresh()
    },
    onError: (error) => toast.error(getApiErrorMessage(error, '保存商品失败')),
  })

  const enabledMutation = useMutation({
    mutationFn: ({ id, nextEnabled }: { id: string; nextEnabled: boolean }) =>
      updateCatalogProductEnabled(id, nextEnabled),
    onSuccess: () => {
      toast.success('商品状态已更新')
      refresh()
    },
    onError: (error) =>
      toast.error(getApiErrorMessage(error, '更新商品状态失败')),
  })

  const deleteMutation = useMutation({
    mutationFn: deleteCatalogProduct,
    onSuccess: () => {
      toast.success('商品已删除')
      setDeleteProduct(null)
      if (selectedProduct?.id === deleteProduct?.id) {
        setSelectedProduct(null)
      }
      refresh()
    },
    onError: (error) => toast.error(getApiErrorMessage(error, '删除商品失败')),
  })

  const syncMutation = useMutation({
    mutationFn: syncCatalogThirdPartyProducts,
    onSuccess: (result) => {
      if (result.skipped) {
        toast.info(result.reason || '已有同步任务正在执行')
        return
      }
      toast.success(
        `同步完成：新增 ${result.productCreated ?? 0} 个，更新 ${result.productUpdated ?? 0} 个，移除 ${result.productRemoved ?? 0} 个`
      )
      refresh()
    },
    onError: (error) =>
      toast.error(getApiErrorMessage(error, '同步第三方商品失败')),
  })

  useEffect(() => {
    setEditForm(selectedProduct ? toForm(selectedProduct) : null)
  }, [selectedProduct])

  function handleSearch() {
    setPage(1)
    setKeyword(keywordInput.trim())
  }

  function handleReset() {
    setPage(1)
    setKeyword('')
    setKeywordInput('')
    setSourceType(FILTER_ALL)
    setEnabled(FILTER_ALL)
    setCategoryId(FILTER_ALL)
  }

  function handleSync() {
    syncMutation.mutate(
      syncRemoteCategoryId === FILTER_ALL ? undefined : syncRemoteCategoryId
    )
  }

  function openProduct(product: CatalogProduct, mode: ProductDrawerMode) {
    setSelectedProduct(product)
    setProductDrawerMode(mode)
  }

  function openOrderPage(product: CatalogProduct) {
    const params = new URLSearchParams({ productId: product.id })
    if (product.categoryId) {
      params.set('categoryId', product.categoryId)
    }
    const path =
      product.sourceType === 'self_owned' ? '/self-owned-order' : '/course-query'
    window.location.assign(`${path}?${params.toString()}`)
  }

  const products = productsQuery.data?.list ?? []

  return (
    <AdminPage
      title='商品列表'
      description='统一管理第三方商品和平台自营商品，自营商品可配置价格、库存和交付方式。'
      actions={
        canWrite ? (
          <div className='flex flex-wrap gap-2'>
            <Select
              value={syncRemoteCategoryId}
              onValueChange={setSyncRemoteCategoryId}
            >
              <SelectTrigger className='h-9 w-48'>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={FILTER_ALL}>同步全部第三方分类</SelectItem>
                {thirdPartyCategories.map((category) => (
                  <SelectItem
                    key={category.id}
                    value={category.remoteCategoryId || category.externalId || category.id}
                  >
                    {category.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Button
              variant='outline'
              onClick={handleSync}
              disabled={syncMutation.isPending}
            >
              {syncMutation.isPending ? (
                <Loader2 className='animate-spin' />
              ) : (
                <SwitchCamera />
              )}
              同步第三方商品
            </Button>
            <Button onClick={() => setCreateOpen(true)}>
              <Plus />
              新建自营商品
            </Button>
          </div>
        ) : null
      }
    >
      <div className='flex flex-col gap-4'>
        <div className='flex flex-wrap items-center gap-2'>
          <Input
            value={keywordInput}
            onChange={(event) => setKeywordInput(event.target.value)}
            onKeyDown={(event) => {
              if (event.key === 'Enter') handleSearch()
            }}
            placeholder='搜索商品名称或外部 ID'
            className='h-9 w-64'
          />
          <Select
            value={sourceType}
            onValueChange={(value) => {
              setPage(1)
              setSourceType(value)
            }}
          >
            <SelectTrigger className='h-9 w-32'>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value={FILTER_ALL}>全部来源</SelectItem>
              <SelectItem value='third_party'>第三方</SelectItem>
              <SelectItem value='self_owned'>自营</SelectItem>
            </SelectContent>
          </Select>
          <Select
            value={enabled}
            onValueChange={(value) => {
              setPage(1)
              setEnabled(value)
            }}
          >
            <SelectTrigger className='h-9 w-32'>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value={FILTER_ALL}>全部状态</SelectItem>
              <SelectItem value='true'>启用</SelectItem>
              <SelectItem value='false'>停用</SelectItem>
            </SelectContent>
          </Select>
          <Select
            value={categoryId}
            onValueChange={(value) => {
              setPage(1)
              setCategoryId(value)
            }}
          >
            <SelectTrigger className='h-9 w-44'>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value={FILTER_ALL}>全部分类</SelectItem>
              {(categoriesQuery.data?.list ?? []).map((category) => (
                <SelectItem key={category.id} value={category.id}>
                  {category.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button variant='outline' onClick={handleSearch}>
            <SearchIcon />
            查询
          </Button>
          <Button variant='ghost' onClick={handleReset}>
            <RotateCcw />
            重置
          </Button>
        </div>

        <div className='overflow-auto rounded-md border'>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>商品</TableHead>
                <TableHead>来源</TableHead>
                <TableHead>分类</TableHead>
                <TableHead>价格</TableHead>
                <TableHead>库存</TableHead>
                <TableHead>交付</TableHead>
                <TableHead>状态</TableHead>
                <TableHead>更新时间</TableHead>
                <TableHead className='sticky right-0 z-20 w-20 bg-background text-right shadow-[-8px_0_12px_-12px_rgba(0,0,0,0.45)]'>
                  操作
                </TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {productsQuery.isLoading ? (
                <TableRow>
                  <TableCell colSpan={9} className='h-24 text-center'>
                    <Loader2 className='mx-auto animate-spin' />
                  </TableCell>
                </TableRow>
              ) : products.length ? (
                products.map((product) => (
                  <TableRow key={product.id}>
                    <TableCell>
                      <div className='font-medium'>{product.name}</div>
                      <div className='text-xs text-muted-foreground'>
                        {product.externalId || product.remoteCourseId || '-'}
                      </div>
                    </TableCell>
                    <TableCell>
                      <Badge
                        variant={
                          product.sourceType === 'third_party'
                            ? 'outline'
                            : 'default'
                        }
                      >
                        {sourceLabel(product.sourceType)}
                      </Badge>
                    </TableCell>
                    <TableCell>{product.categoryName || '-'}</TableCell>
                    <TableCell>{formatPrice(product.price)}</TableCell>
                    <TableCell>
                      {product.stock === null ? '不限' : product.stock}
                    </TableCell>
                    <TableCell>
                      {fulfillmentLabels[product.fulfillmentType] ||
                        product.fulfillmentType}
                    </TableCell>
                    <TableCell>
                      <Badge
                        variant={
                          product.syncStatus === 'removed'
                            ? 'destructive'
                            : product.enabled
                              ? 'default'
                              : 'secondary'
                        }
                      >
                        {product.syncStatus === 'removed'
                          ? '已移除'
                          : product.enabled
                            ? '上架'
                            : '下架'}
                      </Badge>
                    </TableCell>
                    <TableCell>{formatDateTime(product.updatedAt)}</TableCell>
                    <TableCell className='sticky right-0 z-10 bg-background text-right shadow-[-8px_0_12px_-12px_rgba(0,0,0,0.45)]'>
                      <ProductRowActions
                        product={product}
                        canWrite={canWrite}
                        canOrder={canCreateOrder}
                        actionPending={enabledMutation.isPending}
                        onView={() => openProduct(product, 'view')}
                        onOrder={() => openOrderPage(product)}
                        onEdit={() => openProduct(product, 'edit')}
                        onDelete={() => setDeleteProduct(product)}
                        onToggleEnabled={() =>
                          enabledMutation.mutate({
                            id: product.id,
                            nextEnabled: !product.enabled,
                          })
                        }
                      />
                    </TableCell>
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={9} className='h-24 text-center'>
                    暂无商品数据
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>

        <ListPagination
          page={productsQuery.data?.page ?? page}
          pageSize={productsQuery.data?.pageSize ?? pageSize}
          total={productsQuery.data?.total ?? 0}
          onPageChange={setPage}
          onPageSizeChange={(nextPageSize) => {
            setPage(1)
            setPageSize(nextPageSize)
          }}
        />
      </div>

      <ProductDialog
        open={createOpen}
        form={createForm}
        categories={selfOwnedCategories}
        pending={createMutation.isPending}
        onOpenChange={setCreateOpen}
        onFormChange={setCreateForm}
        onSubmit={() => createMutation.mutate(createForm)}
      />

      <ConfirmDialog
        open={!!deleteProduct}
        onOpenChange={(open) => {
          if (!open) setDeleteProduct(null)
        }}
        title='删除商品'
        desc={
          <div className='space-y-2'>
            <p>确认删除商品「{deleteProduct?.name}」吗？</p>
            {deleteProduct?.sourceType === 'third_party' ? (
              <p className='text-muted-foreground'>
                如果该商品仍存在于第三方接口，下次同步会重新写入本地。
              </p>
            ) : (
              <p className='text-muted-foreground'>
                自营商品删除后不会再出现在商品列表中。
              </p>
            )}
          </div>
        }
        cancelBtnText='取消'
        confirmText='删除'
        destructive
        isLoading={deleteMutation.isPending}
        handleConfirm={() => {
          if (deleteProduct) {
            deleteMutation.mutate(deleteProduct.id)
          }
        }}
      />

      <Sheet
        open={!!selectedProduct}
        onOpenChange={(open) => {
          if (!open) setSelectedProduct(null)
        }}
      >
        <SheetContent className='flex h-full w-full flex-col gap-0 sm:max-w-2xl'>
          <SheetHeader className='border-b text-start'>
            <SheetTitle>
              {productDrawerMode === 'edit' ? '编辑商品' : '商品详情'}
            </SheetTitle>
            <SheetDescription>
              {productDrawerMode === 'edit'
                ? '编辑自营商品的价格、库存、交付类型和上下架状态。'
                : '查看商品来源、价格、分类、同步时间和第三方标识。'}
            </SheetDescription>
          </SheetHeader>
          {selectedProduct && editForm && (
            <ScrollArea className='min-h-0 flex-1 overflow-y-auto'>
              <div className='space-y-4 p-4'>
                <div className='grid gap-3 sm:grid-cols-2'>
                  <InfoItem label='商品 ID' value={selectedProduct.id} />
                  <InfoItem label='商品名称' value={selectedProduct.name} />
                  <InfoItem
                    label='来源'
                    value={sourceLabel(selectedProduct.sourceType)}
                  />
                  <InfoItem label='分类' value={selectedProduct.categoryName} />
                  <InfoItem label='服务商' value={selectedProduct.provider} />
                  <InfoItem label='外部 ID' value={selectedProduct.externalId} />
                  <InfoItem
                    label='远程商品 ID'
                    value={selectedProduct.remoteCourseId}
                  />
                  <InfoItem
                    label='最近同步'
                    value={formatDateTime(selectedProduct.lastSyncedAt)}
                  />
                  <InfoItem
                    label='最近出现'
                    value={formatDateTime(selectedProduct.lastSeenAt)}
                  />
                  <InfoItem
                    label='同步状态'
                    value={
                      selectedProduct.syncStatus === 'removed'
                        ? '第三方已移除'
                        : '正常'
                    }
                  />
                  <InfoItem
                    label='移除时间'
                    value={formatDateTime(selectedProduct.removedAt)}
                  />
                  <InfoItem
                    label='更新时间'
                    value={formatDateTime(selectedProduct.updatedAt)}
                  />
                </div>

                {selectedProduct.content && (
                  <div className='grid gap-1'>
                    <div className='text-xs text-muted-foreground'>商品内容</div>
                    <div className='rounded-md border bg-muted/30 px-3 py-2 text-sm whitespace-pre-wrap'>
                      {selectedProduct.content}
                    </div>
                  </div>
                )}

                {productDrawerMode === 'edit' &&
                  canWrite &&
                  selectedProduct.sourceType === 'self_owned' && (
                  <div className='space-y-4 border-t pt-4'>
                    <ProductForm
                      form={editForm}
                      categories={selfOwnedCategories}
                      onFormChange={setEditForm}
                    />
                    <div className='flex justify-end gap-2'>
                      <Button
                        variant='outline'
                        onClick={() => setEditForm(toForm(selectedProduct))}
                        disabled={updateMutation.isPending}
                      >
                        还原
                      </Button>
                      <Button
                        onClick={() =>
                          updateMutation.mutate({
                            id: selectedProduct.id,
                            data: editForm,
                          })
                        }
                        disabled={updateMutation.isPending || !editForm.name}
                      >
                        {updateMutation.isPending && (
                          <Loader2 className='animate-spin' />
                        )}
                        保存修改
                      </Button>
                    </div>
                  </div>
                )}
              </div>
            </ScrollArea>
          )}
        </SheetContent>
      </Sheet>
    </AdminPage>
  )
}

function ProductDialog({
  open,
  form,
  categories,
  pending,
  onOpenChange,
  onFormChange,
  onSubmit,
}: {
  open: boolean
  form: ProductPayload
  categories: CatalogCategory[]
  pending: boolean
  onOpenChange: (open: boolean) => void
  onFormChange: (form: ProductPayload) => void
  onSubmit: () => void
}) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='sm:max-w-2xl'>
        <DialogHeader>
          <DialogTitle>新建自营商品</DialogTitle>
          <DialogDescription>
            自营商品只写入本地商品库，不会调用第三方下单接口。
          </DialogDescription>
        </DialogHeader>
        <ScrollArea className='max-h-[70vh] pr-3'>
          <ProductForm
            form={form}
            categories={categories}
            onFormChange={onFormChange}
          />
        </ScrollArea>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            取消
          </Button>
          <Button onClick={onSubmit} disabled={pending || !form.name.trim()}>
            {pending && <Loader2 className='animate-spin' />}
            保存
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

function ProductForm({
  form,
  categories,
  onFormChange,
}: {
  form: ProductPayload
  categories: CatalogCategory[]
  onFormChange: (form: ProductPayload) => void
}) {
  return (
    <div className='grid gap-4'>
      <div className='grid gap-2'>
        <Label htmlFor='product-name'>商品名称</Label>
        <Input
          id='product-name'
          value={form.name}
          onChange={(event) => onFormChange({ ...form, name: event.target.value })}
        />
      </div>
      <div className='grid gap-2'>
        <Label>自营分类</Label>
        <Select
          value={form.categoryId || CATEGORY_NONE}
          onValueChange={(value) =>
            onFormChange({
              ...form,
              categoryId: value === CATEGORY_NONE ? null : value,
            })
          }
        >
          <SelectTrigger>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value={CATEGORY_NONE}>不选择分类</SelectItem>
            {categories.map((category) => (
              <SelectItem key={category.id} value={category.id}>
                {category.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>
      <div className='grid gap-4 sm:grid-cols-2'>
        <div className='grid gap-2'>
          <Label htmlFor='product-price'>价格</Label>
          <Input
            id='product-price'
            type='number'
            min='0'
            step='0.01'
            value={form.price}
            onChange={(event) =>
              onFormChange({ ...form, price: event.target.value })
            }
          />
        </div>
        <div className='grid gap-2'>
          <Label htmlFor='product-sort'>排序</Label>
          <Input
            id='product-sort'
            type='number'
            value={form.sortOrder}
            onChange={(event) =>
              onFormChange({
                ...form,
                sortOrder: Number(event.target.value || 0),
              })
            }
          />
        </div>
      </div>
      <div className='grid gap-4 sm:grid-cols-2'>
        <div className='grid gap-2'>
          <Label htmlFor='product-stock'>库存</Label>
          <Input
            id='product-stock'
            type='number'
            min='0'
            placeholder='留空表示不限'
            value={form.stock ?? ''}
            onChange={(event) =>
              onFormChange({
                ...form,
                stock: event.target.value ? Number(event.target.value) : null,
              })
            }
          />
        </div>
        <div className='grid gap-2'>
          <Label htmlFor='product-sales-limit'>限购</Label>
          <Input
            id='product-sales-limit'
            type='number'
            min='0'
            placeholder='留空表示不限'
            value={form.salesLimit ?? ''}
            onChange={(event) =>
              onFormChange({
                ...form,
                salesLimit: event.target.value
                  ? Number(event.target.value)
                  : null,
              })
            }
          />
        </div>
      </div>
      <div className='grid gap-2'>
        <Label>交付类型</Label>
        <Select
          value={form.fulfillmentType}
          onValueChange={(value) =>
            onFormChange({
              ...form,
              fulfillmentType: value as FulfillmentType,
            })
          }
        >
          <SelectTrigger>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value='local_only'>本地交付</SelectItem>
            <SelectItem value='manual'>人工处理</SelectItem>
          </SelectContent>
        </Select>
      </div>
      <div className='grid gap-2'>
        <Label htmlFor='product-cover-url'>封面地址</Label>
        <Input
          id='product-cover-url'
          value={form.coverUrl ?? ''}
          onChange={(event) =>
            onFormChange({
              ...form,
              coverUrl: event.target.value.trim() || null,
            })
          }
        />
      </div>
      <div className='grid gap-2'>
        <Label htmlFor='product-content'>商品描述</Label>
        <Textarea
          id='product-content'
          value={form.content ?? ''}
          onChange={(event) =>
            onFormChange({
              ...form,
              content: event.target.value || null,
            })
          }
        />
      </div>
      <div className='grid gap-2'>
        <Label htmlFor='product-after-sales'>售后说明</Label>
        <Textarea
          id='product-after-sales'
          value={form.afterSalesNote ?? ''}
          onChange={(event) =>
            onFormChange({
              ...form,
              afterSalesNote: event.target.value || null,
            })
          }
        />
      </div>
      <OrderFormBuilder
        fields={form.orderFormSchema ?? []}
        onFieldsChange={(orderFormSchema) =>
          onFormChange({ ...form, orderFormSchema })
        }
      />
      <label className='flex items-center gap-3 text-sm'>
        <Switch
          checked={form.enabled}
          onCheckedChange={(enabled) => onFormChange({ ...form, enabled })}
        />
        商品上架
      </label>
    </div>
  )
}

function OrderFormBuilder({
  fields,
  onFieldsChange,
}: {
  fields: OrderFormField[]
  onFieldsChange: (fields: OrderFormField[]) => void
}) {
  function updateField(index: number, patch: Partial<OrderFormField>) {
    onFieldsChange(
      fields.map((field, fieldIndex) => {
        if (fieldIndex !== index) return field
        const next = { ...field, ...patch }
        if (patch.type && patch.type !== 'select') {
          delete next.options
        }
        if (patch.type === 'select' && !next.options?.length) {
          next.options = [{ label: '选项 1', value: 'option_1' }]
        }
        return next
      })
    )
  }

  function addField() {
    const nextIndex = fields.length + 1
    onFieldsChange([
      ...fields,
      {
        key: `field_${nextIndex}`,
        label: `字段 ${nextIndex}`,
        type: 'text',
        required: true,
        placeholder: null,
      },
    ])
  }

  function removeField(index: number) {
    onFieldsChange(fields.filter((_, fieldIndex) => fieldIndex !== index))
  }

  function moveField(index: number, direction: -1 | 1) {
    const nextIndex = index + direction
    if (nextIndex < 0 || nextIndex >= fields.length) return
    const next = [...fields]
    const [field] = next.splice(index, 1)
    next.splice(nextIndex, 0, field)
    onFieldsChange(next)
  }

  return (
    <div className='space-y-3 rounded-md border p-3'>
      <div className='flex flex-wrap items-center justify-between gap-2'>
        <div>
          <div className='text-sm font-medium'>下单表单</div>
          <div className='text-xs text-muted-foreground'>
            配置用户购买该商品时需要填写的信息。
          </div>
        </div>
        <Button type='button' variant='outline' size='sm' onClick={addField}>
          <Plus />
          添加字段
        </Button>
      </div>

      {fields.length ? (
        <div className='space-y-3'>
          {fields.map((field, index) => (
            <div key={`${field.key}-${index}`} className='rounded-md border bg-muted/20 p-3'>
              <div className='mb-3 flex flex-wrap items-center justify-between gap-2'>
                <div className='text-sm font-medium'>
                  {index + 1}. {field.label || field.key}
                </div>
                <div className='flex gap-1'>
                  <Button
                    type='button'
                    size='sm'
                    variant='ghost'
                    disabled={index === 0}
                    onClick={() => moveField(index, -1)}
                  >
                    上移
                  </Button>
                  <Button
                    type='button'
                    size='sm'
                    variant='ghost'
                    disabled={index === fields.length - 1}
                    onClick={() => moveField(index, 1)}
                  >
                    下移
                  </Button>
                  <Button
                    type='button'
                    size='sm'
                    variant='ghost'
                    onClick={() => removeField(index)}
                  >
                    删除
                  </Button>
                </div>
              </div>
              <div className='grid gap-3 sm:grid-cols-2'>
                <div className='grid gap-2'>
                  <Label>字段名称</Label>
                  <Input
                    value={field.label}
                    onChange={(event) =>
                      updateField(index, { label: event.target.value })
                    }
                  />
                </div>
                <div className='grid gap-2'>
                  <Label>字段标识</Label>
                  <Input
                    value={field.key}
                    onChange={(event) =>
                      updateField(index, { key: event.target.value })
                    }
                  />
                </div>
                <div className='grid gap-2'>
                  <Label>字段类型</Label>
                  <Select
                    value={field.type}
                    onValueChange={(value) =>
                      updateField(index, {
                        type: value as OrderFormFieldType,
                      })
                    }
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {Object.entries(orderFieldTypeLabels).map(([value, label]) => (
                        <SelectItem key={value} value={value}>
                          {label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className='grid gap-2'>
                  <Label>占位提示</Label>
                  <Input
                    value={field.placeholder ?? ''}
                    onChange={(event) =>
                      updateField(index, {
                        placeholder: event.target.value || null,
                      })
                    }
                  />
                </div>
              </div>
              <label className='mt-3 flex items-center gap-3 text-sm'>
                <Switch
                  checked={field.required}
                  onCheckedChange={(required) =>
                    updateField(index, { required })
                  }
                />
                必填
              </label>
              {field.type === 'select' && (
                <SelectOptionsEditor
                  options={field.options ?? []}
                  onOptionsChange={(options) => updateField(index, { options })}
                />
              )}
            </div>
          ))}
          <OrderFormPreview fields={fields} />
        </div>
      ) : (
        <div className='rounded-md border border-dashed py-8 text-center text-sm text-muted-foreground'>
          暂未配置下单字段，购买时不需要额外填写信息。
        </div>
      )}
    </div>
  )
}

function SelectOptionsEditor({
  options,
  onOptionsChange,
}: {
  options: Array<{ label: string; value: string }>
  onOptionsChange: (options: Array<{ label: string; value: string }>) => void
}) {
  return (
    <div className='mt-3 space-y-2 rounded-md border bg-background p-3'>
      <div className='flex items-center justify-between gap-2'>
        <div className='text-xs font-medium text-muted-foreground'>下拉选项</div>
        <Button
          type='button'
          size='sm'
          variant='outline'
          onClick={() =>
            onOptionsChange([
              ...options,
              {
                label: `选项 ${options.length + 1}`,
                value: `option_${options.length + 1}`,
              },
            ])
          }
        >
          <Plus />
          添加选项
        </Button>
      </div>
      {options.map((option, index) => (
        <div key={index} className='grid gap-2 sm:grid-cols-[1fr_1fr_auto]'>
          <Input
            value={option.label}
            placeholder='选项名称'
            onChange={(event) =>
              onOptionsChange(
                options.map((item, itemIndex) =>
                  itemIndex === index
                    ? { ...item, label: event.target.value }
                    : item
                )
              )
            }
          />
          <Input
            value={option.value}
            placeholder='选项值'
            onChange={(event) =>
              onOptionsChange(
                options.map((item, itemIndex) =>
                  itemIndex === index
                    ? { ...item, value: event.target.value }
                    : item
                )
              )
            }
          />
          <Button
            type='button'
            variant='ghost'
            onClick={() =>
              onOptionsChange(options.filter((_, itemIndex) => itemIndex !== index))
            }
          >
            删除
          </Button>
        </div>
      ))}
    </div>
  )
}

function OrderFormPreview({ fields }: { fields: OrderFormField[] }) {
  return (
    <div className='space-y-3 rounded-md border bg-background p-3'>
      <div className='text-sm font-medium'>表单预览</div>
      <div className='grid gap-3'>
        {fields.map((field) => (
          <div key={field.key} className='grid gap-1'>
            <Label>
              {field.label}
              {field.required && <span className='ml-1 text-destructive'>*</span>}
            </Label>
            {field.type === 'textarea' ? (
              <Textarea placeholder={field.placeholder ?? undefined} disabled />
            ) : field.type === 'select' ? (
              <Select disabled>
                <SelectTrigger>
                  <SelectValue placeholder={field.placeholder || '请选择'} />
                </SelectTrigger>
              </Select>
            ) : field.type === 'checkbox' ? (
              <label className='flex items-center gap-2 text-sm text-muted-foreground'>
                <Switch disabled />
                {field.placeholder || '勾选确认'}
              </label>
            ) : (
              <Input
                type={field.type === 'password' ? 'password' : 'text'}
                placeholder={field.placeholder ?? undefined}
                disabled
              />
            )}
          </div>
        ))}
      </div>
    </div>
  )
}
