import type { MediaClient, MediaItem } from '@platform-modules/uploads-react';
import { UploadRejectedError } from '@platform-modules/uploads-react';

async function readError(res: Response): Promise<string> {
  try {
    const body = (await res.json()) as { error?: { code?: string } };
    return body.error?.code ?? `http_${res.status}`;
  } catch {
    return `http_${res.status}`;
  }
}

/** Same-origin client. CSRF is satisfied by the same-origin cookie + Origin header the browser sends. */
export function createHostMediaClient(): MediaClient {
  return {
    async upload(file, opts): Promise<MediaItem> {
      const fd = new FormData();
      fd.set('file', file);
      const res = await fetch('/api/admin/media', { method: 'POST', body: fd, signal: opts?.signal });
      if (!res.ok) throw new UploadRejectedError(await readError(res), res.status);
      return ((await res.json()) as { item: MediaItem }).item;
    },
    async list(opts): Promise<{ items: MediaItem[]; cursor?: string }> {
      const qs = new URLSearchParams();
      if (opts?.cursor) qs.set('cursor', opts.cursor);
      if (opts?.limit) qs.set('limit', String(opts.limit));
      const res = await fetch(`/api/admin/media?${qs.toString()}`);
      if (!res.ok) throw new Error(`list failed: ${res.status}`);
      return (await res.json()) as { items: MediaItem[]; cursor?: string };
    },
    async remove(key): Promise<void> {
      // Catch-all [...key] route: keep '/' as path separators, escape only unsafe chars WITHIN each
      // segment. NOT encodeURIComponent(key) — that would turn slashes into %2F and miss the route.
      const path = key.split('/').map(encodeURIComponent).join('/');
      const res = await fetch(`/api/admin/media/${path}`, { method: 'DELETE' });
      if (!res.ok && res.status !== 404) throw new Error(`delete failed: ${res.status}`);
    },
  };
}
