import { cookies } from "next/headers"
import { NextResponse } from "next/server"
import { createPkcePair, randomString } from "@/lib/auth/pkce"
import { platformUserFromToken } from "@/lib/auth/jwt-claims"
import { resolveOidcConfig, getAppOrigin } from "@/lib/auth/oidc-config"
import { sessionCookieOptions } from "@/lib/auth/session"

const PKCE_COOKIE = "ulti_pkce_verifier"
const STATE_COOKIE = "ulti_oauth_state"
const INTENT_COOKIE = "ulti_auth_intent"
const PREVIOUS_SUB_COOKIE = "ulti_auth_previous_sub"
const COOKIE_MAX_AGE = 600

function oauthCookieOptions() {
  return {
    ...sessionCookieOptions(),
    maxAge: COOKIE_MAX_AGE,
  }
}

export async function GET(request: Request) {
  let cfg
  try {
    cfg = await resolveOidcConfig()
  } catch (err) {
    const message =
      err instanceof Error ? err.message : "oidc_discovery_failed"
    return NextResponse.redirect(
      new URL(
        `/login?error=${encodeURIComponent(message)}`,
        getAppOrigin()
      )
    )
  }
  const { verifier, challenge } = await createPkcePair()
  const state = randomString(16)
  const requestUrl = new URL(request.url)
  const returnTo = requestUrl.searchParams.get("returnTo") ?? "/mail/inbox"
  const intent = requestUrl.searchParams.get("intent")
  const prompt =
    requestUrl.searchParams.get("prompt") ??
    (intent === "add_account" ? "login select_account" : "select_account")

  const jar = await cookies()
  const existingUser = platformUserFromToken(
    jar.get("ulti_access_token")?.value ?? ""
  )

  const params = new URLSearchParams({
    client_id: cfg.clientId,
    redirect_uri: cfg.redirectUri,
    response_type: "code",
    scope: "openid profile email offline_access",
    state,
    code_challenge: challenge,
    code_challenge_method: "S256",
    prompt,
  })

  const response = NextResponse.redirect(
    `${cfg.authorizationEndpoint}?${params.toString()}`
  )
  const cookieOpts = oauthCookieOptions()
  response.cookies.set(PKCE_COOKIE, verifier, cookieOpts)
  response.cookies.set(STATE_COOKIE, state, cookieOpts)
  response.cookies.set("ulti_auth_return", returnTo, cookieOpts)
  if (intent === "add_account") {
    response.cookies.set(INTENT_COOKIE, "add_account", cookieOpts)
    if (existingUser?.sub) {
      response.cookies.set(PREVIOUS_SUB_COOKIE, existingUser.sub, cookieOpts)
    }
  }

  return response
}
