import { cookies, headers } from "next/headers"
import { type Session } from "next-auth"
import { cache } from "react"

import { auth } from "@/auth"

import type { Lang } from "@/constants/languages"

typeof auth

type CreateContextOptions = {
  auth: () => Promise<Session | null>
  lang: Lang
  pathname: string
  uid?: string | null
  url: string
  webToken?: string
  contentType?: string
}

/** Use this helper for:
 * - testing, where we dont have to Mock Next.js' req/res
 * - trpc's `createSSGHelpers` where we don't have req/res
 **/
export function createContextInner(opts: CreateContextOptions) {
  return {
    auth: opts.auth,
    lang: opts.lang,
    pathname: opts.pathname,
    uid: opts.uid,
    url: opts.url,
    webToken: opts.webToken,
    contentType: opts.contentType,
  }
}

/**
 * This is the actual context you'll use in your router
 * @link https://trpc.io/docs/context
 **/
export const createContext = cache(async function () {
  const headersList = await headers()

  const cookie = await cookies()
  const webviewTokenCookie = cookie.get("webviewToken")
  const loginType = headersList.get("loginType")

  return createContextInner({
    auth: async () => {
      const session = await auth()
      const webToken = webviewTokenCookie?.value
      if (!session?.token && !webToken) {
        return null
      }

      return (
        session ||
        ({
          token: { access_token: webToken, loginType },
        } as Session)
      )
    },
    lang: headersList.get("x-lang") as Lang,
    pathname: headersList.get("x-pathname")!,
    uid: headersList.get("x-uid"),
    url: headersList.get("x-url")!,
    webToken: webviewTokenCookie?.value,
    contentType: headersList.get("x-contenttype")!,
  })
})

export type Context = Awaited<ReturnType<typeof createContext>>
