import React, { useEffect } from 'react'

import { ClerkProvider, useUser } from '@clerk/clerk-react'

import { createAuth } from '@cedarjs/auth-clerk-web'
import { navigate } from '@cedarjs/router'

export const { AuthProvider: ClerkRwAuthProvider, useAuth } = createAuth()

const ClerkStatusUpdater = () => {
  const { isSignedIn, user, isLoaded } = useUser()
  const { reauthenticate } = useAuth()

  useEffect(() => {
    if (isLoaded) {
      reauthenticate()
    }
  }, [isSignedIn, user, reauthenticate, isLoaded])

  return null
}

type ClerkOptions = { publishableKey: string }

interface Props {
  children: React.ReactNode
}

const ClerkProviderWrapper = ({
  children,
  clerkOptions,
}: Props & { clerkOptions: ClerkOptions }) => {
  const { reauthenticate } = useAuth()

  return (
    <ClerkProvider
      {...clerkOptions}
      routerPush={(to) => reauthenticate().then(() => navigate(to))}
      routerReplace={(to) => reauthenticate().then(() => navigate(to, { replace: true }))}
    >
      {children}
      <ClerkStatusUpdater />
    </ClerkProvider>
  )
}

export const AuthProvider = ({ children }: Props) => {
  const publishableKey = process.env.CLERK_PUBLISHABLE_KEY

  return (
    <ClerkRwAuthProvider>
      <ClerkProviderWrapper clerkOptions={{ publishableKey }}>
        {children}
      </ClerkProviderWrapper>
    </ClerkRwAuthProvider>
  )
}
