import {useTranslation} from 'react-i18next';
import {useMutation} from 'react-query';
import {
  ChatUserStatus,
  Conversation,
  HuDataMember,
} from '@modules/chats/interfaces';
import {ConversationCreateParams} from '@modules/chats/services/interfaces';
import {
  createConversation as createConversationService,
  inviteUsersToConversation,
} from '@modules/chats/services';
import {
  AmplitudeConversationTypes,
  LOCAL_INITIAL_VERSION,
} from '@modules/chats/constants';
import {
  ConversationsUpdaterService,
  MembershipUpdaterService,
  UsersUpdaterService,
} from '@modules/chats/instances/updaters';
import {useAppSelector} from '@redux/utils';
import {showSnackbar} from '@redux/dispatchers';
import {getUlid, logAmplitudeEvent} from '@shared/utils';
import {AMPLITUDE_EVENTS} from '@shared/constants';

export const useCreateGroupConversation = (
  onSuccess?: (response: Conversation) => void,
  onError?: () => void,
) => {
  const {t} = useTranslation();
  const user = useAppSelector(state => state.user);
  const {mutate: createConversation, isLoading} = useMutation(
    async (params: ConversationCreateParams) => {
      try {
        const idempotencyKey = getUlid();
        const conversation = await createConversationService(
          params,
          idempotencyKey,
        );
        logAmplitudeEvent(AMPLITUDE_EVENTS.CHATS_2_CONVERSATION_CREATED, {
          conversationType: AmplitudeConversationTypes.Group,
          conversationID: conversation.id,
        });

        // Save new conversation to the DB (even if no_op is true, we're not sure if the conversation exists in the DB)
        await ConversationsUpdaterService.saveNewConversation(conversation);

        const otherUsers: HuDataMember[] = params.users.map(
          invitedUser => invitedUser.hu_data.member,
        );

        if (params.users.length) {
          // Send invitations to other users
          await inviteUsersToConversation({
            channel: conversation.id,
            users: otherUsers.map(otherUser => otherUser.id.toString()),
            idempotencyKey: getUlid(),
          });
        }

        const members: HuDataMember[] = [
          ...otherUsers,
          {
            email: user.email || null,
            id: user.id,
            employee_internal_id: user.employeeInternalId,
            first_name: user.firstName,
            last_name: user.lastName,
            picture_asset_url: user.profilePicture || null,
            status: ChatUserStatus.Active,
            version: LOCAL_INITIAL_VERSION,
          },
        ];

        // Save users to the DB
        UsersUpdaterService.saveUsers(members);

        // Save memberships to the DB
        await MembershipUpdaterService.saveGroupMemberships({
          channelId: conversation.id,
          memberships: members.map(member => ({
            user_id: member.id,
            conversation_id: conversation.id,
            version: LOCAL_INITIAL_VERSION,
            is_admin: member.id === user.id,
          })),
        });

        return conversation;
      } catch (error) {
        showSnackbar({
          title: t('errors.api.500', {info: ''}),
          variant: 'error',
        });
        throw error;
      }
    },
    {
      onSuccess,
      onError,
    },
  );
  return {createConversation, isLoading};
};
