// app.tsx
// Copyright (C) 2020  Dwayne Harris

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

import React, { FC, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

import { handleApiError } from '../api/errors'
import { fetchSelf, setChecked } from '../actions/authentication'
import { setTheme } from '../actions/theme'
import { getAuthenticatedUser } from '../selectors/authentication'
import { getFetching } from '../selectors'

import { LOCAL_STORAGE_ACCESS_TOKEN_KEY } from '../constants'
import { useDeepCompareEffect, useTheme } from '../hooks'
import { AppThunkDispatch } from '../types'

import Footer from './footer'
import Logo from './logo'
import NavigationMenu from './navigation-menu'
import NotificationContainer from './notification-container'
import Search from './search'
import SelfInfo from './self-info'
import Spinner from './spinner'

import About from './pages/about'
import Admin from './pages/admin'
import AdminApps from './pages/admin-apps'
import AdminGroups from './pages/admin-groups'
import Apps from './pages/apps'
import CreateApp from './pages/create-app'
import Developers from './pages/developers'
import EditApp from './pages/edit-app'
import GroupAdmin from './pages/group-admin'
import Groups from './pages/groups'
import Home from './pages/home'
import Login from './pages/login'
import Register from './pages/register'
import RegisterGroup from './pages/register-group'
import Self from './pages/self'
import ViewApp from './pages/view-app'
import ViewGroup from './pages/view-group'
import ViewPost from './pages/view-post'
import ViewUser from './pages/view-user'

import '../styles/app.css'

const App: FC = () => {
    const theme = useTheme()
    const user = useSelector(getAuthenticatedUser)
    const fetching = useSelector(getFetching)
    const dispatch = useDispatch<AppThunkDispatch>()

    const init = async () => {
        if (localStorage.getItem(LOCAL_STORAGE_ACCESS_TOKEN_KEY)) {
            try {
                await dispatch(fetchSelf())
            } catch (err) {
                console.log('err', err)
                handleApiError(err, dispatch)
            }
        } else {
            dispatch(setChecked())
        }
    }

    useEffect(() => {
        init()
    }, [])

    useDeepCompareEffect(() => {
        if (user && user.theme) dispatch(setTheme(user.theme))
    }, [user])

    useDeepCompareEffect(() => {
        document.body.style.backgroundColor = theme.backgroundPrimary
    }, [theme])

    return (
        <Router>
            <main style={{ backgroundColor: theme.backgroundPrimary }}>
                <div className="logo-container">
                    <Logo />
                </div>

                <div className="content-container" style={{ backgroundColor: theme.backgroundPrimary }}>
                    <div className="content" style={{ borderLeftColor: theme.backgroundSecondary, borderRightColor: theme.backgroundPrimary }}>
                        <Switch>
                            <Route path="/c/:id/admin/:tab?">
                                <GroupAdmin />
                            </Route>
                            <Route path="/c/:id/register">
                                <RegisterGroup />
                            </Route>
                            <Route path="/c/:id">
                                <ViewGroup />
                            </Route>
                            <Route path="/a/:id/edit">
                                <EditApp />
                            </Route>
                            <Route path="/a/:id">
                                <ViewApp />
                            </Route>
                            <Route path="/u/:id">
                                <ViewUser />
                            </Route>
                            <Route path="/p/:id">
                                <ViewPost />
                            </Route>
                            <Route path="/login">
                                <Login />
                            </Route>
                            <Route path="/register">
                                <Register />
                            </Route>
                            <Route path="/communities">
                                <Groups />
                            </Route>
                            <Route path="/self">
                                <Self />
                            </Route>
                            <Route path="/apps">
                                <Apps />
                            </Route>
                            <Route path="/developers/create">
                                <CreateApp />
                            </Route>
                            <Route path="/developers">
                                <Developers />
                            </Route>
                            <Route path="/about">
                                <About />
                            </Route>
                            <Route path="/admin/apps">
                                <AdminApps />
                            </Route>
                            <Route path="/admin/groups">
                                <AdminGroups />
                            </Route>
                            <Route path="/admin">
                                <Admin />
                            </Route>
                            <Route path="/">
                                <Home />
                            </Route>
                        </Switch>
                    </div>
                </div>

                <div className="menu-container">
                    <div className="menu" style={{ backgroundColor: theme.backgroundSecondary, borderColor: theme.backgroundPrimary }}>
                        <Search />
                        <NavigationMenu />
                        {fetching && <Spinner />}
                        <SelfInfo />
                        <Footer />
                    </div>
                </div>

                <NotificationContainer />
            </main>
        </Router>
    )
}

export default App
