"use client";

import { useState, useCallback, useRef } from "react";
import { Upload, Loader2, X, CheckCircle2, FileIcon } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";

type UploadedFile = {
  id: string;
  url: string;
  originalName: string;
  size: number;
  mimeType: string;
};

export function FileUpload({
  onUploaded,
}: {
  onUploaded?: (file: UploadedFile) => void;
}) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [uploading, setUploading] = useState(false);
  const [uploadedFiles, setUploadedFiles] = useState<UploadedFile[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [dragging, setDragging] = useState(false);

  const uploadFile = useCallback(async (file: File) => {
    setUploading(true);
    setError(null);

    const formData = new FormData();
    formData.append("file", file);

    try {
      const res = await fetch("/api/upload", {
        method: "POST",
        body: formData,
      });
      const data = await res.json();

      if (!res.ok) {
        setError(data.error ?? "上传失败");
        return;
      }

      setUploadedFiles((prev) => [data, ...prev]);
      onUploaded?.(data);
    } catch {
      setError("网络错误，上传失败");
    } finally {
      setUploading(false);
    }
  }, [onUploaded]);

  function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (file) {
      uploadFile(file);
    }
    // 重置 input 以便重复上传同一文件
    if (inputRef.current) {
      inputRef.current.value = "";
    }
  }

  function handleDrop(e: React.DragEvent) {
    e.preventDefault();
    setDragging(false);
    const file = e.dataTransfer.files?.[0];
    if (file) {
      uploadFile(file);
    }
  }

  function copyUrl(url: string) {
    navigator.clipboard.writeText(url);
  }

  function formatSize(bytes: number) {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  }

  return (
    <div className="flex flex-col gap-4">
      {/* 拖拽上传区 */}
      <div
        onDragOver={(e) => {
          e.preventDefault();
          setDragging(true);
        }}
        onDragLeave={() => setDragging(false)}
        onDrop={handleDrop}
        className={cn(
          "flex flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-8 transition-colors",
          dragging
            ? "border-primary bg-primary/5"
            : "border-muted-foreground/25 hover:border-primary/50"
        )}
      >
        <Upload className="size-8 text-muted-foreground" />
        <p className="text-sm text-muted-foreground">
          将文件拖拽到此处，或
        </p>
        <Button
          variant="outline"
          size="sm"
          disabled={uploading}
          onClick={() => inputRef.current?.click()}
        >
          {uploading ? (
            <>
              <Loader2 className="size-4 animate-spin" />
              上传中...
            </>
          ) : (
            <>
              <Upload className="size-4" />
              选择文件
            </>
          )}
        </Button>
        <p className="text-xs text-muted-foreground">
          支持任意类型文件，最大 50MB
        </p>
        <Input
          ref={inputRef}
          type="file"
          className="hidden"
          onChange={handleFileChange}
        />
      </div>

      {error && (
        <p className="text-sm text-destructive" role="alert">
          {error}
        </p>
      )}

      {/* 已上传文件列表 */}
      {uploadedFiles.length > 0 && (
        <div className="flex flex-col gap-2">
          {uploadedFiles.map((file) => (
            <div
              key={file.id}
              className="flex items-center gap-3 rounded-lg border p-3"
            >
              <CheckCircle2 className="size-5 shrink-0 text-emerald-500" />
              <FileIcon className="size-4 shrink-0 text-muted-foreground" />
              <div className="flex min-w-0 flex-1 flex-col">
                <span className="truncate text-sm font-medium">
                  {file.originalName}
                </span>
                <span className="text-xs text-muted-foreground">
                  {formatSize(file.size)} · {file.mimeType}
                </span>
              </div>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => copyUrl(file.url)}
              >
                复制链接
              </Button>
              <Button
                variant="ghost"
                size="icon-sm"
                onClick={() =>
                  setUploadedFiles((prev) =>
                    prev.filter((f) => f.id !== file.id)
                  )
                }
              >
                <X className="size-4" />
              </Button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
