import { IMessageListIteratorResult } from '@livelike/javascript';
import { IChatMessage } from '../types';
import { createStore } from './store';

export type ChatMessagesState = {
  chatMessagesLoaded?: boolean;
  chatMessages: IChatMessage[];
  messageListIterator?: () => IMessageListIteratorResult;
  userAvatarUrl?: string;
};

export type ChatMessageStoreValue = {
  [roomId: string]: ChatMessagesState;
};

const initialChatMessageStore: ChatMessageStoreValue = {};

export const chatMessageStore = createStore(initialChatMessageStore);

export type UpdateChatMessagesStateActionArg = {
  roomId: string;
} & ChatMessagesState;

export type UpdateChatConfigActionArg = {
  roomId: string;
  userAvatarUrl?: string;
};

export const chatMessageStoreActions = {
  updateChatConfigAction({ roomId, userAvatarUrl }: UpdateChatConfigActionArg) {
    chatMessageStore.set({
      ...chatMessageStore.get(),
      [roomId]: {
        ...chatMessageStore.get()[roomId],
        userAvatarUrl,
      },
    });
  },
  updateChatMessageStateAction({
    roomId,
    chatMessagesLoaded,
    chatMessages,
    messageListIterator,
  }: UpdateChatMessagesStateActionArg) {
    chatMessageStore.set({
      ...chatMessageStore.get(),
      [roomId]: {
        ...chatMessageStore.get()[roomId],
        chatMessagesLoaded,
        chatMessages,
        messageListIterator,
      },
    });
  },
  updatePrevChatMessagesStateAction({
    roomId,
    chatMessages,
    messageListIterator,
  }: UpdateChatMessagesStateActionArg) {
    chatMessageStore.set({
      ...chatMessageStore.get(),
      [roomId]: {
        ...chatMessageStore.get()[roomId],
        chatMessages: [
          ...chatMessages,
          ...chatMessageStore.get()[roomId].chatMessages,
        ],
        messageListIterator,
      },
    });
  },
  addChatMessageAction({ roomId, chatMessage }) {
    const oldMessages = chatMessageStore.get()[roomId]?.chatMessages ?? [];
    const msgIndex = oldMessages.findIndex((msg) => msg.id === chatMessage.id);
    const updatedMessages = [...oldMessages];
    if (msgIndex > -1) {
      updatedMessages.splice(msgIndex, 1, chatMessage);
    } else {
      updatedMessages.push(chatMessage);
    }
    chatMessageStore.set({
      ...chatMessageStore.get(),
      [roomId]: {
        ...chatMessageStore.get()[roomId],
        chatMessages: updatedMessages,
      },
    });
  },
  deleteChatMessageAction({ roomId, chatMessage }) {
    const oldMessages = chatMessageStore.get()[roomId]?.chatMessages ?? [];
    const updatedMessages = oldMessages.map((msg) =>
      msg.id === chatMessage.id ? { ...msg, isDeleted: true } : msg
    );
    chatMessageStore.set({
      ...chatMessageStore.get(),
      [roomId]: {
        ...chatMessageStore.get()[roomId],
        chatMessages: updatedMessages,
      },
    });
  },
};
