import { useState, useEffect, useCallback, useRef } from 'react'
import { Search, Trash2, Loader2, Upload, Grid, List, FileText, Image, Music, File } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Checkbox } from '@/components/ui/checkbox'
import { getFileList, uploadFile, deleteFile } from '@/api/systemCrud'
import type { SystemOss } from '@/api/system'
import { cn } from '@/lib/utils'

const getFileIcon = (suffix?: string) => {
  if (!suffix) return <File className="h-5 w-5" />
  if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(suffix)) return <Image className="h-5 w-5 text-blue-500" />
  if (['mp3', 'wav', 'ogg', 'flac'].includes(suffix)) return <Music className="h-5 w-5 text-purple-500" />
  return <FileText className="h-5 w-5 text-amber-500" />
}

const isImage = (suffix?: string) => suffix && ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(suffix)

export default function FilesPage() {
  const [files, setFiles] = useState<SystemOss[]>([])
  const [loading, setLoading] = useState(true)
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [search, setSearch] = useState('')
  const [view, setView] = useState<'grid' | 'list'>('grid')
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [uploading, setUploading] = useState(false)
  const [deleteOpen, setDeleteOpen] = useState(false)
  const [previewUrl, setPreviewUrl] = useState('')
  const fileRef = useRef<HTMLInputElement>(null)

  const fetchList = useCallback(async () => {
    setLoading(true)
    try { const res = await getFileList({ current: page, pageSize: 20, keyword: search || undefined }); if (res?.data) { setFiles(res.data.list || []); setTotal(res.data.total || 0) } }
    catch (e) { console.error(e) } finally { setLoading(false) }
  }, [page, search])

  useEffect(() => { fetchList() }, [fetchList])

  const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]; if (!file) return
    setUploading(true)
    try { await uploadFile(file); fetchList() } catch (err) { console.error(err) }
    finally { setUploading(false); if (fileRef.current) fileRef.current.value = '' }
  }

  const toggleSelect = (id: string) => {
    setSelected(prev => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next })
  }

  const handleDelete = async () => {
    try { await deleteFile(Array.from(selected)); setSelected(new Set()); setDeleteOpen(false); fetchList() }
    catch (e) { console.error(e) }
  }

  const totalPages = Math.ceil(total / 20)

  return (
    <div className="space-y-6 animate-fadeIn">
      <Card className="border-border/60 shadow-sm">
        <CardHeader className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 pb-6">
          <div className="space-y-1">
            <CardTitle className="text-xl flex items-center gap-2">文件管理 <Badge variant="secondary" className="text-xs">{total}</Badge></CardTitle>
            <CardDescription>管理上传的文件和图片资源</CardDescription>
          </div>
          <div className="flex items-center gap-3 w-full sm:w-auto flex-wrap">
            <div className="relative flex-1 sm:flex-none"><Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" /><Input placeholder="搜索文件..." className="pl-9 w-full sm:w-[200px] h-10 bg-muted/30" value={search} onChange={e => { setSearch(e.target.value); setPage(1) }} /></div>
            <div className="flex gap-1 border rounded-lg p-0.5">
              <Button variant={view === 'grid' ? 'secondary' : 'ghost'} size="icon" className="h-8 w-8" onClick={() => setView('grid')}><Grid className="h-4 w-4" /></Button>
              <Button variant={view === 'list' ? 'secondary' : 'ghost'} size="icon" className="h-8 w-8" onClick={() => setView('list')}><List className="h-4 w-4" /></Button>
            </div>
            {selected.size > 0 && <Button variant="destructive" size="sm" onClick={() => setDeleteOpen(true)}><Trash2 className="h-4 w-4 mr-1" />删除({selected.size})</Button>}
            <input type="file" ref={fileRef} className="hidden" onChange={handleUpload} />
            <Button onClick={() => fileRef.current?.click()} disabled={uploading} className="h-10 gap-2 shadow-sm">
              {uploading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Upload className="h-4 w-4" />}上传
            </Button>
          </div>
        </CardHeader>
        <CardContent>
          {loading ? <div className="flex items-center justify-center py-16"><Loader2 className="h-8 w-8 animate-spin text-primary" /></div>
          : view === 'grid' ? (
            <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4">
              {files.map(f => (
                <div key={f.id} className={cn("group relative rounded-xl border overflow-hidden cursor-pointer transition-all hover:shadow-md", selected.has(f.id) && "ring-2 ring-primary border-primary")}>
                  <div className="absolute top-2 left-2 z-10"><Checkbox checked={selected.has(f.id)} onCheckedChange={() => toggleSelect(f.id)} /></div>
                  <div className="aspect-square bg-muted/30 flex items-center justify-center" onClick={() => isImage(f.suffix) && setPreviewUrl(f.url)}>
                    {isImage(f.suffix) ? <img src={f.url} alt={f.name} className="w-full h-full object-cover" /> : getFileIcon(f.suffix)}
                  </div>
                  <div className="p-2"><p className="text-xs font-medium truncate">{f.name}</p><p className="text-[10px] text-muted-foreground">{f.suffix?.toUpperCase()}</p></div>
                </div>
              ))}
            </div>
          ) : (
            <div className="rounded-lg border border-border/50 overflow-hidden">
              <Table><TableHeader className="bg-muted/50"><TableRow><TableHead className="w-8" /><TableHead className="font-semibold pl-2">文件名</TableHead><TableHead>类型</TableHead><TableHead>创建时间</TableHead></TableRow></TableHeader>
              <TableBody>{files.map(f => (
                <TableRow key={f.id} className="hover:bg-muted/30">
                  <TableCell><Checkbox checked={selected.has(f.id)} onCheckedChange={() => toggleSelect(f.id)} /></TableCell>
                  <TableCell className="pl-2 flex items-center gap-2">{getFileIcon(f.suffix)}<span className="text-sm">{f.name}</span></TableCell>
                  <TableCell><Badge variant="secondary" className="text-xs">{f.suffix?.toUpperCase()}</Badge></TableCell>
                  <TableCell className="text-xs text-muted-foreground">{new Date(f.createdAt).toLocaleDateString()}</TableCell>
                </TableRow>
              ))}</TableBody></Table>
            </div>
          )}
          {totalPages > 1 && (
            <div className="flex items-center justify-between pt-4">
              <p className="text-sm text-muted-foreground">共 {total} 条</p>
              <div className="flex items-center gap-2">
                <Button variant="outline" size="sm" disabled={page <= 1} onClick={() => setPage(p => p - 1)}>上一页</Button>
                <span className="text-sm text-muted-foreground px-2">{page}/{totalPages}</span>
                <Button variant="outline" size="sm" disabled={page >= totalPages} onClick={() => setPage(p => p + 1)}>下一页</Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      <Dialog open={deleteOpen} onOpenChange={setDeleteOpen}>
        <DialogContent><DialogHeader><DialogTitle>确认删除</DialogTitle><DialogDescription>确定要删除选中的 {selected.size} 个文件吗？</DialogDescription></DialogHeader>
          <DialogFooter><Button variant="outline" onClick={() => setDeleteOpen(false)}>取消</Button><Button variant="destructive" onClick={handleDelete}>删除</Button></DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={!!previewUrl} onOpenChange={() => setPreviewUrl('')}>
        <DialogContent className="sm:max-w-[700px] p-2"><img src={previewUrl} alt="preview" className="w-full rounded-lg" /></DialogContent>
      </Dialog>
    </div>
  )
}
