"use client"

import { useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { Files, Search, Trash2, HardDrive, FileWarning } from "lucide-react"
import { toast } from "sonner"

import { Button } from "@/shared/components/ui/button"
import { Checkbox } from "@/shared/components/ui/checkbox"
import { Input } from "@/shared/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/components/ui/select"
import { Badge } from "@/shared/components/ui/badge"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { formatDate } from "@/shared/lib/utils"
import { formatFileSize } from "@/shared/lib/file-storage"
import { FileIcon } from "./file-icon"
import { FileUpload } from "./file-upload"
import { FilePreviewDialog } from "./file-preview-dialog"
import type { FileAttachment, FileStats } from "../types"

interface AdminFilesViewProps {
  files: FileAttachment[]
  stats: FileStats
}

// 文件类型分组选项
const TYPE_OPTIONS: Array<{ value: string; label: string }> = [
  { value: "all", label: "All Types" },
  { value: "image/", label: "Images" },
  { value: "application/pdf", label: "PDF" },
  { value: "application/msword", label: "Word" },
  { value: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", label: "Word (docx)" },
  { value: "application/vnd.ms-excel", label: "Excel" },
  { value: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", label: "Excel (xlsx)" },
  { value: "application/vnd.ms-powerpoint", label: "PowerPoint" },
  { value: "application/vnd.openxmlformats-officedocument.presentationml.presentation", label: "PowerPoint (pptx)" },
  { value: "text/", label: "Text" },
  { value: "application/zip", label: "ZIP" },
]

export function AdminFilesView({ files, stats }: AdminFilesViewProps) {
  const router = useRouter()
  const [typeFilter, setTypeFilter] = useState<string>("all")
  const [search, setSearch] = useState<string>("")
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
  const [deleting, setDeleting] = useState(false)

  // 客户端二次筛选（与 server 端筛选互补，提升交互即时性）
  const filteredFiles = useMemo(() => {
    return files.filter((f) => {
      if (typeFilter !== "all") {
        if (typeFilter.endsWith("/")) {
          if (!f.mimeType.startsWith(typeFilter)) return false
        } else if (f.mimeType !== typeFilter) {
          return false
        }
      }
      if (search.trim()) {
        const kw = search.trim().toLowerCase()
        if (
          !f.originalName.toLowerCase().includes(kw) &&
          !f.filename.toLowerCase().includes(kw)
        ) {
          return false
        }
      }
      return true
    })
  }, [files, typeFilter, search])

  const allSelected = filteredFiles.length > 0 && selectedIds.size === filteredFiles.length
  const someSelected = selectedIds.size > 0 && !allSelected

  const toggleAll = () => {
    if (allSelected) {
      setSelectedIds(new Set())
    } else {
      setSelectedIds(new Set(filteredFiles.map((f) => f.id)))
    }
  }

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

  const handleUploaded = () => {
    router.refresh()
  }

  const handleDeleted = () => {
    router.refresh()
    setSelectedIds(new Set())
  }

  const handleBatchDelete = async () => {
    if (selectedIds.size === 0) return
    const ids = Array.from(selectedIds)
    setDeleting(true)
    try {
      const res = await fetch("/api/files/batch-delete", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ids }),
      })
      const body = await res.json().catch(() => null)
      if (!res.ok || !body?.success) {
        toast.error(body?.message || "Failed to delete files")
        return
      }
      toast.success(`Deleted ${body.deletedCount} file(s)`)
      handleDeleted()
    } catch {
      toast.error("Failed to delete files")
    } finally {
      setDeleting(false)
    }
  }

  return (
    <div className="flex h-full flex-col space-y-6 p-8">
      <div className="space-y-1">
        <h2 className="flex items-center gap-2 text-2xl font-bold tracking-tight">
          <Files className="h-6 w-6" />
          Files
        </h2>
        <p className="text-muted-foreground">
          Upload and manage all files in the system.
        </p>
      </div>

      {/* 统计卡片 */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <div className="rounded-md border p-4">
          <div className="flex items-center gap-2 text-xs text-muted-foreground">
            <Files className="h-3.5 w-3.5" />
            Total Files
          </div>
          <p className="mt-1 text-2xl font-bold">{stats.totalCount}</p>
        </div>
        <div className="rounded-md border p-4">
          <div className="flex items-center gap-2 text-xs text-muted-foreground">
            <HardDrive className="h-3.5 w-3.5" />
            Total Size
          </div>
          <p className="mt-1 text-2xl font-bold">{formatFileSize(stats.totalSize)}</p>
        </div>
        {stats.byType.slice(0, 2).map((t) => (
          <div key={t.mimeType} className="rounded-md border p-4">
            <div className="flex items-center gap-2 text-xs text-muted-foreground">
              <FileIcon mimeType={t.mimeType} className="h-3.5 w-3.5" />
              <span className="truncate" title={t.mimeType}>{t.mimeType}</span>
            </div>
            <p className="mt-1 text-2xl font-bold">{t.count}</p>
            <p className="text-xs text-muted-foreground">{formatFileSize(t.size)}</p>
          </div>
        ))}
      </div>

      <FileUpload onUploaded={handleUploaded} />

      {/* 筛选与批量操作工具栏 */}
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex flex-1 flex-col gap-2 sm:flex-row sm:items-center">
          <Select value={typeFilter} onValueChange={setTypeFilter}>
            <SelectTrigger className="w-full sm:w-[200px]">
              <SelectValue placeholder="Filter by type" />
            </SelectTrigger>
            <SelectContent>
              {TYPE_OPTIONS.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <div className="relative flex-1">
            <Search className="absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              placeholder="Search by file name..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-8"
            />
          </div>
        </div>
        {selectedIds.size > 0 ? (
          <div className="flex items-center gap-2">
            <Badge variant="secondary">{selectedIds.size} selected</Badge>
            <Button
              type="button"
              variant="destructive"
              size="sm"
              disabled={deleting}
              onClick={() => void handleBatchDelete()}
            >
              <Trash2 className="mr-2 h-4 w-4" />
              {deleting ? "Deleting..." : "Delete Selected"}
            </Button>
          </div>
        ) : null}
      </div>

      {/* 文件列表 */}
      {filteredFiles.length === 0 ? (
        <EmptyState
          title="No files found"
          description="Try adjusting your filters or upload a new file."
          icon={FileWarning}
          className="h-auto border-none shadow-none"
        />
      ) : (
        <div className="rounded-md border">
          <div className="flex items-center gap-3 border-b bg-muted/40 px-3 py-2 text-xs font-medium text-muted-foreground">
            <Checkbox
              checked={allSelected ? true : someSelected ? "indeterminate" : false}
              onCheckedChange={toggleAll}
              aria-label="Select all"
            />
            <span className="flex-1">File</span>
            <span className="hidden w-24 sm:block">Size</span>
            <span className="hidden w-32 md:block">Type</span>
            <span className="hidden w-32 md:block">Uploaded</span>
            <span className="w-24 text-right">Actions</span>
          </div>
          <ul className="divide-y">
            {filteredFiles.map((file) => {
              const checked = selectedIds.has(file.id)
              return (
                <li
                  key={file.id}
                  className="flex items-center gap-3 p-3 transition-colors hover:bg-accent/40"
                >
                  <Checkbox
                    checked={checked}
                    onCheckedChange={() => toggleOne(file.id)}
                    aria-label={`Select ${file.originalName}`}
                  />
                  <FileIcon mimeType={file.mimeType} className="h-6 w-6" />
                  <div className="min-w-0 flex-1">
                    <a
                      href={file.url ?? "#"}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="truncate text-sm font-medium hover:underline"
                      title={file.originalName}
                    >
                      {file.originalName}
                    </a>
                    <p className="mt-0.5 text-xs text-muted-foreground sm:hidden">
                      {formatFileSize(file.size)} · {formatDate(file.createdAt, "zh-CN")}
                    </p>
                  </div>
                  <span className="hidden w-24 shrink-0 text-xs text-muted-foreground sm:block">
                    {formatFileSize(file.size)}
                  </span>
                  <span className="hidden w-32 shrink-0 truncate text-xs text-muted-foreground md:block" title={file.mimeType}>
                    {file.mimeType}
                  </span>
                  <span className="hidden w-32 shrink-0 text-xs text-muted-foreground md:block">
                    {formatDate(file.createdAt, "zh-CN")}
                  </span>
                  <div className="flex w-24 shrink-0 justify-end gap-1">
                    <FilePreviewDialog
                      file={file}
                      triggerLabel=""
                      triggerVariant="ghost"
                      triggerSize="icon"
                    />
                  </div>
                </li>
              )
            })}
          </ul>
        </div>
      )}
    </div>
  )
}
