import { NextResponse } from "next/server";

import { getSessionUser, requireSessionUser } from "@/lib/auth";
import {
  getLocaleOption,
  LOCALE_COOKIE_NAME,
  normalizeSupportedLocale,
} from "@/lib/i18n-config";
import { resolveRequestLocale } from "@/lib/i18n-server";
import {
  getPublicSiteUrl,
  isLocalOrigin,
  resolveOriginFromHeaders,
} from "@/lib/mail-urls";
import { updatePreferredLocaleByEmail } from "@/lib/official-mail";

function localeCookieDomain(request: Request) {
  const requestOrigin = resolveOriginFromHeaders(request.headers, getPublicSiteUrl());

  if (isLocalOrigin(requestOrigin)) {
    return undefined;
  }

  try {
    const hostname = new URL(getPublicSiteUrl()).hostname.toLowerCase();

    if (hostname === "officialsite.kr" || hostname.endsWith(".officialsite.kr")) {
      return ".officialsite.kr";
    }

    return undefined;
  } catch {
    return undefined;
  }
}

function responseWithLocaleCookie(
  request: Request,
  locale: NonNullable<ReturnType<typeof normalizeSupportedLocale>>,
) {
  const response = NextResponse.json({
    ok: true,
    locale,
    htmlLang: getLocaleOption(locale).htmlLang,
  });

  response.cookies.set(LOCALE_COOKIE_NAME, locale, {
    domain: localeCookieDomain(request),
    expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
    httpOnly: true,
    path: "/",
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
  });

  return response;
}

export async function GET() {
  const user = await getSessionUser();
  const locale = await resolveRequestLocale(user?.preferredLocale);

  return NextResponse.json({
    explicit: Boolean(user?.preferredLocale),
    locale,
    htmlLang: getLocaleOption(locale).htmlLang,
  });
}

export async function POST(request: Request) {
  const user = await requireSessionUser();
  const locale = normalizeSupportedLocale(user.preferredLocale);

  if (!locale) {
    return NextResponse.json({ ok: true, locale: null });
  }

  return responseWithLocaleCookie(request, locale);
}

export async function PUT(request: Request) {
  const user = await requireSessionUser();
  const payload = (await request.json().catch(() => null)) as { locale?: unknown } | null;
  const locale = normalizeSupportedLocale(
    typeof payload?.locale === "string" ? payload.locale : null,
  );

  if (!locale) {
    return NextResponse.json(
      { ok: false, message: "Unsupported language." },
      { status: 400 },
    );
  }

  await updatePreferredLocaleByEmail(user.email, locale);

  return responseWithLocaleCookie(request, locale);
}
