import { Box } from '@mui/material'
import Container from '@mui/material/Container'
import { useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import { Outlet } from 'react-router-dom'
import { AppBar } from '../components/AppBar/AppBar'
import { restoreState, setAuthState, setMetadataEvent } from '../store/actions'
import { clearAuthToken, clearState, loadState, saveNsecBunkerDelegatedKey } from '../utils'
import { LoadingSpinner } from '../components/LoadingSpinner'
import { Dispatch } from '../store/store'
import { MetadataController, NostrController } from '../controllers'
import { LoginMethods } from '../store/auth/types'

const metadataController = new MetadataController()

export const MainLayout = () => {
  const dispatch: Dispatch = useDispatch()
  const [isLoading, setIsLoading] = useState(true)

  useEffect(() => {
    const logout = () => {
      dispatch(
        setAuthState({
          keyPair: undefined,
          loggedIn: false,
          usersPubkey: undefined,
          loginMethod: undefined,
          nsecBunkerPubkey: undefined
        })
      )

      dispatch(
        setMetadataEvent(metadataController.getEmptyMetadataEvent())
      )

      // clear authToken saved in local storage
      clearAuthToken()
      clearState()

      // update nsecBunker delegated key
      const newDelegatedKey =
        NostrController.getInstance().generateDelegatedKey()
      saveNsecBunkerDelegatedKey(newDelegatedKey)
    }

    const restoredState = loadState()
    if (restoredState) {
      dispatch(restoreState(restoredState))

      const { loggedIn, loginMethod, usersPubkey, nsecBunkerRelays } =
        restoredState.auth

      if (loggedIn) {
        if (!loginMethod || !usersPubkey) return logout()

        if (loginMethod === LoginMethods.nsecBunker) {
          if (!nsecBunkerRelays) return logout()

          const nostrController = NostrController.getInstance()
          nostrController.nsecBunkerInit(nsecBunkerRelays).then(() => {
            nostrController.createNsecBunkerSigner(usersPubkey)
          })
        }
      }
    }

    setIsLoading(false)
  }, [dispatch])

  if (isLoading) return <LoadingSpinner desc="Loading App" />

  return (
    <>
      <AppBar />

      <Box className="main">
        <Container
          sx={{
            position: 'relative',
            maxWidth: {
              xs: '550px'
            }
          }}
        >
          <Outlet />
        </Container>
      </Box>
    </>
  )
}
