import React, {
  useCallback,
  useEffect,
  useLayoutEffect,
  useMemo,
  useState,
} from 'react';
import {Keyboard, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {shallowEqual} from 'react-redux';
import {IconUsersPlus} from '@tabler/icons-react-native';
import {
  InputSearch,
  OrganizationChart,
  Pressable,
  TabItem as TabItemHuGo,
  Tabs,
  TabsRenderScene,
  Typography,
} from '@components';
import {Language} from '@config/i18n';
import {useTabTracking} from '@hooks/useTabTracking';
import {Navigation} from '@interfaces/navigation';
import AdsTab from '@modules/search/screens/AdsTab';
import {useSearchText} from '@modules/search/hooks/useSearchText';
import {useAppSelector} from '@redux/utils';
import {useInstance, usePermissions} from '@redux/selectors';
import {SHARED_STRINGS, getScreenString} from '@shared/strings';
import {AMPLITUDE_APP_MODULES, Screens} from '@shared/constants';
import {commonStyles} from '@shared/styles';
import {useTheme} from '@shared/theme';
import {capitalize} from '@shared/utils';

import {styles} from './styles';
import PeopleTab from './components/PeopleTab';
import {InviteDialog} from './components/InviteDialog';

type TabItem = TabItemHuGo & {module?: string};

function SearchTabNavigator(props: Navigation<Screens.SEARCH>) {
  const {t, i18n} = useTranslation();
  const {theme, borderRadius, iconSizes} = useTheme();
  const {value, setValue} = useSearchText();
  const {count, filteredCount, filteredUsers} = useAppSelector(
    ({search}) => search,
    shallowEqual,
  );
  const instance = useInstance();
  const {
    VIEW_PEOPLE,
    CREATE_ACKNOWLEDGEMENTS,
    VIEW_ORGANIZATION_CHARTS,
    INVITE_USERS,
  } = usePermissions();
  const {
    navigation,
    route: {
      params: {
        acknowledgedSearch,
        fromWidgets,
        usersList,
        fieldValue,
        firstOrgChart,
      } = {},
    },
  } = props;
  const [showInvite, setShowInvite] = useState(fromWidgets && !firstOrgChart);
  const [isInviteDialogVisible, setIsInviteDialogVisible] = useState(false);
  const trackTabUse = useTabTracking();
  const checkShowPeople = useMemo(
    () =>
      !!(
        usersList ||
        (acknowledgedSearch ? CREATE_ACKNOWLEDGEMENTS : VIEW_PEOPLE)
      ),
    [CREATE_ACKNOWLEDGEMENTS, VIEW_PEOPLE, acknowledgedSearch, usersList],
  );

  const showInviteButton = useMemo(
    () => INVITE_USERS && !acknowledgedSearch && !fieldValue && showInvite,
    [INVITE_USERS, acknowledgedSearch, fieldValue, showInvite],
  );

  const onPressInvite = () => {
    Keyboard.dismiss();
    setIsInviteDialogVisible(true);
  };
  const onCloseInviteDialog = () => setIsInviteDialogVisible(false);

  useLayoutEffect(() => {
    const headerRight = () =>
      showInviteButton && (
        <Pressable
          style={[
            styles.inviteButton,
            {backgroundColor: theme.primary, borderRadius: borderRadius.m},
          ]}
          onPress={onPressInvite}>
          <IconUsersPlus size={iconSizes.x6} color="white" />
        </Pressable>
      );
    fromWidgets &&
      navigation.setOptions({
        title: t(SHARED_STRINGS.PEOPLE),
        headerRight,
      });
  }, [
    t,
    INVITE_USERS,
    acknowledgedSearch,
    borderRadius.m,
    fieldValue,
    instance,
    navigation,
    showInvite,
    theme.primary,
    iconSizes.x6,
    fromWidgets,
    showInviteButton,
  ]);

  const routes = useMemo(() => {
    const routeList = [
      checkShowPeople && {
        key: Screens.PEOPLE,
        label: `${t(SHARED_STRINGS.PEOPLE)}${
          fieldValue ? ` ${t('general.with_item', {item: fieldValue})}` : ''
        }${
          count && !fromWidgets
            ? ` (${filteredUsers.length ? filteredCount : count})`
            : ''
        }`,
        module: AMPLITUDE_APP_MODULES.People,
      },
      !fieldValue &&
        !(acknowledgedSearch || fromWidgets) && {
          key: Screens.ADS,
          label: t('general.posts'),
          module: AMPLITUDE_APP_MODULES.Feed,
        },
      VIEW_ORGANIZATION_CHARTS &&
        fromWidgets && {
          key: Screens.ORGANIZATION_CHART_TAB,
          label:
            capitalize(
              instance.moduleNames?.[i18n.language as Language]
                ?.ORGANIZATION_CHARTS,
              false,
            ) || t(getScreenString(Screens.ORGANIZATION_CHARTS)),
          module: AMPLITUDE_APP_MODULES.OrganizationChart,
        },
    ];
    return routeList.filter(Boolean) as TabItem[];
  }, [
    VIEW_ORGANIZATION_CHARTS,
    acknowledgedSearch,
    checkShowPeople,
    count,
    fieldValue,
    filteredCount,
    filteredUsers.length,
    fromWidgets,
    i18n.language,
    instance.moduleNames,
    t,
  ]);

  const onTabChange = useCallback(
    (key: string, index: number) => {
      routes[index]?.module && trackTabUse(routes[index].module);
      setShowInvite(key === Screens.PEOPLE && fromWidgets);
    },
    [fromWidgets, routes, trackTabUse],
  );

  const placeholderSearch = useMemo(() => t('general.search'), [t]);

  useEffect(() => {
    if (!fromWidgets) {
      const headerTitle = () => (
        <Typography weight="semiBold">{placeholderSearch}</Typography>
      );
      navigation.setOptions({headerTitle});
    }
  }, [fromWidgets, navigation, placeholderSearch]);

  const renderScene = useCallback(
    ({route}: TabsRenderScene<TabItem>) => {
      switch (route.key) {
        case Screens.PEOPLE:
          return <PeopleTab {...props} usersList={usersList} />;
        case Screens.ADS:
          return <AdsTab />;
        case Screens.ORGANIZATION_CHART_TAB:
          return <OrganizationChart comingFrom={Screens.WIDGETS} />;
        default:
          return null;
      }
    },
    [props, usersList],
  );

  const initialRouteIndex = useMemo(() => {
    const initialRouteName = firstOrgChart
      ? Screens.ORGANIZATION_CHART_TAB
      : fromWidgets
      ? Screens.PEOPLE
      : Screens.TOPICS_LIST;
    const index = routes.findIndex(route => route.key === initialRouteName);
    return Math.max(index, 0);
  }, [firstOrgChart, fromWidgets, routes]);

  return (
    <>
      <View style={commonStyles.flex}>
        {!fromWidgets && (
          <View
            style={[
              styles.searchInputContainer,
              {backgroundColor: theme.background.layout.tertiary},
            ]}>
            <InputSearch
              value={value}
              onChangeText={setValue}
              placeholder={placeholderSearch}
              variant="secondary"
            />
          </View>
        )}
        {routes.length && (
          <Tabs
            initialIndex={initialRouteIndex}
            renderScene={renderScene}
            routes={routes}
            swipeEnabled={!(VIEW_ORGANIZATION_CHARTS && fromWidgets)}
            onTabChange={onTabChange}
            withDivider={false}
            tabContainerStyle={{
              backgroundColor: theme.background.layout.default,
            }}
            fullWidth
          />
        )}
      </View>
      {showInviteButton && (
        <InviteDialog
          isInviteDialogVisible={isInviteDialogVisible}
          onCloseInviteDialog={onCloseInviteDialog}
        />
      )}
    </>
  );
}

export default SearchTabNavigator;
