import React, { useCallback, useMemo } from 'react';
import { View, Dimensions, StyleSheet } from 'react-native';
import { NavTabsBar } from './components/NavTabsBar';
import { useStableCallback } from './hooks/useStableCallback';

import type { BottomTabBarProps } from './types';

interface Route {
  name: string;
  key: string;
}

export const NavBar = ({
  state,
  descriptors,
  navigation,
  tabs,
  ...rest
}: BottomTabBarProps<any>) => {
  const totalWidth = Dimensions.get('window').width;

  const {
    index: navigationIndex,
    key: navigationKey,
    routes,
  }: {
    index: number;
    routes: Route[];
    key: string;
  } = useMemo(() => {
    return state;
  }, [state]);

  const getRouteTitle = useCallback(
    (route: Route) => {
      const { options } = descriptors[route.key];
      return options.tabBarLabel !== undefined &&
        typeof options.tabBarLabel === 'string'
        ? options.tabBarLabel
        : options.title !== undefined
        ? options.title
        : route.name;
    },
    [descriptors]
  );

  const getRouteTabConfigs = useCallback(
    (route: Route) => {
      return tabs[route.name];
    },
    [tabs]
  );

  const routesWithTabConfig = useMemo(() => {
    return routes.reduce((result: { [key: string]: {} }, route) => {
      result[route.key] = {
        title: getRouteTitle(route),
        ...getRouteTabConfigs(route),
      };
      return result;
    }, {});
  }, [routes, getRouteTitle, getRouteTabConfigs]) as any;
  //#endregion

  //#region callbacks
  const handleIndexChange = useStableCallback((index: number) => {
    const focused = index === navigationIndex;
    const { key, name } = routes[index];

    const event = navigation.emit({
      type: 'tabPress',
      target: key,
      canPreventDefault: true,
    });

    if (!focused && !event.defaultPrevented) {
      navigation.dispatch({
        ...navigation.navigate(name),
        target: navigationKey,
      });
    }
  });

  const handleLongPress = useStableCallback((index: number) => {
    const { key } = routes[index];
    navigation.emit({
      type: 'tabLongPress',
      target: key,
    });
  });

  return (
    <View style={[style.tabContainer, { width: totalWidth }]}>
      <NavTabsBar
        {...rest}
        navigationIndex={navigationIndex}
        tabs={routesWithTabConfig}
        handleIndexChange={handleIndexChange}
        handleLongPress={handleLongPress}
      />
    </View>
  );
};

const style = StyleSheet.create({
  tabContainer: {
    height: 60,
    shadowOffset: {
      width: 0,
      height: -1,
    },
    shadowOpacity: 0.1,
    backgroundColor: 'white',
    elevation: 10,
    position: 'absolute',
    bottom: 0,
  },
  slider: {
    height: 2,
    position: 'absolute',
    top: 0,
    left: 10,
    backgroundColor: '#FF0136',
    borderRadius: 10,
  },
});
