import { NextRequest } from "next/server";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export const revalidate = 0;

/**
 * Image proxy: serves files from Supabase Storage under a clean avbeat.com
 * URL so article HTML doesn't ship the long `https://supabase.onsethost.com/
 * storage/v1/object/public/...` path. Better for SEO + makes images look
 * first-party.
 *
 * Usage: /img/distribute-media/<uuid>/<file>.jpg
 *        /img/campaign-creatives/<uuid>/<file>.jpg
 *        /img/bb-forum-avatars/<file>.png
 *
 * Resilience rules (prior bug):
 *   - Supabase storage occasionally returns transient 5xx. We retry up to 2x
 *     with backoff before surfacing failure.
 *   - Failures MUST emit no-store cache headers, otherwise Next + Cloudflare
 *     pin the failure indefinitely (page itself had s-maxage of one year).
 *   - The route must be dynamic — force-static used to pre-bake a single
 *     fetch result at build time, which is exactly the bug we hit.
 */
const SUPABASE_BASE = (process.env.NEXT_PUBLIC_SUPABASE_URL || "https://supabase.onsethost.com")
  .replace(/\/+$/, "") + "/storage/v1/object/public";

async function fetchWithRetry(url: string, tries = 3): Promise<Response> {
  let lastErr: unknown = null;
  for (let i = 0; i < tries; i++) {
    try {
      const r = await fetch(url, { cache: "no-store" });
      if (r.ok) return r;
      if (r.status === 404) return r;
      // 5xx — back off and retry
      lastErr = new Error(`upstream ${r.status}`);
    } catch (e) {
      lastErr = e;
    }
    if (i < tries - 1) await new Promise((res) => setTimeout(res, 150 * (i + 1)));
  }
  throw lastErr instanceof Error ? lastErr : new Error("upstream failed");
}

function failResponse(status: number, body: string) {
  return new Response(body, {
    status,
    headers: {
      "content-type": "text/plain; charset=utf-8",
      // Critical: never cache failures.
      "cache-control": "no-store, max-age=0",
      "x-bb-img-source": "proxy-error",
    },
  });
}

export async function GET(_req: NextRequest, { params }: { params: Promise<{ path: string[] }> }) {
  const { path } = await params;
  if (!path || path.length < 2) return failResponse(400, "bad path");

  const target = `${SUPABASE_BASE}/${path.map(encodeURIComponent).join("/")}`;
  let upstream: Response;
  try {
    upstream = await fetchWithRetry(target, 3);
  } catch (e: any) {
    return failResponse(502, "upstream error after retries: " + (e?.message || String(e)));
  }
  if (!upstream.ok) {
    return failResponse(upstream.status === 404 ? 404 : 502, "not found");
  }

  return new Response(upstream.body, {
    status: 200,
    headers: {
      "content-type": upstream.headers.get("content-type") || "image/jpeg",
      "cache-control": "public, max-age=86400, s-maxage=86400, stale-while-revalidate=604800",
      "x-bb-img-source": "supabase-storage",
    },
  });
}
