import { NextResponse } from "next/server";

const SPRING_BASE =
    process.env.SPRING_BASE_URL ?? "http://battlbuilder-api:8080";

function forwardHeaders(req: Request) {
    const headers = new Headers();
    const auth = req.headers.get("authorization");
    const cookie = req.headers.get("cookie");

    if (auth) headers.set("authorization", auth);
    if (cookie) headers.set("cookie", cookie);

    headers.set("accept", "application/json");
    return headers;
}

type SpringProxyOptions<TBody> = {
    method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
    body?: TBody;
    cache?: RequestCache;
};

export async function springProxy<TResponse, TBody = never>(
    req: Request,
    path: string,
    options?: SpringProxyOptions<TBody>
) {
    const url = `${SPRING_BASE}${path}`;
    const headers = forwardHeaders(req);

    const init: RequestInit = {
        method: options?.method ?? "GET",
        headers,
        cache: options?.cache ?? "no-store",
    };

    if (options && "body" in options && options.body !== undefined) {
        headers.set("content-type", "application/json");
        init.body = JSON.stringify(options.body);
    }

    const res = await fetch(url, init);

    // If Spring returns 204 No Content, don't try to parse JSON
    if (res.status === 204) {
        return new NextResponse(null, { status: 204 });
    }

    const contentType = res.headers.get("content-type") ?? "";
    let payload: unknown;

    if (contentType.includes("application/json")) {
        payload = await res.json().catch(() => null);
    } else {
        payload = await res.text().catch(() => null);
    }

    // If Spring returned JSON, we respond JSON; otherwise text
    if (typeof payload === "string") {
        return new NextResponse(payload, {
            status: res.status,
            headers: { "content-type": contentType || "text/plain" },
        });
    }

    return NextResponse.json(payload as TResponse, { status: res.status });
}
