import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {FlatList, Pressable, ScrollView, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import * as Sentry from '@sentry/react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {IconCamera, IconX} from '@tabler/icons-react-native';
import {Typography, DismissKeyboard} from '@components';
import {
  Avatar,
  BackButton,
  Button,
  CloseButton,
  InputClassic,
  ListItem,
  Title,
} from '@components/_HuGo';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {Navigation} from '@interfaces/navigation';
import {ChatUser, Conversation} from '@modules/chats/interfaces';
import {getUserAvatar} from '@modules/chats/utils';
import {CONVERSATION_ITEM_HEIGHT} from '@modules/chats/constants';
import {useCreateGroupConversation} from '@modules/chats/hooks/useCreateGroupConversation';
import {useUploadMedia} from '@modules/chats/hooks';
import {DialogMissingPermission} from '@modules/chats/components';
import {useNewChatData} from '@modules/chats/store/zustand/useNewChatSharedData';
import {useAppSelector} from '@redux/utils';
import {useTheme} from '@shared/theme';
import {getCompleteName} from '@shared/utils';
import {Screens} from '@shared/constants';

import {styles} from './styles';

enum Type {
  CUSTOM = 'custom',
  USER = 'user',
}
interface Item {
  type: Type.USER;
  data: ChatUser;
}

interface CustomItem {
  type: Type.CUSTOM;
  data: null;
}

type MappedItem = Item | CustomItem;

const keyExtractor = (item: MappedItem) => `${item.type}-${item.data?.id}`;
function ChatNewGroupNameScreenComponent({
  navigation,
}: Navigation<Screens.CHATS_NEW_GROUP_NAME>) {
  const [showMissingPermissions, setShowMissingPermissions] = useState(false);
  const {
    members,
    groupName,
    setGroupName,
    groupPicture,
    setGroupPicture,
    removeMember,
    clear,
  } = useNewChatData();
  const user = useAppSelector(state => state.profile.user);
  const bottomSafePadding = useSafeAreaBottomPadding();
  const {t} = useTranslation();
  const {theme} = useTheme();
  const {top} = useSafeAreaInsets();
  const {files, uploadImageOrVideo, isUploadingFiles} = useUploadMedia();
  useEffect(() => {
    files.length > 0 && setGroupPicture(files.at(-1) || null);
  }, [files, setGroupPicture]);
  const mappedData: MappedItem[] = useMemo(
    () => [
      {type: Type.CUSTOM, data: null} as CustomItem,
      ...members.map((u): Item => ({type: Type.USER, data: u})),
    ],
    [members],
  );

  const {createConversation, isLoading} = useCreateGroupConversation(
    (conversation: Conversation) => {
      navigation.popToTop();
      navigation.navigate(Screens.CHAT_MESSAGES, {id: conversation.id});
      clear();
    },
  );
  const onDeleteUser = useCallback(
    (userToDelete: ChatUser) => {
      removeMember(userToDelete.id);
    },
    [removeMember],
  );
  const renderItem = useCallback(
    ({item, index}: {item: MappedItem; index: number}) => {
      let avatarProps;
      let onPressRightButton;
      const isCustomItem = item.type === Type.CUSTOM;
      if (item.type === Type.USER) {
        avatarProps = getUserAvatar(item.data.hu_data.member);
        onPressRightButton = () => onDeleteUser(item.data);
      }
      const userName = getCompleteName(user);
      const isFirstItem = index === 0;
      const isLastItem = index === mappedData.length - 1;
      return (
        <ListItem
          title={isCustomItem ? t('chat.you') : avatarProps?.title || ''}
          avatar={avatarProps || {url: user?.profilePicture, name: userName}}
          RightButton={!isCustomItem ? IconX : undefined}
          isFirstItem={isFirstItem}
          style={{height: CONVERSATION_ITEM_HEIGHT}}
          onPressRightButton={onPressRightButton}
          presentation="card"
          isLastItem={isLastItem}
        />
      );
    },
    [mappedData.length, onDeleteUser, t, user],
  );

  const onGoBack = () => {
    navigation.navigate(Screens.CHATS_NEW_GROUP, {
      isGroupCreation: true,
    });
  };

  const handleNext = () => {
    if (groupPicture?.fileAsset) {
      createConversation({
        name: groupName,
        users: members,
        picture: {
          id: groupPicture.fileAsset.id,
          image_url: groupPicture.fileAsset.url,
          image_bytes: groupPicture.sizeInBytes,
          image_height: groupPicture.fileAsset.height || 0,
          image_width: groupPicture.fileAsset.width || 0,
          mimetype: groupPicture.contentType,
          filename: groupPicture.name,
          metadata: {format: 'image'},
        },
      });
    } else {
      createConversation({
        name: groupName,
        users: members,
      });
    }
  };

  const onPressImage = async () => {
    const result = await uploadImageOrVideo({multiple: false});

    if (!result.ok && result.shouldOpenSettings) {
      setShowMissingPermissions(true);
    }
  };

  const onChangeGroupName = (text: string) => {
    setGroupName(text);
  };

  return (
    <DismissKeyboard
      accessible={false}
      style={[
        styles.container,
        !!top && {paddingTop: top},
        {backgroundColor: theme.background.layout.tertiary},
      ]}>
      <View
        style={[styles.header, {borderColor: theme.border.neutral.default}]}>
        <View style={styles.backButtonContainer}>
          <BackButton onPress={onGoBack} />
        </View>
        <Title title={t('chat.groups.new_group')} center />
        <View style={styles.closeButtonContainer}>
          <CloseButton onPress={navigation.popToTop} />
        </View>
      </View>
      <ScrollView
        contentContainerStyle={[
          styles.content,
          {backgroundColor: theme.background.layout.default},
        ]}
        keyboardDismissMode="on-drag"
        keyboardShouldPersistTaps="always"
        bounces={false}>
        <View style={styles.innerContent}>
          <Pressable onPress={onPressImage} style={styles.cameraContainer}>
            <Avatar
              url={groupPicture?.localUri}
              size="xxl"
              Icon={IconCamera}
              variant="primary"
              isLoading={isUploadingFiles}
              loaderType="spinner"
            />
          </Pressable>
          <InputClassic
            style={styles.inputName}
            placeholder={t('chat.groups.group_name')}
            value={groupName}
            onChangeText={onChangeGroupName}
          />
          <Typography variant="s" weight="semiBold" style={styles.membersTitle}>
            {t('chat.groups.members', {count: mappedData.length})}
          </Typography>
          <FlatList
            data={mappedData}
            keyExtractor={keyExtractor}
            contentContainerStyle={styles.listContent}
            renderItem={renderItem}
            showsVerticalScrollIndicator={false}
          />
        </View>
      </ScrollView>
      <View
        style={[
          {
            paddingBottom: bottomSafePadding,
            backgroundColor: theme.background.layout.tertiary,
            borderColor: theme.border.neutral.default,
          },
          styles.nextButtonContainer,
        ]}>
        <Button
          text={t('chat.groups.create.cta')}
          onPress={handleNext}
          disabled={!groupName.length || isLoading || isUploadingFiles}
          isLoading={isLoading}
        />
      </View>
      <DialogMissingPermission
        isVisible={showMissingPermissions}
        onClose={() => setShowMissingPermissions(false)}
      />
    </DismissKeyboard>
  );
}

export const ChatNewGroupName = Sentry.withProfiler(
  ChatNewGroupNameScreenComponent,
  {
    name: 'Chats2.ChatNewGroupNameScreen',
  },
) as typeof ChatNewGroupNameScreenComponent;
