import { cookies } from "next/headers";
import { NextResponse } from "next/server";

const ACCESS_TOKEN_COOKIE = "access_token";
const DEFAULT_COOKIE_MAX_AGE_SECONDS = 60 * 60;

export function getHermesUrl() {
  return process.env.HERMES_INTERNAL_URL?.replace(/\/$/, "") ?? null;
}

export async function getAccessToken() {
  const cookieStore = await cookies();
  return cookieStore.get(ACCESS_TOKEN_COOKIE)?.value;
}

function isSecureCookieEnabled() {
  if (process.env.AUTH_COOKIE_SECURE) {
    return process.env.AUTH_COOKIE_SECURE !== "false";
  }

  return process.env.NODE_ENV === "production";
}

function normalizeMaxAge(maxAge?: number) {
  if (typeof maxAge !== "number" || !Number.isFinite(maxAge) || maxAge <= 0) {
    return DEFAULT_COOKIE_MAX_AGE_SECONDS;
  }

  return Math.floor(maxAge);
}

export function setAuthCookie(response: NextResponse, token: string, maxAge: number) {
  response.cookies.set({
    name: ACCESS_TOKEN_COOKIE,
    value: token,
    httpOnly: true,
    secure: isSecureCookieEnabled(),
    sameSite: "lax",
    path: "/",
    maxAge: normalizeMaxAge(maxAge),
  });
}

export function clearAuthCookie(response: NextResponse) {
  response.cookies.set({
    name: ACCESS_TOKEN_COOKIE,
    value: "",
    httpOnly: true,
    secure: isSecureCookieEnabled(),
    sameSite: "lax",
    path: "/",
    maxAge: 0,
  });
}

export function unauthorizedResponse() {
  return NextResponse.json(
    { detail: "Nicht authentifiziert" },
    { status: 401 },
  );
}

export function upstreamUnavailableResponse() {
  return NextResponse.json(
    { detail: "Hermes ist nicht erreichbar" },
    { status: 502 },
  );
}

export function upstreamConfigurationErrorResponse() {
  return NextResponse.json(
    { detail: "Hermes ist nicht konfiguriert" },
    { status: 500 },
  );
}

export async function readJson(response: Response) {
  const text = await response.text();

  if (!text) {
    return null;
  }

  try {
    return JSON.parse(text);
  } catch {
    return { detail: text };
  }
}

export async function hermesJsonResponse(response: Response) {
  if (response.status === 204) {
    return new NextResponse(null, {
      status: 204,
    });
  }

  const body = await readJson(response);

  return NextResponse.json(body, {
    status: response.status,
  });
}
