/**
 * Runtime proxy for /api/* → the FastAPI backend.
 *
 * This replaces the old next.config.js `rewrites()` proxy, whose destination
 * was baked into the build (routes-manifest.json) from FASTAPI_URL at build
 * time. Because one frontend image is promoted staging→prod, a baked hostname
 * forced every environment to name the backend identically; a mismatch (e.g.
 * a `backend_stg` service) produced `getaddrinfo ENOTFOUND backend`.
 *
 * A route handler reads process.env.FASTAPI_URL on each request, so the same
 * image adapts to whatever the backend is called in each environment.
 */

import { type NextRequest, NextResponse } from 'next/server';

export const dynamic = 'force-dynamic';
export const runtime = 'nodejs';

// FASTAPI_URL already includes the `/api` suffix (e.g. http://backend:80/api).
function backendBase(): string {
  return process.env.FASTAPI_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api';
}

// Hop-by-hop / length headers must not be copied across a proxy — undici has
// already decoded the body, so a stale content-encoding/length corrupts it.
const STRIPPED_RESPONSE_HEADERS = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'];
const METHODS_WITH_BODY = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);

async function handler(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
  const { path } = await ctx.params;
  const target = `${backendBase()}/${path.join('/')}${req.nextUrl.search}`;

  const headers = new Headers(req.headers);
  headers.delete('host');
  headers.delete('connection');

  const init: RequestInit & { duplex?: 'half' } = {
    method: req.method,
    headers,
    redirect: 'manual',
    cache: 'no-store',
  };
  if (METHODS_WITH_BODY.has(req.method)) {
    init.body = req.body;
    init.duplex = 'half';
  }

  let upstream: Response;
  try {
    upstream = await fetch(target, init);
  } catch (err) {
    // e.g. DNS failure or connection refused — surface a clean 502 instead of
    // an opaque proxy crash so callers can degrade gracefully.
    return NextResponse.json({ detail: 'Upstream request failed' }, { status: 502 });
  }

  const responseHeaders = new Headers(upstream.headers);
  for (const h of STRIPPED_RESPONSE_HEADERS) responseHeaders.delete(h);

  return new NextResponse(upstream.body, {
    status: upstream.status,
    statusText: upstream.statusText,
    headers: responseHeaders,
  });
}

export {
  handler as GET,
  handler as HEAD,
  handler as POST,
  handler as PUT,
  handler as PATCH,
  handler as DELETE,
  handler as OPTIONS,
};
