import React, {memo, useCallback, useMemo, useState} from 'react';
import {ScrollView, StyleSheet, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {IconX} from '@tabler/icons-react-native';
import {
  Avatar,
  Button,
  CardContainer,
  IconButton,
  InputSearch,
  RenderSceneProps,
  Tabs,
  Typography,
} from '@components';
import {useDebounceCallback} from '@hooks/useDebounceCallback';
import {User} from '@interfaces/user';
import {GroupChatListItem} from '@modules/chat/interfaces';
import {getShortName} from '@shared/utils';
import {SPACING} from '@shared/theme';

import UsersTab from './components/UsersTab';
import GroupsTab from './components/GroupsTab';

interface Props {
  onCancel?: () => void;
  onNext?: ({
    selectedUsers,
    selectedGroups,
  }: {
    selectedUsers: User[];
    selectedGroups: GroupChatListItem[];
  }) => void;
}

const isTargetUser = (target: User | GroupChatListItem): target is User => {
  return !!(target as User).id;
};

const getTargetInfo = (target: User | GroupChatListItem) =>
  isTargetUser(target)
    ? {
        isUser: true,
        id: target.id,
        name: getShortName(target),
        picture: target.profilePicture,
      }
    : {
        isUser: false,
        id: target.chatId,
        name: target.title,
        picture: target.pictureUrl,
      };

const SelectUsersAndGroups = ({onCancel, onNext}: Props) => {
  const {t} = useTranslation();
  const [searchText, setSearchText] = useState('');
  const [selectedUsers, setSelectedUsers] = useState<User[]>([]);
  const [selectedGroups, setSelectedGroups] = useState<GroupChatListItem[]>([]);
  const selectedTargets = [...selectedUsers, ...selectedGroups];

  const TABS_ROUTES = useMemo(
    () => [
      {key: 'users', label: t('general.people')},
      {key: 'groups', label: t('group.groups')},
    ],
    [t],
  );
  const {debouncedCallback: debounceSearch} = useDebounceCallback(
    (text: string) => {
      setSearchText(text);
    },
  );

  const removeUser = useCallback((id: number) => {
    setSelectedUsers(current => current.filter(item => item.id !== id));
  }, []);

  const addUser = useCallback((item: User) => {
    setSelectedUsers(current => [...current, item]);
  }, []);

  const removeGroup = useCallback((chatId: number) => {
    setSelectedGroups(current =>
      current.filter(item => item.chatId !== chatId),
    );
  }, []);

  const addGroup = useCallback((item: GroupChatListItem) => {
    setSelectedGroups(current => [...current, item]);
  }, []);

  const onNextPress = () => {
    onNext?.({selectedUsers, selectedGroups});
  };

  const renderScene = useCallback(
    (props: RenderSceneProps) => {
      switch (props.route.key) {
        case 'users':
          return (
            <UsersTab
              selectedUsers={selectedUsers}
              addUser={addUser}
              removeUser={removeUser}
              searchText={searchText}
            />
          );
        case 'groups':
          return (
            <GroupsTab
              selectedGroups={selectedGroups}
              addGroup={addGroup}
              removeGroup={removeGroup}
              searchText={searchText}
            />
          );
      }
    },
    [
      addGroup,
      addUser,
      removeGroup,
      removeUser,
      searchText,
      selectedGroups,
      selectedUsers,
    ],
  );

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Button variant="flat" text={t('general.cancel')} onPress={onCancel} />
        <Button
          variant="flat"
          text={t('general.send')}
          onPress={onNextPress}
          disabled={!selectedTargets.length}
        />
      </View>
      <View style={styles.subHeader}>
        <InputSearch
          value={searchText}
          placeholder={t('chat.search.by_name')}
          onChangeText={debounceSearch}
        />
        {!!selectedTargets.length && (
          <CardContainer>
            <ScrollView
              horizontal
              contentContainerStyle={{gap: SPACING.x2}}
              showsHorizontalScrollIndicator={false}>
              {selectedTargets.map(target => {
                const {isUser, id, name, picture} = getTargetInfo(target);
                return (
                  <View key={id} style={styles.selectedItem}>
                    <View>
                      <Avatar name={name} url={picture} size="lg" />
                      <View style={styles.selectedRemoveButton}>
                        <IconButton
                          Icon={IconX}
                          size="sm"
                          onPress={() =>
                            isUser ? removeUser(id) : removeGroup(id)
                          }
                        />
                      </View>
                    </View>
                    <Typography numberOfLines={1}>{name}</Typography>
                  </View>
                );
              })}
            </ScrollView>
          </CardContainer>
        )}
      </View>
      <Tabs renderScene={renderScene} routes={TABS_ROUTES} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {flex: 1},
  header: {
    padding: SPACING.x2,
    paddingTop: SPACING.x3,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  subHeader: {
    paddingHorizontal: SPACING.x2,
    gap: SPACING.x2,
    marginBottom: SPACING.x2,
  },
  selectedItem: {
    justifyContent: 'center',
    alignItems: 'center',
    width: 80,
  },
  selectedRemoveButton: {position: 'absolute', top: 0, right: 0},
});

export default memo(SelectUsersAndGroups);
