"use client";

import { useRef, useState } from "react";
import type { Download } from "@/lib/posts";

// Manages a post's download section: a mix of uploaded files and external links.
// Uploads POST to /admin/upload and come back as a /uploads/<name> URL; external
// links are entered by hand. The whole list is serialized to a hidden input
// (name="downloads") as JSON, mirroring the console/game pickers' pattern.

function formatSize(bytes?: number): string {
  if (!bytes && bytes !== 0) return "";
  const units = ["B", "KB", "MB", "GB"];
  let n = bytes;
  let u = 0;
  while (n >= 1024 && u < units.length - 1) {
    n /= 1024;
    u++;
  }
  return `${n >= 10 || u === 0 ? Math.round(n) : n.toFixed(1)} ${units[u]}`;
}

export default function DownloadEditor({
  name,
  initial,
}: {
  name: string;
  initial: Download[];
}) {
  const [items, setItems] = useState<Download[]>(initial);
  const [linkLabel, setLinkLabel] = useState("");
  const [linkUrl, setLinkUrl] = useState("");
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  function setLabel(idx: number, label: string) {
    setItems((prev) => prev.map((it, i) => (i === idx ? { ...it, label } : it)));
  }

  function remove(idx: number) {
    setItems((prev) => prev.filter((_, i) => i !== idx));
  }

  function addLink() {
    const url = linkUrl.trim();
    if (!url) return;
    setItems((prev) => [
      ...prev,
      { label: linkLabel.trim() || url, url, kind: "link" },
    ]);
    setLinkLabel("");
    setLinkUrl("");
  }

  async function onFiles(files: FileList | null) {
    if (!files || files.length === 0) return;
    setError(null);
    setUploading(true);
    try {
      for (const file of Array.from(files)) {
        const fd = new FormData();
        fd.append("file", file);
        const res = await fetch("/admin/upload", { method: "POST", body: fd });
        if (!res.ok) {
          const j = (await res.json().catch(() => ({}))) as { error?: string };
          throw new Error(j.error || `upload failed (${res.status})`);
        }
        const j = (await res.json()) as { url: string; filename: string; size: number };
        setItems((prev) => [
          ...prev,
          { label: j.filename, url: j.url, kind: "file", size: j.size, filename: j.filename },
        ]);
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "upload failed");
    } finally {
      setUploading(false);
      if (fileRef.current) fileRef.current.value = "";
    }
  }

  return (
    <div className="rb-dl">
      <input type="hidden" name={name} value={JSON.stringify(items)} />

      {items.length > 0 && (
        <ul className="rb-dl-list">
          {items.map((it, i) => (
            <li key={`${it.url}-${i}`} className="rb-dl-row">
              <span className="rb-dl-kind" aria-hidden>
                {it.kind === "file" ? "📦" : "🔗"}
              </span>
              <input
                className="rb-dl-label"
                type="text"
                value={it.label}
                placeholder="Download label"
                onChange={(e) => setLabel(i, e.target.value)}
              />
              <a className="rb-dl-url" href={it.url} target="_blank" rel="noreferrer" title={it.url}>
                {it.kind === "file" ? it.filename ?? it.url : it.url}
              </a>
              {it.size != null && <span className="rb-dl-size">{formatSize(it.size)}</span>}
              <button
                type="button"
                className="rb-dl-remove"
                aria-label={`Remove ${it.label}`}
                onClick={() => remove(i)}
              >
                ✕
              </button>
            </li>
          ))}
        </ul>
      )}

      <div className="rb-dl-add">
        <div className="rb-dl-add-row">
          <input
            type="text"
            className="rb-dl-add-label"
            value={linkLabel}
            placeholder="Label (optional)"
            onChange={(e) => setLinkLabel(e.target.value)}
          />
          <input
            type="url"
            className="rb-dl-add-url"
            value={linkUrl}
            placeholder="https://example.com/file.zip"
            onChange={(e) => setLinkUrl(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                e.preventDefault();
                addLink();
              }
            }}
          />
          <button type="button" className="rb-btn rb-btn-inline" onClick={addLink}>
            Add link
          </button>
        </div>

        <div className="rb-dl-add-row">
          <input
            ref={fileRef}
            type="file"
            multiple
            className="rb-dl-file"
            disabled={uploading}
            onChange={(e) => onFiles(e.target.files)}
          />
          {uploading && <span className="rb-dl-status">Uploading…</span>}
        </div>

        {error && <p className="rb-admin-error rb-dl-error">{error}</p>}
      </div>
    </div>
  );
}
