import {
  DialogueRecord,
  RoomRecord,
} from '../../../../../../server-services/query-records/room-records';
import {
  ResourceType,
  SidebarGroup,
  SidebarResource,
  UNGROUPPED_GROUP_ID,
} from '../../../../../../server-services/query-records/sidebar-records';
import {
  WorkspaceQueryDialogueRecord,
  WorkspaceQueryRecord,
  WorkspaceQueryRoomRecord,
} from '../../../../../../server-services/query-records/workspace-records';
import {
  getAccountQuery,
  getAllAccountIdQuery,
  getAllRoomQuery,
  getAllSidebarGroupQuery,
  getAndroidAppVersionQuery,
  getContactListIdsQuery,
  getDialogueDataQuery,
  getMeQuery,
  getNanoVersionQuery,
  getRoomQuery,
  getSidebarGrantedRoomsQuery,
  getSidebarGroupQuery,
  getSidebarRejectedRoomsQuery,
  getSidebarResourceQuery,
  getSidebarUngrouppedQuery,
  getTimedOffersQuery,
  waitingNanosQuery,
} from '../../../../../../server-services/querys';
import { ResponseMergerHandler } from '../../../cache-logic-interface';
import { recalculateNews } from '../../subscription-merger/sub-merger/news-handler/news-handler';

export let customWorkspaceQueryMerger: ResponseMergerHandler = function (
  cache,
  request,
  response: WorkspaceQueryRecord
) {
  cache.setCacheDataByRequest({ query: getAllAccountIdQuery, variables: {} }, []);
  cache.setCacheDataByRequest({ query: getAllRoomQuery, variables: {} }, []);
  cache.setCacheDataByRequest({ query: getAllSidebarGroupQuery, variables: {} }, []);

  let allResource: Array<WorkspaceQueryRoomRecord | WorkspaceQueryDialogueRecord> = [];

  response.resourceGroups.forEach((group) => {
    allResource = allResource.concat(group.resources);

    let sidebarGroup: SidebarGroup = {
      id: group.id,
      closed: group.closed,
      ordering: group.ordering,
      resources: [],
      name: group.name,
      decryptionError: group.decryptionError,
      decryptionErrorMessage: group.decryptionErrorMessage,
    };

    group.resources.forEach((res) => {
      let sidebarRes: SidebarResource = {
        id: res.id,
        ordering: res.ordering,
        type: res.type,
        groupId: group.id,
      };
      cache.setCacheDataByRequest({ query: getSidebarResourceQuery, variables: res }, sidebarRes);
      sidebarGroup.resources.push(sidebarRes);
    });

    cache.setCacheDataByRequest({ query: getSidebarGroupQuery, variables: group }, sidebarGroup);

    cache
      .getCacheDataByRequest({ query: getAllSidebarGroupQuery, variables: {} })
      .push(sidebarGroup);
  });

  allResource = allResource.concat(response.ungroupedResources);

  let ungroupRes: SidebarResource[] = [];
  response.ungroupedResources.forEach((res) => {
    let sidebarRes: SidebarResource = {
      id: res.id,
      ordering: res.ordering,
      type: res.type,
      groupId: UNGROUPPED_GROUP_ID,
    };

    cache.setCacheData(
      cache
        .getCacheLogic()
        .makeCacheDataPath({ query: getSidebarResourceQuery, variables: { id: res.id } }),
      sidebarRes
    );
    ungroupRes.push(sidebarRes);
  });
  cache.setCacheDataByRequest({ query: getSidebarUngrouppedQuery, variables: {} }, ungroupRes);

  cache.setCacheDataByRequest(
    { query: getSidebarGrantedRoomsQuery, variables: {} },
    response.grantedRooms
  );

  cache.setCacheDataByRequest(
    { query: getSidebarRejectedRoomsQuery, variables: {} },
    response.rejectedRooms
  );

  allResource.forEach((resource) => {
    if (resource.type == ResourceType.ROOM) {
      let res: WorkspaceQueryRoomRecord = <WorkspaceQueryRoomRecord>resource;
      let room: RoomRecord = {
        id: res.id,
        nanoSessions: res.nanoSessions,
        ownerAccountId: res.ownerAccountId,
        pinnedKey: res.pinnedKey,
        seenMessageId: res.seenMessageId,
        topMessageId: res.topMessageId,
        ignore: res.ignore,
        inaccessible: res.inaccessible,
        savedKey: res.savedKey,
      };

      cache.setCacheDataByRequest({ query: getRoomQuery, variables: { id: resource.id } }, room);
      cache.getCacheDataByRequest({ query: getAllRoomQuery, variables: {} }).push(room);
    } else {
      let res: WorkspaceQueryDialogueRecord = <WorkspaceQueryDialogueRecord>resource;
      let dialogue: DialogueRecord = {
        hidden: res.hidden,
        id: res.id,
        ignore: res.ignore,
        seenMessageId: res.seenMessageId,
        topMessageId: res.topMessageId,
      };

      cache.setCacheDataByRequest(
        { query: getDialogueDataQuery, variables: { id: resource.id } },
        dialogue
      );
      cache.getCacheDataByRequest({ query: getAllAccountIdQuery, variables: {} }).push(resource.id);
    }
  });

  cache.setCacheDataByRequest({ query: waitingNanosQuery, variables: {} }, response.waitingNanos);
  cache.setCacheDataByRequest({ query: getMeQuery, variables: {} }, response.me);
  cache.setCacheDataByRequest({ query: getContactListIdsQuery, variables: {} }, response.contacts);
  cache.setCacheDataByRequest({ query: getNanoVersionQuery, variables: {} }, response.newestNano);
  cache.setCacheDataByRequest(
    { query: getAndroidAppVersionQuery, variables: {} },
    response.newestApp
  );

  cache.setCacheDataByRequest(
    { query: getAccountQuery, variables: { id: response.me.id } },
    response.me
  );

  let allAccountId = cache.getCacheDataByRequest({ query: getAllAccountIdQuery, variables: {} });
  response.contacts.forEach((contactId) => {
    if (!allAccountId.includes(contactId)) {
      cache.getCacheDataByRequest({ query: getAllAccountIdQuery, variables: {} }).push(contactId);
    }
  });

  cache.setCacheDataByRequest({ query: getTimedOffersQuery, variables: {} }, response.timedOffers);

  cache.setCacheData(cache.getCacheLogic().makeCacheDataPath(request), response);

  recalculateNews(cache);

  console.log('cache', cache);
};
