import { NextRequest, NextResponse } from "next/server";
import { cookies } from "next/headers";
import {
  decodeDevToken,
  handleDevOnboarding,
  shouldFallbackToDevMock,
} from "@/lib/dev-api-mock";
import { AUTH_COOKIE_NAME } from "@/lib/auth-cookie";
import { apiErrorResponse } from "@/lib/api-errors";
import { clearCookieOnUnauthorized, rejectLegacyAuthToken } from "@/lib/auth-proxy";
import { getOrCreateCorrelationId, withCorrelationId } from "@/lib/correlation-id";
import { fetchUpstream } from "@/lib/proxy-upstream";

export async function POST(req: NextRequest) {
  const correlationId = getOrCreateCorrelationId(req);
  const jar = await cookies();
  const token = jar.get(AUTH_COOKIE_NAME)?.value;

  if (!token) {
    return apiErrorResponse(401, "UNAUTHORIZED", "Unauthorized", correlationId);
  }

  const legacyReject = rejectLegacyAuthToken(token, correlationId);
  if (legacyReject) return legacyReject;

  const searchParams = req.nextUrl.searchParams;
  const forceNew = searchParams.get("forceNew") === "true";
  const bodyText = await req.text();

  if (shouldFallbackToDevMock()) {
    const user = decodeDevToken(token);
    if (!user) {
      return apiErrorResponse(401, "UNAUTHORIZED", "Unauthorized", correlationId);
    }
    const body = bodyText ? JSON.parse(bodyText) : null;
    const result = handleDevOnboarding("", "POST", body, user.id, forceNew);
    return withCorrelationId(NextResponse.json(result.data, { status: result.status }), correlationId);
  }

  const upstream = await fetchUpstream(
    `/onboarding${forceNew ? "?forceNew=true" : ""}`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      body: bodyText,
      correlationId,
    },
  );

  if (!upstream && shouldFallbackToDevMock()) {
    const user = decodeDevToken(token);
    if (!user) {
      return apiErrorResponse(401, "UNAUTHORIZED", "Unauthorized", correlationId);
    }
    const body = bodyText ? JSON.parse(bodyText) : null;
    const result = handleDevOnboarding("", "POST", body, user.id, forceNew);
    return withCorrelationId(NextResponse.json(result.data, { status: result.status }), correlationId);
  }

  if (!upstream) {
    return apiErrorResponse(
      503,
      "SERVICE_UNAVAILABLE",
      "Backend service unavailable",
      correlationId,
    );
  }

  const data = await upstream.json().catch(() => ({}));
  const response = withCorrelationId(NextResponse.json(data, { status: upstream.status }), correlationId);
  return clearCookieOnUnauthorized(response, upstream.status);
}
