import React, {memo, useCallback} from 'react';
import {Keyboard, SectionListRenderItem, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useNavigation} from '@react-navigation/native';
import Animated, {
  EntryAnimationsValues,
  ExitAnimationsValues,
  withDelay,
  withTiming,
} from 'react-native-reanimated';
import {
  ChatListItem,
  UserListItem,
  ChatSearch,
} from '@modules/chats/components';
import {useOpenConversation} from '@modules/chats/hooks';
import {ChatUser, Conversation} from '@modules/chats/interfaces';
import {SEARCH_HEIGHT} from '@modules/chats/screens/ChatNew/styles';
import {showSnackbar} from '@redux/dispatchers';
import {useTheme} from '@shared/theme';
import {commonStyles} from '@shared/styles';
import {Screens} from '@shared/constants';
import {sentryLogs} from '@shared/utils';

import {styles} from './styles';

interface Props {
  searchText: string;
  onMorePress?: (target: Conversation) => void;
  onPinPress?: (target: Conversation) => void;
  onMarkAsUnreadPress?: (target: Conversation, unreadCount: number) => void;
}

const customEntering = (_: EntryAnimationsValues) => {
  'worklet';
  const animations = {
    opacity: withDelay(100, withTiming(1, {duration: 250})),
    transform: [{translateY: withTiming(0, {duration: 250})}],
  };
  const initialValues = {
    opacity: 0,
    transform: [{translateY: SEARCH_HEIGHT}],
  };
  return {
    initialValues,
    animations,
  };
};

const customExiting = (_: ExitAnimationsValues) => {
  'worklet';
  const animations = {
    opacity: withTiming(0, {duration: 250}),
    transform: [{translateY: withTiming(SEARCH_HEIGHT, {duration: 250})}],
  };
  const initialValues = {
    opacity: 1,
    transform: [{translateY: 0}],
  };
  return {
    initialValues,
    animations,
  };
};

function SearchChatsAndUsersCmp({
  searchText,
  onMorePress,
  onPinPress,
  onMarkAsUnreadPress,
}: Props) {
  const {t} = useTranslation();
  const {theme} = useTheme();
  const navigation = useNavigation();
  const {openConversation} = useOpenConversation();

  const onUserPress = useCallback(
    (user: ChatUser) => {
      Keyboard.dismiss();
      openConversation(
        {users: [user]},
        {
          onSuccess: response => {
            if (!response.id) {
              sentryLogs.error({
                message: 'Conversation id not defined',
                module: 'CHATS',
                component: 'SearchChatsAndUsers',
                data: {
                  conversation: response,
                },
              });
              showSnackbar({
                title: t('errors.api.500', {info: ''}),
                variant: 'error',
              });
              return;
            }
            navigation.navigate(Screens.CHAT_MESSAGES, {
              id: response.id,
            });
          },
        },
      );
    },
    [openConversation, navigation, t],
  );

  const onChatPress = useCallback(() => {
    Keyboard.dismiss();
  }, []);

  const renderItem: SectionListRenderItem<Conversation | ChatUser> =
    useCallback(
      ({item, section}) =>
        section.type === 'chats' ? (
          <ChatListItem
            chat={item as Conversation}
            onPress={onChatPress}
            onMorePress={onMorePress}
            onPinPress={onPinPress}
            onMarkAsUnreadPress={onMarkAsUnreadPress}
          />
        ) : (
          <UserListItem
            style={styles.userListItem}
            user={item as ChatUser}
            onItemPress={onUserPress}
          />
        ),
      [onChatPress, onMorePress, onPinPress, onMarkAsUnreadPress, onUserPress],
    );

  if (!searchText) {
    return null;
  }

  return (
    <Animated.View
      entering={customEntering}
      exiting={customExiting}
      style={styles.searchContainer}>
      <View
        style={[
          commonStyles.flex,
          {backgroundColor: theme.background.layout.tertiary},
        ]}>
        <ChatSearch searchText={searchText} renderItem={renderItem} />
      </View>
    </Animated.View>
  );
}

export const SearchChatsAndUsers = memo(SearchChatsAndUsersCmp);
