import React, { useCallback, useEffect } from 'react';
import {
  NavigationContainer as NavigationContainerBase,
  ParamListBase,
  createNavigationContainerRef,
} from '@react-navigation/native';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Snackbar, useTheme } from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import {
  Memes,
  Tags,
  Settings,
  EditMeme,
  EditTag,
  AddMeme,
  AddTag,
  MemeView,
} from './screens';
import { darkNavigationTheme, lightNavigationTheme } from './theme';
import {
  FloatingActionButton,
  HideableBottomNavigationBar,
} from './components';
import {
  ROUTE,
  RootStackParamList,
  SharedItem,
  sharedItemToAddMemeFile,
} from './types';
import { RootState } from './state';
import ShareMenu from 'react-native-share-menu';
import { setSnackbarMessage } from './state/navigation';
import { StyleSheet } from 'react-native';
import { useKeyboard } from '@react-native-community/hooks';

const tabNavigatorStyles = StyleSheet.create({
  snackbar: {
    marginBottom: 90,
  },
  snackbarKeyboard: {
    marginBottom: 10,
  },
});

const TabNavigator = () => {
  const navVisible = useSelector(
    (state: RootState) => state.navigation.navVisible,
  );
  const snackbarMessage = useSelector(
    (state: RootState) => state.navigation.snackbarMessage,
  );
  const dispatch = useDispatch();
  const keyboardOpen = useKeyboard().keyboardShown;

  const [route, setRoute] = React.useState(ROUTE.MEMES);
  const TabNavigatorBase = createBottomTabNavigator();

  return (
    <>
      <TabNavigatorBase.Navigator
        screenOptions={{
          headerShown: false,
          lazy: false,
        }}
        tabBar={({ navigation, state, descriptors, insets }) => (
          <HideableBottomNavigationBar
            navigation={navigation}
            state={state}
            descriptors={descriptors}
            insets={insets}
            visible={!!navVisible}
            routeCallback={newRoute => setRoute(newRoute)}
          />
        )}>
        <TabNavigatorBase.Screen
          name={ROUTE.MEMES}
          component={Memes}
          options={{
            tabBarIcon: ({ color, size }) => (
              <FontAwesome5 name="images" color={color} size={size} />
            ),
          }}
        />
        <TabNavigatorBase.Screen
          name={ROUTE.TAGS}
          component={Tags}
          options={{
            tabBarIcon: ({ color, size }) => (
              <FontAwesome5 name="tags" color={color} size={size} />
            ),
          }}
        />
        <TabNavigatorBase.Screen
          name={ROUTE.SETTINGS}
          component={Settings}
          options={{
            tabBarIcon: ({ color, size }) => (
              <FontAwesome5 name="cog" color={color} size={size} />
            ),
          }}
        />
      </TabNavigatorBase.Navigator>
      <FloatingActionButton visible={navVisible && route !== ROUTE.SETTINGS} />
      <Snackbar
        visible={!!snackbarMessage}
        // eslint-disable-next-line unicorn/no-useless-undefined
        onDismiss={() => dispatch(setSnackbarMessage(undefined))}
        style={
          keyboardOpen
            ? tabNavigatorStyles.snackbarKeyboard
            : tabNavigatorStyles.snackbar
        }
        action={{
          label: 'Dismiss',
          // eslint-disable-next-line unicorn/no-useless-undefined
          onPress: () => dispatch(setSnackbarMessage(undefined)),
        }}>
        {snackbarMessage}
      </Snackbar>
    </>
  );
};

const NavigationContainer = () => {
  const theme = useTheme();

  const navigationRef = createNavigationContainerRef<ParamListBase>();

  const handleShare = useCallback(
    (item: SharedItem | undefined) => {
      if (!item) return;
      const files = sharedItemToAddMemeFile(item);
      navigationRef.current?.navigate(ROUTE.ADD_MEME, { files });
    },
    [navigationRef],
  );

  useEffect(() => {
    ShareMenu.getInitialShare(handleShare);
    const listener = ShareMenu.addNewShareListener(handleShare);
    return () => listener.remove();
  }, [handleShare]);

  const StackNavigatorBase = createNativeStackNavigator<RootStackParamList>();

  return (
    <NavigationContainerBase
      ref={navigationRef}
      theme={theme.dark ? darkNavigationTheme : lightNavigationTheme}>
      <StackNavigatorBase.Navigator
        screenOptions={{
          headerShown: false,
          animation: 'slide_from_bottom',
        }}>
        <StackNavigatorBase.Screen name={ROUTE.MAIN} component={TabNavigator} />
        <StackNavigatorBase.Screen
          name={ROUTE.MEME_VIEW}
          component={MemeView}
          options={{ presentation: 'modal', animation: 'default' }}
        />
        <StackNavigatorBase.Screen name={ROUTE.ADD_MEME} component={AddMeme} />
        <StackNavigatorBase.Screen
          name={ROUTE.EDIT_MEME}
          component={EditMeme}
        />
        <StackNavigatorBase.Screen name={ROUTE.ADD_TAG} component={AddTag} />
        <StackNavigatorBase.Screen name={ROUTE.EDIT_TAG} component={EditTag} />
      </StackNavigatorBase.Navigator>
    </NavigationContainerBase>
  );
};

export default NavigationContainer;
