import { useEffect, useState } from 'react';
import { authFetch } from './auth';

/**
 * Resolve a same-origin `/api/files/*` path into a blob object URL that was fetched
 * WITH the `Authorization: Bearer <token>` header.
 *
 * Why this exists: `/api/files/*` requires auth (it used to be an unauthenticated GET
 * but was closed off in the "leaky endpoints" hardening). Native `<img>`/`<audio>`
 * elements cannot attach a Bearer token to their `src` request, so a raw
 * `<img src="/api/files/...">` now 401s and the picture/audio never loads. Fetching the
 * file through `authFetch` (token in the header, never in the URL — so no new token-leak
 * surface) and handing back a `blob:` object URL is the secure way to render it.
 *
 * `data:`, `blob:`, and other non-`/api/files` inputs (and `undefined`) pass through
 * unchanged. The created object URL is revoked when the input changes or the component
 * unmounts. Returns `undefined` while the fetch is in flight or if it failed, so callers
 * can show a placeholder.
 */
export function useAuthedFileUrl(rawUrl: string | undefined): string | undefined {
  const requiresAuthedFetch = !!rawUrl && rawUrl.startsWith('/api/files/');
  const [resolvedUrl, setResolvedUrl] = useState<string | undefined>(
    requiresAuthedFetch ? undefined : rawUrl,
  );

  useEffect(() => {
    // Pass through anything that isn't a protected file path (data:/blob:/undefined).
    if (!rawUrl || !rawUrl.startsWith('/api/files/')) {
      setResolvedUrl(rawUrl);
      return;
    }

    let createdObjectUrl: string | null = null;
    let cancelled = false;
    setResolvedUrl(undefined);

    (async () => {
      try {
        const response = await authFetch(rawUrl);
        if (!response.ok) return; // leave undefined → caller shows a placeholder
        const blob = await response.blob();
        if (cancelled) return;
        createdObjectUrl = URL.createObjectURL(blob);
        setResolvedUrl(createdObjectUrl);
      } catch {
        /* network error — leave undefined so the caller renders its placeholder */
      }
    })();

    return () => {
      cancelled = true;
      if (createdObjectUrl) URL.revokeObjectURL(createdObjectUrl);
    };
  }, [rawUrl]);

  return resolvedUrl;
}
