import { useEffect, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  Eye,
  Pencil,
  Power,
  PowerOff,
  Trash2,
  Loader2,
  Plus,
  RotateCcw,
  SearchIcon,
  SwitchCamera,
} 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 { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { ScrollArea } from '@/components/ui/scroll-area'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
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 { AdminPage } from '@/features/admin/components/admin-page'
import { ListPagination } from '@/features/admin/components/list-pagination'
import { formatDateTime } from '@/features/admin/utils'
import {
  deleteCatalogCategory,
  createCatalogCategory,
  listCatalogCategories,
  syncCatalogThirdPartyCategories,
  updateCatalogCategory,
  updateCatalogCategoryEnabled,
  type CatalogCategory,
  type CategoryPayload,
} from './api'

const FILTER_ALL = 'all'

type CategoryDrawerMode = 'view' | 'edit'

const defaultForm: CategoryPayload = {
  name: '',
  sortOrder: 0,
  enabled: true,
}

function sourceLabel(sourceType: CatalogCategory['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 CategoryRowActions({
  category,
  canWrite,
  actionPending,
  onView,
  onEdit,
  onDelete,
  onToggleEnabled,
}: {
  category: CatalogCategory
  canWrite: boolean
  actionPending: boolean
  onView: () => 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>
        {canWrite && category.sourceType === 'self_owned' && (
          <DropdownMenuItem onClick={onEdit}>
            <Pencil />
            编辑
          </DropdownMenuItem>
        )}
        {canWrite && (
          <DropdownMenuItem
            disabled={actionPending}
            onClick={onToggleEnabled}
          >
            {category.enabled ? <PowerOff /> : <Power />}
            {category.enabled ? '停用' : '启用'}
          </DropdownMenuItem>
        )}
        {canWrite && category.sourceType === 'self_owned' && (
          <>
            <DropdownMenuSeparator />
            <DropdownMenuItem variant='destructive' onClick={onDelete}>
              <Trash2 />
              删除
            </DropdownMenuItem>
          </>
        )}
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

function toForm(category: CatalogCategory): CategoryPayload {
  return {
    name: category.name,
    sortOrder: category.sortOrder,
    enabled: category.enabled,
  }
}

export function CatalogCategoriesPage() {
  const queryClient = useQueryClient()
  const currentUser = useAuthStore((state) => state.auth.user)
  const canWrite = hasPermission(
    currentUser?.permissions,
    'catalog/categories',
    '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 [createOpen, setCreateOpen] = useState(false)
  const [createForm, setCreateForm] = useState<CategoryPayload>(defaultForm)
  const [selectedCategory, setSelectedCategory] =
    useState<CatalogCategory | null>(null)
  const [categoryDrawerMode, setCategoryDrawerMode] =
    useState<CategoryDrawerMode>('view')
  const [deleteCategory, setDeleteCategory] =
    useState<CatalogCategory | null>(null)
  const [editForm, setEditForm] = useState<CategoryPayload | null>(null)

  const categoriesQuery = useQuery({
    queryKey: [
      'catalog-categories',
      page,
      pageSize,
      keyword,
      sourceType,
      enabled,
    ],
    queryFn: () =>
      listCatalogCategories({
        page,
        pageSize,
        keyword,
        sourceType: sourceType === FILTER_ALL ? undefined : sourceType,
        enabled: enabled === FILTER_ALL ? undefined : enabled,
      }),
  })

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

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

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: CategoryPayload }) =>
      updateCatalogCategory(id, data),
    onSuccess: (category) => {
      toast.success('分类已保存')
      setSelectedCategory(category)
      setEditForm(toForm(category))
      void refresh()
    },
    onError: (error) => toast.error(getApiErrorMessage(error, '保存分类失败')),
  })

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

  const deleteMutation = useMutation({
    mutationFn: deleteCatalogCategory,
    onSuccess: () => {
      toast.success('分类已删除')
      setDeleteCategory(null)
      if (selectedCategory?.id === deleteCategory?.id) {
        setSelectedCategory(null)
      }
      void refresh()
    },
    onError: (error) => toast.error(getApiErrorMessage(error, '删除分类失败')),
  })

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

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

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

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

  const categories = categoriesQuery.data?.list ?? []

  function openCategory(category: CatalogCategory, mode: CategoryDrawerMode) {
    setSelectedCategory(category)
    setCategoryDrawerMode(mode)
  }

  return (
    <AdminPage
      title='分类管理'
      description='统一管理第三方同步分类和平台自营分类，自营分类可手动维护。'
      actions={
        canWrite ? (
          <div className='flex flex-wrap gap-2'>
            <Button
              variant='outline'
              onClick={() => syncMutation.mutate()}
              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>
          <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>外部 ID</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>
              {categoriesQuery.isLoading ? (
                <TableRow>
                  <TableCell colSpan={8} className='h-24 text-center'>
                    <Loader2 className='mx-auto animate-spin' />
                  </TableCell>
                </TableRow>
              ) : categories.length ? (
                categories.map((category) => (
                  <TableRow key={category.id}>
                    <TableCell className='font-medium'>
                      {category.name}
                    </TableCell>
                    <TableCell>
                      <Badge
                        variant={
                          category.sourceType === 'third_party'
                            ? 'outline'
                            : 'default'
                        }
                      >
                        {sourceLabel(category.sourceType)}
                      </Badge>
                    </TableCell>
                    <TableCell>{category.externalId || '-'}</TableCell>
                    <TableCell>{category.sortOrder}</TableCell>
                    <TableCell>
                      <Badge variant={category.enabled ? 'default' : 'secondary'}>
                        {category.enabled ? '启用' : '停用'}
                      </Badge>
                    </TableCell>
                    <TableCell>{formatDateTime(category.lastSyncedAt)}</TableCell>
                    <TableCell>{formatDateTime(category.updatedAt)}</TableCell>
                    <TableCell className='sticky right-0 z-10 bg-background text-right shadow-[-8px_0_12px_-12px_rgba(0,0,0,0.45)]'>
                      <CategoryRowActions
                        category={category}
                        canWrite={canWrite}
                        actionPending={enabledMutation.isPending}
                        onView={() => openCategory(category, 'view')}
                        onEdit={() => openCategory(category, 'edit')}
                        onDelete={() => setDeleteCategory(category)}
                        onToggleEnabled={() =>
                          enabledMutation.mutate({
                            id: category.id,
                            nextEnabled: !category.enabled,
                          })
                        }
                      />
                    </TableCell>
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={8} className='h-24 text-center'>
                    暂无分类数据
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>

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

      <CategoryDialog
        title='新建自营分类'
        description='自营分类用于平台自己维护的商品，不会调用第三方接口。'
        open={createOpen}
        form={createForm}
        pending={createMutation.isPending}
        onOpenChange={setCreateOpen}
        onFormChange={setCreateForm}
        onSubmit={() => createMutation.mutate(createForm)}
      />

      <ConfirmDialog
        open={!!deleteCategory}
        onOpenChange={(open) => {
          if (!open) setDeleteCategory(null)
        }}
        title='删除分类'
        desc={
          <div className='space-y-2'>
            <p>
              确认删除分类「{deleteCategory?.name}」吗？此操作只支持没有商品的自营分类。
            </p>
            <p className='text-muted-foreground'>
              如果分类下已有商品，请先调整商品分类或下架处理。
            </p>
          </div>
        }
        cancelBtnText='取消'
        confirmText='删除'
        destructive
        isLoading={deleteMutation.isPending}
        handleConfirm={() => {
          if (deleteCategory) {
            deleteMutation.mutate(deleteCategory.id)
          }
        }}
      />

      <Sheet
        open={!!selectedCategory}
        onOpenChange={(open) => {
          if (!open) setSelectedCategory(null)
        }}
      >
        <SheetContent className='flex w-full flex-col gap-0 sm:max-w-xl'>
          <SheetHeader className='border-b text-start'>
            <SheetTitle>
              {categoryDrawerMode === 'edit' ? '编辑分类' : '分类详情'}
            </SheetTitle>
            <SheetDescription>
              {categoryDrawerMode === 'edit'
                ? '编辑自营分类的名称、排序和启用状态。'
                : '查看分类来源、外部 ID、同步时间和更新信息。'}
            </SheetDescription>
          </SheetHeader>
          {selectedCategory && editForm && (
            <ScrollArea className='flex-1'>
              <div className='space-y-4 p-4'>
                <div className='grid gap-3 sm:grid-cols-2'>
                  <InfoItem label='分类 ID' value={selectedCategory.id} />
                  <InfoItem label='分类名称' value={selectedCategory.name} />
                  <InfoItem
                    label='来源'
                    value={sourceLabel(selectedCategory.sourceType)}
                  />
                  <InfoItem label='服务商' value={selectedCategory.provider} />
                  <InfoItem label='外部 ID' value={selectedCategory.externalId} />
                  <InfoItem
                    label='远程分类 ID'
                    value={selectedCategory.remoteCategoryId}
                  />
                  <InfoItem
                    label='最近同步'
                    value={formatDateTime(selectedCategory.lastSyncedAt)}
                  />
                  <InfoItem
                    label='更新时间'
                    value={formatDateTime(selectedCategory.updatedAt)}
                  />
                </div>

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

function CategoryDialog({
  title,
  description,
  open,
  form,
  pending,
  onOpenChange,
  onFormChange,
  onSubmit,
}: {
  title: string
  description: string
  open: boolean
  form: CategoryPayload
  pending: boolean
  onOpenChange: (open: boolean) => void
  onFormChange: (form: CategoryPayload) => void
  onSubmit: () => void
}) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>
        <CategoryForm form={form} onFormChange={onFormChange} />
        <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 CategoryForm({
  form,
  onFormChange,
}: {
  form: CategoryPayload
  onFormChange: (form: CategoryPayload) => void
}) {
  return (
    <div className='grid gap-4'>
      <div className='grid gap-2'>
        <Label htmlFor='category-name'>分类名称</Label>
        <Input
          id='category-name'
          value={form.name}
          onChange={(event) =>
            onFormChange({ ...form, name: event.target.value })
          }
        />
      </div>
      <div className='grid gap-2'>
        <Label htmlFor='category-sort'>排序</Label>
        <Input
          id='category-sort'
          type='number'
          value={form.sortOrder}
          onChange={(event) =>
            onFormChange({ ...form, sortOrder: Number(event.target.value || 0) })
          }
        />
      </div>
      <label className='flex items-center gap-3 text-sm'>
        <Switch
          checked={form.enabled}
          onCheckedChange={(enabled) => onFormChange({ ...form, enabled })}
        />
        分类启用
      </label>
    </div>
  )
}
