import { useEffect, useState, type ImgHTMLAttributes } from 'react';
import { apiFetch } from '@/utils/api';

// Browsers cannot attach Authorization headers to <img src="..."> requests, but
// Caddy's forward_auth gate (Phase 6.7 / 9.2) demands a Bearer on /uploads/*.
// AuthedImage fetches gated URLs through apiFetch (which adds the Bearer), then
// renders the bytes via an object URL. Non-gated URLs (CDN, external) pass
// straight through to a plain <img>.

const GATED_PATH_PATTERN = /\/uploads\//;

function needsAuth(src: string | undefined): boolean {
  if (!src) return false;
  return GATED_PATH_PATTERN.test(src);
}

// /uploads/* URLs are stored absolute in the DB (https://tools.acherryontop.com/...).
// Strip the origin so the request goes through the vite dev proxy in dev and stays
// same-origin in prod — either way no CORS preflight on the fetch.
function toFetchUrl(src: string): string {
  try {
    const parsed = new URL(src, window.location.origin);
    return parsed.pathname + parsed.search;
  } catch {
    return src;
  }
}

type AuthedImageProps = ImgHTMLAttributes<HTMLImageElement> & { src?: string };

export function AuthedImage({ src, alt, ...rest }: AuthedImageProps) {
  const [resolvedSrc, setResolvedSrc] = useState<string | undefined>(
    needsAuth(src) ? undefined : src,
  );

  useEffect(() => {
    if (!needsAuth(src)) {
      setResolvedSrc(src);
      return;
    }

    let objectUrl: string | undefined;
    let cancelled = false;

    (async () => {
      try {
        const res = await apiFetch(toFetchUrl(src!));
        if (!res.ok) {
          if (!cancelled) setResolvedSrc(undefined);
          return;
        }
        const blob = await res.blob();
        if (cancelled) return;
        objectUrl = URL.createObjectURL(blob);
        setResolvedSrc(objectUrl);
      } catch {
        if (!cancelled) setResolvedSrc(undefined);
      }
    })();

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

  return <img src={resolvedSrc} alt={alt} {...rest} />;
}
