"use client"

import { useTranslations } from "next-intl"
import { useRouter } from "next/navigation"
import { Files, Search, Trash2, HardDrive, FileWarning } from "lucide-react"

import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Checkbox } from "@/shared/components/ui/checkbox"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Input } from "@/shared/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/components/ui/select"
import { WidgetBoundary } from "@/shared/components/widget-boundary"
import { formatDate } from "@/shared/lib/utils"
import { formatFileSize } from "@/shared/lib/file-storage"

import { FileIcon } from "./file-icon"
import { FilePreviewDialog } from "./file-preview-dialog"
import { FileUpload } from "./file-upload"
import { useFileBatchOperations } from "../hooks/use-file-batch-operations"
import type { FileAttachment, FileStats } from "../types"

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

interface TypeOption {
  value: string
  labelKey:
    | "allTypes"
    | "images"
    | "pdf"
    | "word"
    | "wordDocx"
    | "excel"
    | "excelXlsx"
    | "powerpoint"
    | "powerpointPptx"
    | "text"
    | "zip"
}

const TYPE_OPTIONS = [
  { value: "all", labelKey: "allTypes" },
  { value: "image/", labelKey: "images" },
  { value: "application/pdf", labelKey: "pdf" },
  { value: "application/msword", labelKey: "word" },
  { value: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", labelKey: "wordDocx" },
  { value: "application/vnd.ms-excel", labelKey: "excel" },
  { value: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", labelKey: "excelXlsx" },
  { value: "application/vnd.ms-powerpoint", labelKey: "powerpoint" },
  { value: "application/vnd.openxmlformats-officedocument.presentationml.presentation", labelKey: "powerpointPptx" },
  { value: "text/", labelKey: "text" },
  { value: "application/zip", labelKey: "zip" },
] as const satisfies TypeOption[]

type TypeLabelKey = TypeOption["labelKey"]

export function AdminFilesView({
  files,
  stats,
}: AdminFilesViewProps): React.ReactElement {
  const t = useTranslations("files.admin")
  const router = useRouter()

  const renderTypeLabel = (key: TypeLabelKey): string => {
    switch (key) {
      case "allTypes": return t("filter.allTypes")
      case "images": return t("filter.images")
      case "pdf": return t("filter.pdf")
      case "word": return t("filter.word")
      case "wordDocx": return t("filter.wordDocx")
      case "excel": return t("filter.excel")
      case "excelXlsx": return t("filter.excelXlsx")
      case "powerpoint": return t("filter.powerpoint")
      case "powerpointPptx": return t("filter.powerpointPptx")
      case "text": return t("filter.text")
      case "zip": return t("filter.zip")
    }
  }

  const {
    selectedIds,
    typeFilter,
    search,
    deleting,
    setTypeFilter,
    setSearch,
    filteredFiles,
    allSelected,
    someSelected,
    toggleAll,
    toggleOne,
    handleBatchDelete,
  } = useFileBatchOperations({
    files,
    onAfterDelete: () => router.refresh(),
  })

  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" aria-hidden="true" />
          {t("title")}
        </h2>
        <p className="text-muted-foreground">{t("subtitle")}</p>
      </div>

      <WidgetBoundary title={t("stats.totalFiles")} skeletonHeight={120}>
        <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" aria-hidden="true" />
              {t("stats.totalFiles")}
            </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" aria-hidden="true" />
              {t("stats.totalSize")}
            </div>
            <p className="mt-1 text-2xl font-bold">{formatFileSize(stats.totalSize)}</p>
          </div>
          {stats.byType.slice(0, 2).map((typeStat) => (
            <div key={typeStat.mimeType} className="rounded-md border p-4">
              <div className="flex items-center gap-2 text-xs text-muted-foreground">
                <FileIcon mimeType={typeStat.mimeType} className="h-3.5 w-3.5" />
                <span className="truncate" title={typeStat.mimeType}>
                  {typeStat.mimeType}
                </span>
              </div>
              <p className="mt-1 text-2xl font-bold">{typeStat.count}</p>
              <p className="text-xs text-muted-foreground">
                {formatFileSize(typeStat.size)}
              </p>
            </div>
          ))}
        </div>
      </WidgetBoundary>

      <WidgetBoundary title={t("title")} skeletonHeight={160}>
        <FileUpload onUploaded={() => router.refresh()} />
      </WidgetBoundary>

      <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={t("filter.byType")} />
            </SelectTrigger>
            <SelectContent>
              {TYPE_OPTIONS.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {renderTypeLabel(opt.labelKey)}
                </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"
              aria-hidden="true"
            />
            <Input
              placeholder={t("filter.search")}
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-8"
              aria-label={t("filter.search")}
            />
          </div>
        </div>
        {selectedIds.size > 0 ? (
          <div className="flex items-center gap-2">
            <Badge variant="secondary">
              {t("selection.selected", { count: selectedIds.size })}
            </Badge>
            <Button
              type="button"
              variant="destructive"
              size="sm"
              disabled={deleting}
              onClick={() => void handleBatchDelete()}
            >
              <Trash2 className="mr-2 h-4 w-4" aria-hidden="true" />
              {deleting ? t("selection.deleting") : t("selection.deleteSelected")}
            </Button>
          </div>
        ) : null}
      </div>

      <WidgetBoundary title={t("title")} skeletonHeight={400}>
        {filteredFiles.length === 0 ? (
          <EmptyState
            title={t("empty.title")}
            description={t("empty.description")}
            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={t("columns.file")}
              />
              <span className="flex-1">{t("columns.file")}</span>
              <span className="hidden w-24 sm:block">{t("columns.size")}</span>
              <span className="hidden w-32 md:block">{t("columns.type")}</span>
              <span className="hidden w-32 md:block">{t("columns.uploaded")}</span>
              <span className="w-24 text-right">{t("columns.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}
                        aria-label={`${t("columns.file")}: ${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>
        )}
      </WidgetBoundary>
    </div>
  )
}
