import React, {useCallback, useMemo, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {IconUsersGroup} from '@tabler/icons-react-native';
import {useMutation} from '@tanstack/react-query';
import {Avatar, Button, Dialog, InputClassic} from '@components';
import {updateConversation} from '@modules/chats/services';
import {useUploadMedia} from '@modules/chats/hooks';
import {useConversation} from '@modules/chats/store';
import {ConversationsUpdaterService} from '@modules/chats/instances/updaters';
import {showSnackbar} from '@redux/dispatchers';
import {getUlid} from '@shared/utils';

import {styles} from './styles';

interface Props {
  channel: string;
  isVisible: boolean;
  onClose: () => void;
}

export function DialogEditGroup({channel, isVisible, onClose}: Props) {
  const {t} = useTranslation();
  const conversation = useConversation(channel);
  const [groupName, setGroupName] = useState(conversation?.name);
  const {mutate, isPending} = useMutation({
    mutationFn: updateConversation,
    onSuccess: response => {
      onClose();
      ConversationsUpdaterService.saveNewConversation(response);
    },
  });
  const {uploadImageOrVideo, files, clearMedia, isUploadingFiles} =
    useUploadMedia();
  const currentFile = files.at(-1);

  const onChangePicture = useCallback(async () => {
    clearMedia();
    const result = await uploadImageOrVideo({multiple: false});

    if (!result.ok && result.shouldOpenSettings) {
      showSnackbar({
        title: t('chat.files.missing_permission.title'),
        description: t('chat.files.missing_permission.description'),
        variant: 'error',
      });
    }
  }, [clearMedia, t, uploadImageOrVideo]);

  const onSave = useCallback(() => {
    if (!currentFile && conversation?.name === groupName) {
      onClose();
      return;
    }

    if (!conversation?.id) {
      return;
    }

    if (currentFile?.fileAsset) {
      mutate({
        channel: conversation.id,
        name: groupName,
        idempotencyKey: getUlid(),
        picture: {
          id: currentFile.fileAsset.id,
          image_url: currentFile.fileAsset.url,
          image_bytes: currentFile.sizeInBytes,
          image_height: currentFile.fileAsset.height || 0,
          image_width: currentFile.fileAsset.width || 0,
          mimetype: currentFile.contentType,
          filename: currentFile.name,
          metadata: {format: 'image'},
        },
      });
    } else {
      mutate({
        channel: conversation.id,
        name: groupName,
        idempotencyKey: getUlid(),
      });
    }
  }, [
    conversation?.id,
    conversation?.name,
    currentFile,
    onClose,
    groupName,
    mutate,
  ]);

  const footer = useMemo(() => {
    return {
      primaryButton: {
        text: t('general.save'),
        onPress: onSave,
        isLoading: isPending,
        disabled: isPending || isUploadingFiles,
      },
      secondaryButton: {
        text: t('general.cancel'),
        onPress: onClose,
      },
    };
  }, [isPending, isUploadingFiles, onClose, onSave, t]);

  return (
    <Dialog
      isVisible={isVisible}
      onClose={onClose}
      title={t('chat.groups.manage.edit_info')}
      footer={footer}
      fullScreen>
      <View style={styles.container}>
        <View style={styles.innerContainer}>
          <Avatar
            url={currentFile?.localUri || conversation?.picture_url}
            size="xxl"
            Icon={IconUsersGroup}
            style={styles.pictureContainer}
            withAuthHeader={!!conversation?.picture_url}
            enableCache
            loaderType={currentFile?.localUri ? 'spinner' : 'skeleton'}
          />
          <Button
            text={t('chat.groups.manage.edit_image')}
            variant="secondary"
            style={styles.editButton}
            size="sm"
            onPress={onChangePicture}
          />
          <InputClassic
            value={groupName}
            onChangeText={setGroupName}
            style={styles.input}
          />
        </View>
      </View>
    </Dialog>
  );
}
