"use client";

import { useParams, useRouter } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";

import { api } from "@/lib/api/client";
import type { components } from "@/lib/api/schema";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";

type Media = components["schemas"]["MediaRead"];

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

export default function MediaPage() {
  const router = useRouter();
  const params = useParams<{ id: string }>();
  const treeId = params.id;

  const [items, setItems] = useState<Media[]>([]);
  const [ready, setReady] = useState(false);
  const [uploading, setUploading] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  const load = useCallback(async () => {
    const { data, response } = await api.GET("/api/v1/trees/{tree_id}/media", {
      params: { path: { tree_id: treeId } },
    });
    if (response.status === 401) {
      router.push("/login");
      return;
    }
    setItems(data ?? []);
    setReady(true);
  }, [router, treeId]);

  useEffect(() => {
    load();
  }, [load]);

  async function onFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    const fd = new FormData();
    fd.append("file", file);
    // Plain fetch for multipart (same origin → cookie auth via Caddy).
    await fetch(`/api/v1/trees/${treeId}/media`, {
      method: "POST",
      body: fd,
      credentials: "include",
    });
    setUploading(false);
    if (fileRef.current) fileRef.current.value = "";
    load();
  }

  async function remove(id: string) {
    await api.DELETE("/api/v1/trees/{tree_id}/media/{media_id}", {
      params: { path: { tree_id: treeId, media_id: id } },
    });
    load();
  }

  if (!ready) return <p className="text-[var(--muted)]">Loading…</p>;

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h1 className="text-2xl font-semibold">Media</h1>
        <div>
          <input
            ref={fileRef}
            type="file"
            onChange={onFile}
            className="hidden"
            id="media-upload"
          />
          <Button onClick={() => fileRef.current?.click()} disabled={uploading}>
            {uploading ? "Uploading…" : "Upload file"}
          </Button>
        </div>
      </div>

      {items.length === 0 ? (
        <p className="text-[var(--muted)]">
          No media yet — upload scans, photos, or documents and attach them to facts.
        </p>
      ) : (
        <div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4">
          {items.map((m) => (
            <Card key={m.id} className="overflow-hidden">
              <a href={m.url ?? "#"} target="_blank" rel="noreferrer" className="block">
                {m.content_type.startsWith("image/") ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={m.url ?? ""}
                    alt={m.title ?? m.original_filename}
                    className="aspect-square w-full object-cover"
                  />
                ) : (
                  <div className="grid aspect-square w-full place-items-center bg-bronze/[0.06] text-3xl font-serif text-bronze">
                    {(m.original_filename.split(".").pop() ?? "file").toUpperCase()}
                  </div>
                )}
              </a>
              <CardContent className="p-3">
                <div className="flex items-start justify-between gap-2">
                  <div className="min-w-0">
                    <div className="truncate text-sm font-medium" title={m.original_filename}>
                      {m.title ?? m.original_filename}
                    </div>
                    <div className="text-xs text-[var(--muted)]">{humanSize(m.byte_size)}</div>
                  </div>
                  <button
                    onClick={() => remove(m.id)}
                    className="text-[var(--muted)] hover:text-bronze"
                    aria-label="Remove"
                  >
                    ×
                  </button>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}
