import * as Sentry from "@sentry/node"

// Interface for Auth0 userinfo response
interface Auth0UserInfo {
  sub: string
  [key: string]: any
}
// Function to check if token is JWE (encrypted)
function isJWE(token: string): boolean {
  const parts = token.split(".")
  if (parts.length !== 5) return false

  try {
    const header = JSON.parse(Buffer.from(parts[0], "base64url").toString())
    return header.enc !== undefined // JWE has 'enc' field
  } catch {
    return false
  }
}

// Type guard to check if response is Auth0UserInfo
function isAuth0UserInfo(data: unknown): data is Auth0UserInfo {
  return typeof data === "object" && data !== null && "sub" in data
}

// Function to authenticate token and return userId (JWE only)
export async function userForAPIKeyAUTH(token: string): Promise<string | null> {
  try {
    console.log("[Auth] Starting token authentication")

    // Check if it's a JWE token
    if (isJWE(token)) {
      console.log("[Auth] Processing JWE token")
      return await validateJWEToken(token)
    } else {
      console.log("[Auth] Non-JWE token provided - only JWE tokens are supported")
      return null
    }
  } catch (error) {
    console.error(
      "[Auth] Authentication failed:",
      error instanceof Error ? error.message : "Unknown error",
    )
    Sentry.captureException(error)
    return null
  }
}

// Handle JWE tokens by calling Auth0's userinfo endpoint
async function validateJWEToken(token: string): Promise<string | null> {
  try {
    const response = await fetch(`${process.env.AUTH0_ISSUER_BASE_URL_CF_WEB_APP}/userinfo`, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
      },
    })

    if (!response.ok) {
      console.error("[Auth] Auth0 userinfo request failed:", {
        status: response.status,
        statusText: response.statusText,
      })
      return null
    }

    const userInfo: unknown = await response.json()

    // Type guard to ensure userInfo has the expected structure
    if (!isAuth0UserInfo(userInfo)) {
      console.warn("[Auth] Invalid userinfo response structure")
      return null
    }

    const userId = userInfo.sub

    if (!userId || typeof userId !== "string") {
      console.warn("[Auth] No valid user ID found in userinfo response")
      return null
    }

    console.log("[Auth] Successfully authenticated user via userinfo")
    return userId
  } catch (error) {
    console.error("[Auth] JWE token validation failed:")
    Sentry.captureException(error)
    return null
  }
}
