"use client";

import { FormEvent, useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/admin/page-header";
import { FormCard, SelectField, TextInput } from "@/components/admin/form-fields";
import { apiFetch } from "@/lib/admin-api";

type MediaItem = {
  id: string;
  filename: string;
  originalName: string;
  path: string;
  mimeType: string;
  size: number;
  folder: string;
  alt?: string | null;
};

const FOLDERS = ["ROOT", "PRODUCTS", "ARTICLES", "BANNERS", "LOGOS", "OTHER"].map((v) => ({
  value: v,
  label: v,
}));

export default function AdminMediaPage() {
  const [items, setItems] = useState<MediaItem[]>([]);
  const [folder, setFolder] = useState("ROOT");
  const [q, setQ] = useState("");
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState("");
  const [alt, setAlt] = useState("");

  async function load() {
    const data = await apiFetch<{ items: MediaItem[] }>(
      `/api/media?limit=48&folder=${folder}${q ? `&q=${encodeURIComponent(q)}` : ""}`,
    );
    setItems(data.items);
  }

  useEffect(() => {
    load().catch((err) => setError(err instanceof Error ? err.message : "Failed to load"));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [folder]);

  async function onUpload(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const form = e.currentTarget;
    const fileInput = form.elements.namedItem("file") as HTMLInputElement;
    const file = fileInput.files?.[0];
    if (!file) return;

    setUploading(true);
    setError("");
    try {
      const body = new FormData();
      body.append("file", file);
      body.append("folder", folder);
      if (alt) body.append("alt", alt);

      const res = await fetch("/api/media", { method: "POST", body, credentials: "include" });
      const json = await res.json();
      if (!res.ok || !json.success) throw new Error(json.message || "Upload failed");
      form.reset();
      setAlt("");
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Upload failed");
    } finally {
      setUploading(false);
    }
  }

  async function rename(id: string, current: string) {
    const name = prompt("New name (without extension)", current.replace(/\.[^.]+$/, ""));
    if (!name) return;
    await apiFetch(`/api/media/${id}`, { method: "PATCH", json: { name } });
    await load();
  }

  async function remove(id: string) {
    if (!confirm("Delete this file?")) return;
    await apiFetch(`/api/media/${id}`, { method: "DELETE" });
    await load();
  }

  function copyPath(path: string) {
    navigator.clipboard.writeText(path).catch(() => undefined);
  }

  return (
    <div>
      <PageHeader title="Media library" description="Upload and manage assets" />

      <FormCard title="Upload" className="mb-6">
        <form onSubmit={onUpload} className="grid gap-4 md:grid-cols-4">
          <SelectField
            label="Folder"
            name="folder"
            options={FOLDERS}
            value={folder}
            onChange={(e) => setFolder(e.target.value)}
          />
          <TextInput label="Alt text" name="alt" value={alt} onChange={(e) => setAlt(e.target.value)} />
          <label className="block space-y-1.5 md:col-span-2">
            <span className="text-sm font-medium">File</span>
            <input
              type="file"
              name="file"
              required
              accept="image/*,application/pdf"
              className="w-full rounded-xl border border-border bg-bg px-3 py-2 text-sm"
            />
          </label>
          <div className="md:col-span-4">
            <Button type="submit" disabled={uploading}>
              {uploading ? "Uploading…" : "Upload"}
            </Button>
          </div>
        </form>
        {error ? <p className="mt-3 text-sm text-danger">{error}</p> : null}
      </FormCard>

      <div className="mb-4 flex flex-wrap gap-2">
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          onKeyDown={(e) => e.key === "Enter" && load()}
          placeholder="Search files…"
          className="h-11 rounded-xl border border-border bg-bg px-3 text-sm outline-none focus:border-accent"
        />
        <Button type="button" variant="secondary" onClick={() => load()}>
          Search
        </Button>
      </div>

      <div className="grid gap-4 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4">
        {items.map((item) => (
          <div key={item.id} className="overflow-hidden rounded-2xl border border-border bg-surface">
            <div className="flex h-36 items-center justify-center bg-bg">
              {item.mimeType.startsWith("image/") ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img src={item.path} alt={item.alt || item.filename} className="h-full w-full object-cover" />
              ) : (
                <span className="text-sm text-muted">{item.mimeType}</span>
              )}
            </div>
            <div className="space-y-2 p-3">
              <p className="truncate text-sm font-medium">{item.originalName}</p>
              <p className="truncate text-xs text-muted">{item.path}</p>
              <div className="flex flex-wrap gap-2 text-xs">
                <button className="text-accent hover:underline" onClick={() => copyPath(item.path)}>
                  Copy URL
                </button>
                <button className="text-muted hover:underline" onClick={() => rename(item.id, item.filename)}>
                  Rename
                </button>
                <button className="text-danger hover:underline" onClick={() => remove(item.id)}>
                  Delete
                </button>
              </div>
            </div>
          </div>
        ))}
      </div>
      {!items.length ? <p className="mt-8 text-center text-sm text-muted">No media files</p> : null}
    </div>
  );
}
