import { useEffect } from 'react'
import { useSelector } from 'react-redux'
import { Navigate, Route, Routes } from 'react-router-dom'
import { AuthController, NostrController } from './controllers'
import { MainLayout } from './layouts/Main'
import {
  appPrivateRoutes,
  appPublicRoutes,
  privateRoutes,
  publicRoutes,
  recursiveRouteRenderer
} from './routes'
import { State } from './store/rootReducer'
import { getNsecBunkerDelegatedKey, saveNsecBunkerDelegatedKey } from './utils'
import './App.scss'

const App = () => {
  const authState = useSelector((state: State) => state.auth)

  useEffect(() => {
    if (window.location.hostname === '0.0.0.0') {
      // A change of the host is needed to make  library available in windows object
      // the app can't encrypt files without the crypto library
      // which is only available on https or localhost
      window.location.hostname = 'localhost'
    }

    generateBunkerDelegatedKey()

    const authController = new AuthController()
    authController.checkSession()
  }, [])

  const generateBunkerDelegatedKey = () => {
    const existingKey = getNsecBunkerDelegatedKey()

    if (!existingKey) {
      const nostrController = NostrController.getInstance()
      const newDelegatedKey = nostrController.generateDelegatedKey()

      saveNsecBunkerDelegatedKey(newDelegatedKey)
    }
  }

  const handleRootRedirect = () => {
    if (authState.loggedIn) return appPrivateRoutes.homePage
    const callbackPathEncoded = btoa(
      window.location.href.split(`${window.location.origin}/#`)[1]
    )
    return `${appPublicRoutes.login}?callbackPath=${callbackPathEncoded}`
  }

  // Hide route only if loggedIn and r.hiddenWhenLoggedIn are both true
  const publicRoutesList = recursiveRouteRenderer(publicRoutes, (r) => {
    return !authState.loggedIn || !r.hiddenWhenLoggedIn
  })

  const privateRouteList = recursiveRouteRenderer(privateRoutes)

  return (
    <Routes>
      <Route element={<MainLayout />}>
        {authState?.loggedIn && privateRouteList}
        {publicRoutesList}
        <Route path="*" element={<Navigate to={handleRootRedirect()} />} />
      </Route>
    </Routes>
  )
}

export default App
