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

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

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 UsersMapScreen from 'src/screens/InAppScreens/ProfileScreen/UsersMap';

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';
import { MenuDrawer } from 'src/components';
import { setFastestMapHost } from 'src/constants';
import { determineFastestServer } from 'src/utils/determineServer';
import {
  InfoScreen,
  PlanInfoScreen,
  JoinInfoScreen,
  DiscoverInfoScreen,
  FirstStepsInfoScreen,
  CountriesInfoScreen,
  RegionsInfoScreen,
  EarthInfoScreen,
  DareInfoScreen,
  TripsInfoScreen
} from 'src/screens/InfoScreens';

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'),
    'montserrat-700': require('./assets/fonts/Montserrat-Bold.ttf'),
    'montserrat-600': require('./assets/fonts/Montserrat-SemiBold.ttf'),
    'montserrat-400': require('./assets/fonts/Montserrat-Regular.ttf')
  });
  const [dbLoaded, setDbLoaded] = useState(false);
  const [serverReady, setServerReady] = useState(false);

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

    const findFastestServer = async () => {
      try {
        const fastest = await determineFastestServer();
        setFastestMapHost(fastest);
      } catch (error) {
        console.error('Error finding fastest server:', error);
      }
    };

    prepareApp();
  }, []);

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

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

  const checkTokenAndUpdate = async () => {
    const storedToken = storage.get('deviceToken', StoreType.STRING);
    const currentToken = await Notifications.getDevicePushTokenAsync();

    if (storedToken && currentToken?.data !== storedToken) {
      storage.set('deviceToken', currentToken.data);
    }
  };

  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
        }
      })
    },
    cardStyle: { backgroundColor: 'white' },
    unmountOnBlur: true
  });

  const MapDrawer = createDrawerNavigator();

  function MapDrawerNavigator() {
    return (
      <MapDrawer.Navigator drawerContent={(props) => <MenuDrawer {...props} />}>
        <MapDrawer.Screen
          options={{ headerShown: false }}
          name="MapDrawerScreen"
          component={MapScreen}
        />
      </MapDrawer.Navigator>
    );
  }

  return (
    <ScreenStack.Navigator
      screenOptions={{ headerShown: false, cardStyle: { backgroundColor: 'white' } }}
      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.INFO} component={InfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.JOIN_INFO} component={JoinInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.DISCOVER_INFO} component={DiscoverInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.PLAN_INFO} component={PlanInfoScreen} />
      <ScreenStack.Screen
        name={NAVIGATION_PAGES.FIRST_STEPS_INFO}
        component={FirstStepsInfoScreen}
      />
      <ScreenStack.Screen name={NAVIGATION_PAGES.COUNTRIES_INFO} component={CountriesInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.DARE_INFO} component={DareInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.REGIONS_INFO} component={RegionsInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.TRIPS_INFO} component={TripsInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.EARTH_INFO} component={EarthInfoScreen} />
      <ScreenStack.Screen name={NAVIGATION_PAGES.IN_APP}>
        {() => (
          <BottomTab.Navigator screenOptions={screenOptions}>
            <BottomTab.Screen name={NAVIGATION_PAGES.IN_APP_MAP_TAB}>
              {() => (
                <ScreenStack.Navigator screenOptions={screenOptions}>
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.MAP_TAB}
                    component={MapDrawerNavigator}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW}
                    component={ProfileScreen}
                  />
                  <ScreenStack.Screen
                    name={NAVIGATION_PAGES.USERS_MAP}
                    component={UsersMapScreen}
                  />
                </ScreenStack.Navigator>
              )}
            </BottomTab.Screen>
            <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.Screen
                    name={NAVIGATION_PAGES.USERS_MAP}
                    component={UsersMapScreen}
                  />
                </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;
