import type { Download } from "../types";
import * as api from "../api";

/**
 * What is being downloaded, and what just was.
 *
 * WebKit saves the file on its own and says nothing about it, so without this
 * a download is indistinguishable from a click that did nothing.
 */
export default function Downloads({
  items,
  onDismiss,
}: {
  items: Download[];
  onDismiss: (id: number) => void;
}) {
  if (items.length === 0) return null;

  return (
    <div className="pointer-events-none fixed bottom-4 right-4 z-[80] flex w-[320px] flex-col gap-2">
      {items.map((d) => (
        <div
          key={d.id}
          className="pointer-events-auto flex items-center gap-3 rounded-xl border border-slate-200
                     bg-white/95 px-3 py-2.5 shadow-xl backdrop-blur
                     dark:border-slate-800 dark:bg-slate-900/95"
        >
          <span className="grid size-8 shrink-0 place-items-center rounded-lg bg-slate-100 dark:bg-slate-800">
            {d.state === "done" ? (
              <svg viewBox="0 0 24 24" className="size-4 text-emerald-500" fill="none"
                stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M5 13l4 4L19 7" />
              </svg>
            ) : d.state === "failed" ? (
              <svg viewBox="0 0 24 24" className="size-4 text-red-500" fill="none"
                stroke="currentColor" strokeWidth="2.2" strokeLinecap="round">
                <path d="M6 6l12 12M18 6L6 18" />
              </svg>
            ) : (
              /* No total to divide by — the webview reports a start and a
                 finish and nothing between — so this spins rather than fills. */
              <svg viewBox="0 0 24 24" className="size-4 animate-spin text-sky-500" fill="none">
                <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="2.5" className="opacity-25" />
                <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" />
              </svg>
            )}
          </span>

          <span className="min-w-0 flex-1">
            <span className="block truncate text-[12px] font-medium">{d.name}</span>
            <span className="block text-[11px] text-slate-500 dark:text-slate-400">
              {d.state === "done"
                ? "Downloaded"
                : d.state === "failed"
                  ? "Download failed"
                  : d.bytes > 0
                    ? `${formatBytes(d.bytes)} so far`
                    : "Starting…"}
            </span>
          </span>

          {d.state === "done" && (
            <button
              onClick={() => api.reveal(d.path)}
              title="Show in Finder"
              className="shrink-0 cursor-pointer rounded-lg px-2 py-1 text-[11px] font-medium
                         text-sky-600 hover:bg-sky-500/10 dark:text-sky-400"
            >
              Show
            </button>
          )}
          <button
            onClick={() => onDismiss(d.id)}
            title="Dismiss"
            aria-label="Dismiss"
            className="shrink-0 cursor-pointer rounded-lg p-1 text-slate-400 hover:text-slate-700
                       dark:hover:text-slate-200"
          >
            <svg viewBox="0 0 24 24" className="size-3.5" fill="none" stroke="currentColor"
              strokeWidth="2" strokeLinecap="round">
              <path d="M6 6l12 12M18 6L6 18" />
            </svg>
          </button>
        </div>
      ))}
    </div>
  );
}

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