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 StatisticsScreen from './src/screens/InAppScreens/TravellersScreen/StatisticsScreen';
import StatisticsListScreen from './src/screens/InAppScreens/TravellersScreen/StatisticsListScreen';
import TriumphsScreen from 'src/screens/InAppScreens/TravellersScreen/TriumphsScreen';
import SeriesRankingScreen from 'src/screens/InAppScreens/TravellersScreen/SeriesRankingScreen';
import SeriesRankingListScreen from 'src/screens/InAppScreens/TravellersScreen/SeriesRankingListScreen';

import SeriesScreen from 'src/screens/InAppScreens/TravelsScreen/Series';
import { SeriesItemScreen } from 'src/screens/InAppScreens/TravelsScreen/SeriesItemScreen';
import EarthScreen from 'src/screens/InAppScreens/TravelsScreen/EarthScreen';
import PhotosScreen from 'src/screens/InAppScreens/TravelsScreen/PhotosScreen';
import MorePhotosScreen from 'src/screens/InAppScreens/TravelsScreen/MorePhotosScreen';
import AddPhotoScreen from 'src/screens/InAppScreens/TravelsScreen/AddPhotoScreen';
import TripsScreen from 'src/screens/InAppScreens/TravelsScreen/TripsScreen';
import AddNewTripScreen from 'src/screens/InAppScreens/TravelsScreen/AddNewTripScreen';
import AddRegionsScreen from 'src/screens/InAppScreens/TravelsScreen/AddRegionsScreen';
import CountriesScreen from 'src/screens/InAppScreens/TravelsScreen/CountriesScreen';
import RegionsScreen from 'src/screens/InAppScreens/TravelsScreen/RegionsScreen';
import DareScreen from 'src/screens/InAppScreens/TravelsScreen/DareScreen';

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
        }
      }),
      backgroundColor: '#FAFAFA',
    }
  });

  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.STATISTICS}
                    component={StatisticsScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW}
                    component={ProfileScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.STATISTICS_LIST_DATA}
                    component={StatisticsListScreen}
                  />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.TRIUMPHS} component={TriumphsScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.SERIES_RANKING} component={SeriesRankingScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.SERIES_RANKING_LIST} component={SeriesRankingListScreen} />
                </ScreenStack.Navigator>
              )}
            </BottomTab.Screen>
            <BottomTab.Screen name={NAVIGATION_PAGES.IN_APP_TRAVELS_TAB}>
              {() => (
                <ScreenStack.Navigator screenOptions={screenOptions}>
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.TRAVELS_TAB}
                    component={TravelsScreen}
                  />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.SERIES} component={SeriesScreen} />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.SERIES_ITEM}
                    component={SeriesItemScreen}
                  />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.EARTH} component={EarthScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.PHOTOS} component={PhotosScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.MORE_PHOTOS} component={MorePhotosScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.ADD_PHOTO} component={AddPhotoScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.TRIPS} component={TripsScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.ADD_TRIP} component={AddNewTripScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.ADD_REGIONS} component={AddRegionsScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.COUNTRIES} component={CountriesScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.REGIONS} component={RegionsScreen} />
                  <ScreenStack.Screen name={NAVIGATION_PAGES.DARE} component={DareScreen} />
                </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;
