import React, {useCallback, useMemo, useRef, useState} from 'react';
import {AppState, Keyboard, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Animated from 'react-native-reanimated';
import * as Sentry from '@sentry/react-native';
import {useFocusEffect} from '@react-navigation/native';
import {
  InputSearch,
  ListSkeleton,
  StateCard,
  TextInputType,
  VoiceFlowWebChat,
} from '@components';
import {closeAllSwipeables} from '@components/RNSwipeable';
import {useBackHandler} from '@hooks/useBackHandler';
import {useEvent} from '@hooks/useEvent';
import {UserPermissions} from '@interfaces/user';
import {useShowCallStatusBar} from '@modules/calls/store/selectors';
import {Conversation} from '@modules/chats/interfaces';
import {
  showMoreOptions,
  useIsChatsError,
  useIsConversationsLoading,
} from '@modules/chats/store';
import {cleanNotifications, useConversationActions} from '@modules/chats/hooks';
import {ChatsStarter} from '@modules/chats/instances/ChatsStarter';
import {usePermission} from '@redux/selectors';
import {ACTIVE} from '@shared/constants';
import {useTheme} from '@shared/theme';
import {useServerState} from '@stores/serverState';

import {styles} from './styles';
import {useSearchBarAnimation} from './hooks/useSearchBarAnimation';
import {SearchChatsAndUsers} from './components/SearchChatsAndUsers';
import {DialogChatOptions} from './components/DialogChatOptions';
import {DialogPinMaxLimit} from './components/DialogPinMaxLimit';
import {ChatModalFeatures} from './components/ChatModalFeatures';
import ChatHomeHeader from './components/ChatHomeHeader';
import ConversationList from './components/ConversationList';
import {ChatMaintenance} from './components/ChatMaintenance';

function ChatHomeScreenComponent() {
  const {t} = useTranslation();
  const {theme} = useTheme();
  const {top} = useSafeAreaInsets();
  const showCallStatusBar = useShowCallStatusBar();
  const [searchText, setSearchText] = useState('');
  const isLoading = useIsConversationsLoading();
  const isError = useIsChatsError();
  const showSearchResults = searchText.length > 0;
  const inputSearchRef = useRef<TextInputType>(null);
  const {togglePin, markAsUnread} = useConversationActions();
  const isServerDown = useServerState(state => state.isServerDown);
  const canCreateConversation = usePermission(
    UserPermissions.CHATS_V2_CREATE_CONVERSATION,
  );

  const {handleScroll, searchBarAnimatedStyle, searchBarWrapperStyle} =
    useSearchBarAnimation({showSearchResults});

  const onBack = useCallback(() => {
    if (showSearchResults) {
      setSearchText('');
      return true;
    }
  }, [showSearchResults]);

  useBackHandler(onBack);

  const onMorePress = useCallback((chat: Conversation) => {
    Keyboard.dismiss();
    showMoreOptions(chat);
  }, []);

  const onPinPress = useCallback(
    (chat: Conversation) => {
      togglePin({channel: chat.id});
    },
    [togglePin],
  );

  const onMarkAsUnreadPress = useEvent(
    (chat: Conversation, unreadCount: number) => {
      markAsUnread({channel: chat.id, unreadCount});
    },
  );

  const onChangeSearchText = useCallback((text: string) => {
    setSearchText(text);
  }, []);

  const onRetryPress = () => {
    ChatsStarter.retry();
  };

  /**
   * Clear search on screen focus out
   * Clear notifications on focus in the Tab and on AppState active while is focused
   */
  useFocusEffect(
    useCallback(() => {
      cleanNotifications();
      const listener = AppState.addEventListener('change', state => {
        if (state === ACTIVE) {
          cleanNotifications();
        }
      });

      return () => {
        listener.remove();
        setTimeout(() => {
          setSearchText('');
          inputSearchRef.current?.clear();
        }, 250);
      };
    }, []),
  );

  const memoizedStyles = useMemo(() => {
    return {
      container: [
        styles.container,
        {paddingTop: showCallStatusBar ? 0 : top},
        {backgroundColor: theme.background.layout.tertiary},
      ],
      inputSearchWrapper: [styles.inputSearchWrapper, searchBarWrapperStyle],
      inputSearchContainer: [
        styles.inputSearchContainer,
        searchBarAnimatedStyle,
      ],
      content: [
        styles.content,
        {backgroundColor: theme.background.layout.tertiary},
      ],
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [showCallStatusBar, top, theme.background.layout.tertiary]);

  if (isServerDown) {
    return (
      <View style={memoizedStyles.container}>
        <ChatHomeHeader hideCreateButton />
        <ChatMaintenance />
      </View>
    );
  }

  return (
    <View style={memoizedStyles.container}>
      <ChatHomeHeader hideCreateButton={!canCreateConversation} />
      <Animated.View
        style={memoizedStyles.inputSearchWrapper}
        onTouchStart={closeAllSwipeables}>
        <Animated.View style={memoizedStyles.inputSearchContainer}>
          <InputSearch
            ref={inputSearchRef}
            value={searchText}
            allowFontScaling={false}
            onChangeText={onChangeSearchText}
            placeholder={t('general.search')}
            autoCorrect={false}
            variant="custom"
            accessible
            accessibilityRole="search"
            accessibilityLabel={t('general.search')}
          />
        </Animated.View>
      </Animated.View>
      <View style={memoizedStyles.content}>
        {isError ? (
          <StateCard
            variant="error"
            title={t('chat.errors.load_messages')}
            description={t('chat.errors.try_again')}>
            <StateCard.Footer>
              <StateCard.Button
                variant="secondary"
                text={t('general.try_again')}
                onPress={onRetryPress}
                isLoading={isLoading}
              />
            </StateCard.Footer>
          </StateCard>
        ) : isLoading ? (
          <ListSkeleton presentation="flat" />
        ) : (
          <>
            <ConversationList
              onMorePress={onMorePress}
              onPinPress={onPinPress}
              onMarkAsUnreadPress={onMarkAsUnreadPress}
              onScroll={handleScroll}
            />
            {showSearchResults && (
              <SearchChatsAndUsers
                searchText={searchText}
                onMorePress={onMorePress}
                onMarkAsUnreadPress={onMarkAsUnreadPress}
                onPinPress={onPinPress}
              />
            )}
          </>
        )}
      </View>
      <VoiceFlowWebChat />
      <DialogChatOptions />
      <DialogPinMaxLimit />
      <ChatModalFeatures />
    </View>
  );
}

export const ChatHomeScreen = Sentry.withProfiler(ChatHomeScreenComponent, {
  name: 'Chats2.ChatHomeScreen',
}) as typeof ChatHomeScreenComponent;
