import "server-only";

type QueryParams = Record<string, string | undefined | null>;

function normalizeHost(host: string) {
  if (host === "0.0.0.0") {
    return "localhost";
  }

  if (host.startsWith("0.0.0.0:")) {
    return host.replace("0.0.0.0", "localhost");
  }

  if (host === "[::]") {
    return "localhost";
  }

  if (host.startsWith("[::]:")) {
    return host.replace("[::]", "localhost");
  }

  return host;
}

function getConfiguredOrigin() {
  const configured = process.env.APP_URL?.trim();

  if (!configured) {
    return null;
  }

  try {
    return new URL(configured).origin;
  } catch {
    return null;
  }
}

export function getRequestOrigin(request: Request) {
  const configuredOrigin = getConfiguredOrigin();

  if (configuredOrigin) {
    return configuredOrigin;
  }

  const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
  const rawHost = forwardedHost || request.headers.get("host")?.trim();
  const host = rawHost ? normalizeHost(rawHost) : null;
  const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();

  if (host) {
    const protocol = forwardedProto || "http";
    return `${protocol}://${host}`;
  }

  try {
    const requestUrl = new URL(request.url);
    const normalizedHost = normalizeHost(requestUrl.host);
    return `${requestUrl.protocol}//${normalizedHost}`;
  } catch {
    return "http://localhost:3000";
  }
}

export function buildAppUrl(request: Request, path: string, params: QueryParams = {}) {
  const url = new URL(path, getRequestOrigin(request));

  Object.entries(params).forEach(([key, value]) => {
    if (value) {
      url.searchParams.set(key, value);
    }
  });

  return url;
}
