"use client"

import { useEffect } from "react"
import { useSearchParams } from "next/navigation"
import { OAuthResult, oauthHandleRedirectIfPresent, oauthLoginUrl } from "@huggingface/hub"

import { usePersistedOAuth } from "./usePersistedOAuth"
import { getValidOAuth } from "./getValidOAuth"
import { useDynamicConfig } from "./useDynamicConfig"
import { useLocalStorage } from "usehooks-ts"
import { useShouldDisplayLoginWall } from "./useShouldDisplayLoginWall"
import { getOAuthRedirectUrl } from "./getOAuthRedirectUrl"

export function useOAuth({
  debug = false
}: {
  debug?: boolean
} = {
  debug: false
}): {
  clientId: string
  redirectUrl: string
  scopes: string
  canLogin: boolean
  login: () => Promise<void>
  isLoggedIn: boolean
  enableOAuth: boolean
  enableOAuthWall: boolean
  oauthResult?: OAuthResult
 } {
  const { config, isConfigReady } = useDynamicConfig()

  const [oauthResult, setOAuthResult] = usePersistedOAuth()

  const clientId = config.oauthClientId

  // const redirectUrl = config.oauthRedirectUrl
  const redirectUrl = getOAuthRedirectUrl()

  const scopes = config.oauthScopes
  const enableOAuth = config.enableHuggingFaceOAuth

  const searchParams = useSearchParams()
  const code = searchParams?.get("code") || ""
  const state = searchParams?.get("state") || ""

  const hasReceivedFreshOAuth = Boolean(code && state)

  // note: being able to log into hugging face using the popup
  // is different from seeing the "login wall"
  const canLogin: boolean = Boolean(isConfigReady && clientId && enableOAuth)
  const isLoggedIn = Boolean(oauthResult)

  const enableOAuthWall = useShouldDisplayLoginWall() 

  if (debug) {
    console.log("useOAuth debug:", {
      oauthResult,
      clientId,
      redirectUrl,
      scopes,
      enableOAuth,
      enableOAuthWall,
      code,
      state,
      hasReceivedFreshOAuth,
      canLogin,
      isLoggedIn,
    })

    /*
    useOAuth debug: {
      oauthResult: '',
      clientId: '........',
      redirectUrl: 'http://localhost:3000',
      scopes: 'openid profile inference-api',
      isOAuthEnabled: true,
      code: '...........',
      state: '{"nonce":".........","redirectUri":"http://localhost:3000"}',
      hasReceivedFreshOAuth: true,
      canLogin: false,
      isLoggedIn: false
    }
    */
  }

  useEffect(() => {
    // no need to perfor the rest if the operation is there is nothing in the url
    if (hasReceivedFreshOAuth) {

      (async () => {
        const maybeValidOAuth = await oauthHandleRedirectIfPresent()

        const newOAuth = getValidOAuth(maybeValidOAuth)

        if (!newOAuth) {
          if (debug) {
            console.log("useOAuth::useEffect 1: got something in the url but no valid oauth data to show.. something went terribly wrong")
          }
        } else {
          if (debug) {
            console.log("useOAuth::useEffect 1: correctly received the new oauth result, saving it to local storage:", newOAuth)
          }
          setOAuthResult(newOAuth)

          // once set we can (brutally) reload the page
          window.location.href = `//${window.location.host}${window.location.pathname}`
        }
      })()
    }
  }, [debug, hasReceivedFreshOAuth])

  // for debugging purpose
  useEffect(() => {
    if (!debug) {
      return
    }
    console.log(`useOAuth::useEffect 2: canLogin? ${canLogin}`)
    if (!canLogin) {
      return
    }
    console.log(`useOAuth::useEffect2: isLoggedIn? ${isLoggedIn}`)
    if (!isLoggedIn) {
      return
    }
    console.log(`useOAuth::useEffect 2: oauthResult:`, oauthResult)
  }, [debug, canLogin, isLoggedIn, oauthResult])

  const login = async () => {
    window.location.href = await oauthLoginUrl({
      clientId,
      redirectUrl,
      scopes,
    })
  }

  return {
    clientId,
    redirectUrl,
    scopes,
    canLogin,
    login,
    isLoggedIn,
    enableOAuth,
    enableOAuthWall,
    oauthResult
  }
}