import { useState, useEffect, type FormEvent } from "react"
import { Loader2Icon, PlusIcon, SearchIcon, XIcon } from "lucide-react"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Card, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Skeleton } from "@/components/ui/skeleton"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { useAdminBooks, useAdminSearchBooks, useAddBook, useUpdateBook, useUpdateStock, useDeleteBook, useAdminBorrowBook } from "./hooks"
import { useIsMobile } from "@/hooks/useIsMobile"
import type { Book } from "@/types/api"
import { getErrorMessage } from "@/lib/errors"

// ---- Dialog state helpers ----
interface AddDialog { open: boolean }
interface EditDialog { open: boolean; book: Book }
interface StockDialog { open: boolean; book: Book }
type DeleteDialog = { open: boolean; book: Book } | { open: false; book: null }
interface BorrowDialog { open: boolean; book: Book }

const addInitial: AddDialog = { open: false }

export default function AdminBooksPage() {
  const isMobile = useIsMobile()
  const sel = { "data-selectable": true } as const

  const [searchText, setSearchText] = useState("")
  const [submitted, setSubmitted] = useState("")

  const isSearching = submitted.length > 0
  const allQuery = useAdminBooks()
  const searchQuery = useAdminSearchBooks(submitted)
  const { data, isLoading, error } = isSearching ? searchQuery : allQuery

  function doSearch(e: FormEvent) {
    e.preventDefault()
    setSubmitted(searchText.trim())
  }

  function clearSearch() {
    setSearchText("")
    setSubmitted("")
  }

  const [add, setAdd] = useState<AddDialog>(addInitial)
  const [edit, setEdit] = useState<EditDialog | null>(null)
  const [stock, setStock] = useState<StockDialog | null>(null)
  const [del, setDel] = useState<DeleteDialog>({ open: false, book: null })
  const [borrow, setBorrow] = useState<BorrowDialog | null>(null)

  const list = data ?? []

  const content = isLoading ? (
    <AdminBooksSkeleton isMobile={isMobile} />
  ) : error ? (
    <div className="rounded-lg border border-destructive/50 bg-destructive/10 px-4 py-3 text-sm text-destructive">
      加载失败：{getErrorMessage(error)}
    </div>
  ) : list.length === 0 ? (
    <p className="py-16 text-center text-muted-foreground">
      {isSearching ? "无匹配书目" : "暂无书目"}
    </p>
  ) : !isMobile ? (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead className="w-[60px]">ID</TableHead>
          <TableHead>书名</TableHead>
          <TableHead>作者</TableHead>
          <TableHead className="w-[80px]">库存</TableHead>
          <TableHead className="w-[200px]">操作</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {list.map((b) => (
          <TableRow key={b.id}>
            <TableCell>{b.id}</TableCell>
            <TableCell className="font-medium" {...sel}>{b.name}</TableCell>
            <TableCell {...sel}>{b.author}</TableCell>
            <TableCell>{b.stock}</TableCell>
            <TableCell>
              <div className="flex gap-1">
                <Button size="xs" variant="outline" onClick={() => setEdit({ open: true, book: b })}>
                  编辑
                </Button>
                <Button size="xs" variant="outline" onClick={() => setStock({ open: true, book: b })}>
                  修改库存
                </Button>
                <Button size="xs" variant="destructive" onClick={() => setDel({ open: true, book: b })}>
                  删除
                </Button>
                <Button size="xs" variant="outline" disabled={b.stock <= 0} onClick={() => setBorrow({ open: true, book: b })}>
                  手动借阅
                </Button>
              </div>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  ) : (
    <div className="space-y-3">
      {list.map((b) => (
        <Card key={b.id}>
          <CardContent className="space-y-1.5 p-4">
            <div className="flex items-center justify-between">
              <span className="text-xs text-muted-foreground">#{b.id}</span>
              <span className="text-sm">库存：{b.stock}</span>
            </div>
            <div className="font-medium" {...sel}>{b.name}</div>
            <div className="text-sm text-muted-foreground" {...sel}>{b.author}</div>
            <div className="flex gap-1.5 pt-2">
              <Button size="xs" variant="outline" onClick={() => setEdit({ open: true, book: b })}>
                编辑
              </Button>
              <Button size="xs" variant="outline" onClick={() => setStock({ open: true, book: b })}>
                修改库存
              </Button>
              <Button size="xs" variant="destructive" onClick={() => setDel({ open: true, book: b })}>
                删除
              </Button>
              <Button size="xs" variant="outline" disabled={b.stock <= 0} onClick={() => setBorrow({ open: true, book: b })}>
                手动借阅
              </Button>
            </div>
          </CardContent>
        </Card>
      ))}
    </div>
  )

  return (
    <div>
      <div className="mb-4 flex items-center justify-between">
        <h1 className="text-xl font-semibold">图书管理</h1>
        <Button size="sm" onClick={() => setAdd({ open: true })}>
          <PlusIcon />
          添加图书
        </Button>
      </div>

      <form onSubmit={doSearch} className="mb-4 flex gap-2">
        <div className="relative flex-1 max-w-sm">
          <Input
            placeholder="搜索书名或作者..."
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
          />
          {isSearching && (
            <button
              type="button"
              onClick={clearSearch}
              className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
            >
              <XIcon className="size-4" />
            </button>
          )}
        </div>
        <Button type="submit" size="icon-sm" variant="outline">
          <SearchIcon className="size-4" />
        </Button>
      </form>

      {content}

      <AddBookDialog open={add.open} onClose={() => setAdd(addInitial)} />
      {edit && <EditBookDialog book={edit.book} open onClose={() => setEdit(null)} />}
      {stock && <StockDialog_ book={stock.book} open onClose={() => setStock(null)} />}
      {del.book && (
        <DeleteBookDialog book={del.book} open onClose={() => setDel({ open: false, book: null })} />
      )}
      {borrow && <BorrowDialog_ book={borrow.book} open onClose={() => setBorrow(null)} />}
    </div>
  )
}

// ---- Add Book Dialog ----
function AddBookDialog({ open, onClose }: { open: boolean; onClose: () => void }) {
  const mutation = useAddBook()
  const [name, setName] = useState("")
  const [author, setAuthor] = useState("")
  const [initStock, setInitStock] = useState("1")

  useEffect(() => {
    if (!open) {
      setName("")
      setAuthor("")
      setInitStock("1")
    }
  }, [open])

  async function submit(e: FormEvent) {
    e.preventDefault()
    await mutation.mutateAsync({ name, author, stock: Number(initStock) })
    onClose()
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>添加图书</DialogTitle>
        </DialogHeader>
        <form onSubmit={submit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="add-name">书名</Label>
            <Input id="add-name" required value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label htmlFor="add-author">作者</Label>
            <Input id="add-author" required value={author} onChange={(e) => setAuthor(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label htmlFor="add-stock">初始库存</Label>
            <Input id="add-stock" type="number" min={1} required value={initStock} onChange={(e) => setInitStock(e.target.value)} />
          </div>
          <DialogFooter>
            <Button type="submit" disabled={mutation.isPending}>
              {mutation.isPending && <Loader2Icon className="animate-spin" />}
              添加
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}

// ---- Edit Book Dialog ----
function EditBookDialog({ book, open, onClose }: { book: Book; open: boolean; onClose: () => void }) {
  const mutation = useUpdateBook()
  const [name, setName] = useState(book.name)
  const [author, setAuthor] = useState(book.author)

  useEffect(() => {
    if (open) {
      setName(book.name)
      setAuthor(book.author)
    }
  }, [open, book.name, book.author])

  async function submit(e: FormEvent) {
    e.preventDefault()
    await mutation.mutateAsync({ id: book.id!, data: { name, author } })
    onClose()
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>编辑图书</DialogTitle>
        </DialogHeader>
        <form onSubmit={submit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="edit-name">书名</Label>
            <Input id="edit-name" required value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label htmlFor="edit-author">作者</Label>
            <Input id="edit-author" required value={author} onChange={(e) => setAuthor(e.target.value)} />
          </div>
          <DialogFooter>
            <Button type="submit" disabled={mutation.isPending}>
              {mutation.isPending && <Loader2Icon className="animate-spin" />}
              保存
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}

// ---- Update Stock Dialog ----
function StockDialog_({ book, open, onClose }: { book: Book; open: boolean; onClose: () => void }) {
  const mutation = useUpdateStock()
  const [value, setValue] = useState(String(book.stock))

  useEffect(() => {
    if (open) setValue(String(book.stock))
  }, [open, book.stock])

  async function submit(e: FormEvent) {
    e.preventDefault()
    await mutation.mutateAsync({ id: book.id!, stock: Number(value) })
    onClose()
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>修改库存 — {book.name}</DialogTitle>
        </DialogHeader>
        <form onSubmit={submit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="stock-val">库存数量</Label>
            <Input id="stock-val" type="number" min={0} required value={value} onChange={(e) => setValue(e.target.value)} />
          </div>
          <DialogFooter>
            <Button type="submit" disabled={mutation.isPending}>
              {mutation.isPending && <Loader2Icon className="animate-spin" />}
              保存
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}

// ---- Delete Book Dialog ----
function DeleteBookDialog({ book, open, onClose }: { book: Book; open: boolean; onClose: () => void }) {
  const mutation = useDeleteBook()

  return (
    <AlertDialog open={open} onOpenChange={(o) => !o && onClose()}>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>确认删除</AlertDialogTitle>
          <AlertDialogDescription>
            确定要删除《{book.name}》吗？此操作不可撤销。
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>取消</AlertDialogCancel>
          <AlertDialogAction
            variant="destructive"
            disabled={mutation.isPending}
            onClick={() => mutation.mutateAsync(book.id!).then(onClose)}
          >
            {mutation.isPending && <Loader2Icon className="animate-spin" />}
            删除
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  )
}

// ---- Manual Borrow Dialog ----
function BorrowDialog_({ book, open, onClose }: { book: Book; open: boolean; onClose: () => void }) {
  const mutation = useAdminBorrowBook()
  const [userId, setUserId] = useState("")

  useEffect(() => {
    if (!open) setUserId("")
  }, [open])

  async function submit(e: FormEvent) {
    e.preventDefault()
    if (!userId.trim()) return
    await mutation.mutateAsync({ bookId: book.id!, userId: Number(userId) })
    onClose()
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>手动借阅 — {book.name}</DialogTitle>
        </DialogHeader>
        <form onSubmit={submit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="borrow-userid">用户 ID</Label>
            <Input id="borrow-userid" type="number" min={1} required value={userId} onChange={(e) => setUserId(e.target.value)} placeholder="输入用户 ID" />
          </div>
          <DialogFooter>
            <Button type="submit" disabled={mutation.isPending}>
              {mutation.isPending && <Loader2Icon className="animate-spin" />}
              确认借阅
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}

// ---- Skeleton ----
function AdminBooksSkeleton({ isMobile }: { isMobile: boolean }) {
  if (isMobile) {
    return (
      <div className="space-y-3">
        {Array.from({ length: 4 }).map((_, i) => (
          <Card key={i}>
            <CardContent className="space-y-2 p-4">
              <Skeleton className="h-4 w-16" />
              <Skeleton className="h-5 w-32" />
              <Skeleton className="h-4 w-20" />
              <div className="flex gap-1.5 pt-1">
                <Skeleton className="h-6 w-12 rounded-lg" />
                <Skeleton className="h-6 w-16 rounded-lg" />
                <Skeleton className="h-6 w-12 rounded-lg" />
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    )
  }
  return (
    <div className="space-y-2">
      {Array.from({ length: 6 }).map((_, i) => (
        <Skeleton key={i} className="h-10 w-full" />
      ))}
    </div>
  )
}
