import { createHashHistory } from 'history'
import React, { lazy, Suspense, useEffect } from 'react'
import { connect } from 'react-redux'
import { Route, Router, Switch } from 'react-router'
import { bindActionCreators, Dispatch } from 'redux'

import AuthRoute from '@agiliza/components/atoms/AuthRoute'
import CircularProgress from '@agiliza/components/molecules/CircularProgress'
import { StoreState } from '@agiliza/redux'
import { isAuthenticated, isAuthenticating, isInitializing } from '@agiliza/redux/session/selectors'
import { actions as drawerActions } from '@agiliza/redux/ui/drawer'
import { isDrawerOpen } from '@agiliza/redux/ui/drawer/selectors'
import { getError } from '@agiliza/redux/ui/error/selectors'
import * as uiLogin from '@agiliza/redux/ui/login'

const Login = lazy(() => import('./Login'))
const Main = lazy(() => import('./Main'))

const history = createHashHistory()

interface Props {
  error: string
  authenticated: boolean
  authenticating: boolean
  connect: typeof uiLogin.actions.connect
}

const Views = (props: Props) => {
  const { authenticating } = props

  useEffect(() => {
    props.connect()
  }, [])

  if (authenticating) return <CircularProgress root />

  return (
    <Router history={history}>
      <Suspense fallback={<CircularProgress />}>
        <Switch>
          <Route path="/login" render={(renderProps) => <Login {...renderProps} />} />
          <AuthRoute path="/" component={Main} />
        </Switch>
      </Suspense>
    </Router>
  )
}

const mapStateToProps = (state: StoreState) => ({
  error: getError(state.ui.error),
  authenticated: isAuthenticated(state.session),
  authenticating: isAuthenticating(state.session) || isInitializing(state.session),
  drawerOpen: isDrawerOpen(state.ui.drawer),
})

const mapDispatchToProps = (dispatch: Dispatch) =>
  bindActionCreators(
    {
      toggleDrawer: drawerActions.toggleDrawer,
      connect: uiLogin.actions.connect,
    },
    dispatch
  )

export default connect(mapStateToProps, mapDispatchToProps)(Views)
