import React, { useEffect } from 'react'

import { Center, Loader, LoadingOverlay } from '@mantine/core'
import { Outlet, useLocation, useNavigate } from 'react-router-dom'

import { useUserStore } from '~/hooks/state'
import { getCsrfToken } from '~/utils/auth'

import AppLayout from './AppLayout'

const STANDALONE_STATEMENT_ROUTE =
  /^\/orgs\/[^/]+\/clusters\/[^/]+\/sql-statement(?:-v2(?:\/detail)?)?\/?$/

// Make sure the pages inside the AuthGuard have curUser value
const AuthGuard: React.FC = () => {
  const token = getCsrfToken()
  const { user, updateUserFromRemote } = useUserStore()
  const navigate = useNavigate()
  const location = useLocation()
  const standaloneStatementRoute = STANDALONE_STATEMENT_ROUTE.test(
    location.pathname
  )

  useEffect(() => {
    // check token
    if (!token && window.location.hash === '') {
      // when jumping back from auth0, the url likes `{host}/?oauth_callback=1&access_token=xxx&state=xxx
      // at this time, window.location.hash === ''
      // we need to navigate to `/login` with the above paramters
      // new url: `{host}/?oauth_callback=1&access_token=xxx&state=xxx/#/login
      navigate('/login', { replace: true })
      return
    }

    // check user profile
    if (!token || !user) {
      // get user profile by token
      // if getUserProfile fails
      // it will jump to /login page by the axios response interceptor, and remember the login from
      updateUserFromRemote().catch((err) => console.log(err))
    }
  }, [token, user, updateUserFromRemote, navigate])

  if (token && user) {
    return <Outlet />
  }

  if (standaloneStatementRoute) {
    return (
      <Center style={{ height: '100vh' }}>
        <Loader size='md' variant='bars' />
      </Center>
    )
  }

  return (
    <AppLayout>
      <LoadingOverlay loaderProps={{ size: 'md', variant: 'bars' }} visible />
    </AppLayout>
  )
}

export default AuthGuard
