import React, { useEffect, useState } from 'react';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { Platform } from 'react-native';

import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import WelcomeScreen from './src/screens/WelcomeScreen';
import LoginScreen from './src/screens/LoginScreen';
import ResetPasswordScreen from './src/screens/ResetPasswordScreen';
import ResetPasswordDeepScreen from './src/screens/ResetPasswordDeepScreen';
import JoinUsScreen from './src/screens/RegisterScreen/JoinUs';
import EditAccount from './src/screens/RegisterScreen/EditAccount';

import MapScreen from './src/screens/InAppScreens/MapScreen';
import TravelsScreen from './src/screens/InAppScreens/TravelsScreen';
import ProfileScreen from './src/screens/InAppScreens/ProfileScreen';
import TravellersScreen from './src/screens/InAppScreens/TravellersScreen';

import { EditPersonalInfo } from './src/screens/InAppScreens/ProfileScreen/Profile/edit-personal-info';
import Settings from './src/screens/InAppScreens/ProfileScreen/Settings/';

import MasterRankingScreen from './src/screens/InAppScreens/TravellersScreen/MasterRankingScreen';
import LPIRanking from './src/screens/InAppScreens/TravellersScreen/LPIRankingScreen';
import InMemoriamScreen from './src/screens/InAppScreens/TravellersScreen/InMemoriamScreen';
import InHistoryScreen from './src/screens/InAppScreens/TravellersScreen/InHistoryScreen';
import UNMastersScreen from './src/screens/InAppScreens/TravellersScreen/UNMasters';

import { NAVIGATION_PAGES } from './src/types';
import { storage, StoreType } from './src/storage';
import { openDatabases } from './src/db';

import TabBarButton from './src/components/TabBarButton';
import { ParamListBase, RouteProp } from '@react-navigation/native';
import setupDatabaseAndSync from 'src/database';

const ScreenStack = createStackNavigator();
const BottomTab = createBottomTabNavigator();

SplashScreen.preventAutoHideAsync();

const Route = () => {
  const token = storage.get('token', StoreType.STRING);

  const [fontsLoaded] = useFonts({
    'redhat-900': require('./assets/fonts/RedHatDisplay-Black-900.ttf'),
    'redhat-700': require('./assets/fonts/RedHatDisplay-Bold-700.ttf'),
    'redhat-600': require('./assets/fonts/RedHatDisplay-SemiBold-600.ttf')
  });
  const [dbLoaded, setDbLoaded] = useState(false);

  useEffect(() => {
    const prepareApp = async () => {
      await openDatabases();
      setDbLoaded(true);
      await setupDatabaseAndSync();
    };

    prepareApp();
  }, []);

  useEffect(() => {
    const hideSplashScreen = async () => {
      if (fontsLoaded && dbLoaded) {
        await SplashScreen.hideAsync();
      }
    };

    hideSplashScreen();
  }, [fontsLoaded, dbLoaded]);

  if (!fontsLoaded) {
    return null;
  }

  const screenOptions = ({
    route
  }: {
    route: RouteProp<ParamListBase, string>;
    navigation: any;
  }) => ({
    headerShown: false,
    tabBarButton: (props: any) => (
      <TabBarButton {...props} label={route.name} focused={props.accessibilityState.selected} />
    ),
    tabBarStyle: {
      ...Platform.select({
        android: {
          height: 58
        }
      })
    }
  });

  return (
    <ScreenStack.Navigator
      screenOptions={{ headerShown: false }}
      initialRouteName={token ? NAVIGATION_PAGES.IN_APP : NAVIGATION_PAGES.WELCOME}
    >
      <ScreenStack.Screen name={NAVIGATION_PAGES.WELCOME} component={WelcomeScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.LOGIN} component={LoginScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.REGISTER} component={JoinUsScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.REGISTER_ACCOUNT_DATA} component={EditAccount} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.RESET_PASSWORD} component={ResetPasswordScreen} />
      <ScreenStack.Screen
        name={NAVIGATION_PAGES.RESET_PASSWORD_DEEP}
        component={ResetPasswordDeepScreen}
      />
      <ScreenStack.Screen name={NAVIGATION_PAGES.IN_APP}>
        {() => (
          <BottomTab.Navigator screenOptions={screenOptions}>
            <BottomTab.Screen name={NAVIGATION_PAGES.MAP_TAB} component={MapScreen} />
            <BottomTab.Screen name={NAVIGATION_PAGES.IN_APP_TRAVELLERS_TAB}>
              {() => (
                <ScreenStack.Navigator screenOptions={screenOptions}>
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.TRAVELLERS_TAB}
                    component={TravellersScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.MASTER_RANKING}
                    component={MasterRankingScreen}
                  />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.LPI_RANKING} component={LPIRanking} />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.IN_MEMORIAM}
                    component={InMemoriamScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.IN_HISTORY}
                    component={InHistoryScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.UN_MASTERS}
                    component={UNMastersScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW}
                    component={ProfileScreen}
                  />
                </ScreenStack.Navigator>
              )}
            </BottomTab.Screen>
            <BottomTab.Screen name={NAVIGATION_PAGES.IN_APP_TRAVELS_TAB}>
              {() => (
                <ScreenStack.Navigator screenOptions={screenOptions}>
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.TRAVELLERS_TAB}
                    component={TravelsScreen}
                  />
                </ScreenStack.Navigator>
              )}
            </BottomTab.Screen>
            <BottomTab.Screen name={NAVIGATION_PAGES.IN_APP_PROFILE}>
              {() => (
                <ScreenStack.Navigator screenOptions={screenOptions}>
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.PROFILE_TAB}
                    component={ProfileScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.EDIT_PERSONAL_INFO}
                    component={EditPersonalInfo}
                  />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.SETTINGS} component={Settings} />
                </ScreenStack.Navigator>
              )}
            </BottomTab.Screen>
          </BottomTab.Navigator>
        )}
      </ScreenStack.Screen>
    </ScreenStack.Navigator>
  );
};

export default Route;
