import {
  SidebarGroup,
  SidebarResource,
  UNGROUPPED_GROUP_ID,
} from '../../../../../../../../server-services/query-records/sidebar-records';
import { WorkspaceSubscriptionDialogueEventRecord } from '../../../../../../../../server-services/query-records/workspace-records';
import {
  getDialogueDataQuery,
  getSidebarGroupQuery,
  getSidebarResourceQuery,
  getSidebarUngrouppedQuery,
} from '../../../../../../../../server-services/querys';
import { SeenCacheRecord } from '../../../../../custom-cache-reset-logic';
import { WorkspaceChangeSubscriptionSpecificHandler } from '../types';

export let onModifyDialogueEventSubscriptionHandler: WorkspaceChangeSubscriptionSpecificHandler = (
  cache,
  event: WorkspaceSubscriptionDialogueEventRecord
) => {
  let dialogueData = cache.getCacheDataByRequest({
    query: getDialogueDataQuery,
    variables: {
      id: event.id,
    },
  });

  if (dialogueData) {
    if (event.seenMessageId) {
      dialogueData.seenMessageId = event.seenMessageId;
    }

    if (event.topMessageId) {
      dialogueData.topMessageId = event.topMessageId;
    }
  }

  if (event.groupId !== undefined || event.ordering !== undefined) {
    let sidebarRes: SidebarResource = cache.getCacheDataByRequest({
      query: getSidebarResourceQuery,
      variables: event,
    });
    if (sidebarRes) {
      if (event.groupId !== undefined) {
        let oldGroup = sidebarRes.groupId;
        sidebarRes.groupId = event.groupId;

        // remove from the old container
        let container: SidebarResource[] | null = null;
        if (oldGroup == UNGROUPPED_GROUP_ID) {
          container = cache.getCacheDataByRequest({
            query: getSidebarUngrouppedQuery,
            variables: {},
          });
        } else {
          let group: SidebarGroup = cache.getCacheDataByRequest({
            query: getSidebarGroupQuery,
            variables: {
              id: oldGroup,
            },
          });
          if (group) {
            container = group.resources;
          } else {
            console.warn('could not find the source group in the cache', event);
          }
        }

        if (container) {
          // it should be in the prev container
          let index = container.indexOf(sidebarRes);

          if (index > -1) {
            // remove the element from its old container
            container.splice(index, 1);
          } else {
            console.warn('could not find the element in its original container in the cache');
          }
        }

        // push into the new container
        if (event.groupId == UNGROUPPED_GROUP_ID) {
          cache
            .getCacheDataByRequest({ query: getSidebarUngrouppedQuery, variables: {} })
            .push(sidebarRes);
        } else {
          let group: SidebarGroup = cache.getCacheDataByRequest({
            query: getSidebarGroupQuery,
            variables: {
              id: event.groupId,
            },
          });
          if (group) {
            group.resources.push(sidebarRes);
          } else {
            console.warn('could not find the source group in the cache', event);
          }
        }
      }
      if (event.ordering !== undefined) {
        sidebarRes.ordering = event.ordering;
      }
    } else {
      console.warn('could not found the resource in the cache, but got modified event');
    }
  }

  if (event.hidden === true || event.hidden === false) {
    let dialogue = cache.getCacheDataByRequest({ query: getDialogueDataQuery, variables: event });
    if (dialogue) {
      dialogue.hidden = event.hidden;
    }
  }

  if (event.peerSeenId) {
    let msgId = event.peerSeenId;
    let userId = event.id;
    // update the seen status of the messages

    // init the message if it is not exists
    let seenCacheData: SeenCacheRecord = cache.getCacheData('seen')[userId];
    if (!seenCacheData) {
      seenCacheData = {
        messages: {},
        users: {},
      };

      cache.getCacheData('seen')[userId] = seenCacheData;
    }

    // remove the prev message if exists
    let prevMessageId = seenCacheData.users[userId];

    if (prevMessageId) {
      if (seenCacheData.messages[prevMessageId]) {
        let findUserIndex = seenCacheData.messages[prevMessageId].indexOf(userId);
        if (findUserIndex > -1) {
          seenCacheData.messages[prevMessageId].splice(findUserIndex, 1);
          if (seenCacheData.messages[prevMessageId].length == 0) {
            delete seenCacheData.messages[prevMessageId];
          }
        }
      }
    }

    // add the user to the new message
    if (seenCacheData.messages[msgId]) {
      // user should not be there, so we do not need to check if it is already exists
      seenCacheData.messages[msgId].push(userId);
    } else {
      seenCacheData.messages[msgId] = [userId];
    }

    // add the message to the user
    seenCacheData.users[userId] = msgId;
  }
};
