"use client";
import { useCallback, useState } from "react";
import { useDropzone } from "react-dropzone";
import { UploadCloud, Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";

function stringifyApiError(value: unknown): string | null {
  if (!value) return null;
  if (typeof value === "string") return value;
  if (Array.isArray(value)) {
    const parts = value
      .map((item) => {
        if (typeof item === "string") return item;
        if (item && typeof item === "object" && "msg" in item) {
          return String((item as { msg: unknown }).msg);
        }
        return JSON.stringify(item);
      })
      .filter(Boolean);
    return parts.join("; ");
  }
  if (typeof value === "object") return JSON.stringify(value);
  return String(value);
}

export function FileUploader({ onUploaded }: { onUploaded: () => void }) {
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [progress, setProgress] = useState<string | null>(null);

  const upload = useCallback(
    async (files: File[]) => {
      setError(null);
      setBusy(true);
      try {
        for (let i = 0; i < files.length; i++) {
          const f = files[i];
          setProgress(`Uploading ${i + 1}/${files.length}: ${f.name}`);
          const fd = new FormData();
          fd.append("file", f);
          const r = await fetch("/api/upload", { method: "POST", body: fd });
          if (!r.ok) {
            const contentType = r.headers.get("content-type") ?? "";
            let message = "Upload failed";

            if (contentType.includes("application/json")) {
              const payload = (await r.json().catch(() => null)) as
                | { detail?: unknown; error?: unknown }
                | null;
              message =
                stringifyApiError(payload?.detail) ??
                stringifyApiError(payload?.error) ??
                message;
            } else {
              message = (await r.text()).trim() || message;
            }

            throw new Error(`${f.name}: ${message}`);
          }
        }
        onUploaded();
      } catch (e) {
        setError((e as Error).message);
      } finally {
        setBusy(false);
        setProgress(null);
      }
    },
    [onUploaded]
  );

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    accept: { "application/pdf": [".pdf"] },
    multiple: true,
    disabled: busy,
    onDrop: upload,
  });

  return (
    <div className="space-y-2">
      <div
        {...getRootProps()}
        className={cn(
          "flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed p-10 text-center transition-colors",
          isDragActive ? "border-primary bg-accent" : "border-border hover:bg-accent/50",
          busy && "pointer-events-none opacity-60"
        )}
      >
        <input {...getInputProps()} />
        {busy ? (
          <Loader2 className="mb-2 h-8 w-8 animate-spin text-muted-foreground" />
        ) : (
          <UploadCloud className="mb-2 h-8 w-8 text-muted-foreground" />
        )}
        <p className="text-sm font-medium">
          {busy
            ? progress ?? "Uploading…"
            : isDragActive
            ? "Drop the PDFs here"
            : "Drag & drop PDFs here, or click to select"}
        </p>
        <p className="mt-1 text-xs text-muted-foreground">
          Files are pushed to your linked Hugging Face Dataset and indexed automatically.
        </p>
      </div>
      {error && <p className="text-sm text-destructive">{error}</p>}
    </div>
  );
}
