import {
  SubscriptionServiceEvent,
  SubscriptionServiceEventType,
} from '../../../../../../../server-services/subscription-event';
import { CacheInterface, ResponseMergerHandler } from '../../../../cache-logic-interface';
import { WorkspaceChangeSubscriptionHandlerMap } from '../workspace-change-subscription-merger-handlers/types';
import { onNewsHandlerDialogueCreate } from './sub-handler/dialogue-handler/news-handler-dialogue-create';
import { onNewsHandlerDialogueDelete } from './sub-handler/dialogue-handler/news-handler-dialogue-delete';
import { onNewsHandlerDialogueModify } from './sub-handler/dialogue-handler/news-handler-dialogue-modify';
import { onNewsHandlerInit } from './sub-handler/init';
import { onNewsHandlerRoomCreate } from './sub-handler/room-handler/news-handler-room-create';
import { onNewsHandlerRoomDelete } from './sub-handler/room-handler/news-handler-room-delete';
import { onNewsHandlerRoomModify } from './sub-handler/room-handler/news-handler-room-modify';

export type NewsHandlerType = {
  init: ResponseMergerHandler;
  handler: WorkspaceChangeSubscriptionHandlerMap;
};

export let recalculateNews = (cache: CacheInterface) => {
  newsHandler.init(cache, undefined, undefined);
};

export let newsHandler: NewsHandlerType = {
  init: onNewsHandlerInit,
  handler: {
    [SubscriptionServiceEvent.ROOM_EVENT]: {
      [SubscriptionServiceEventType.CREATE]: onNewsHandlerRoomCreate,
      [SubscriptionServiceEventType.MODIFY]: onNewsHandlerRoomModify,
      [SubscriptionServiceEventType.DELETE]: onNewsHandlerRoomDelete,
    },
    [SubscriptionServiceEvent.DIALOGUE_EVENT]: {
      [SubscriptionServiceEventType.CREATE]: onNewsHandlerDialogueCreate,
      [SubscriptionServiceEventType.MODIFY]: onNewsHandlerDialogueModify,
      [SubscriptionServiceEventType.DELETE]: onNewsHandlerDialogueDelete,
    },
  },
};

/**
 * Note: Logic beside the Room/Permission logic ("+" means "CREATE" event, "-" means "DELETE" event)
 *
 * If room is not in the ws/granted/rejected + ROOM_EVENT => put in ws (created room by user)
 * If room is not in the ws/granted/rejected - ROOM_EVENT => invalid case
 * If room is not in the ws/granted/rejected + ROOM_ACCOUNT_PERMISSION => put in granted (incoming invitation)
 * If room is not in the ws/granted/rejected - ROOM_ACCOUNT_PERMISSION => invalid case
 *
 * If room is in the granted + ROOM_EVENT => put in ws, remove from granted (accepted invitation)
 * If room is in the granted - ROOM_EVENT => put in rejected, remove from granted (rejected invitation)
 * If room is in the granted + ROOM_ACCOUNT_PERMISSION => invalid case
 * If room is in the granted - ROOM_ACCOUNT_PERMISSION => remove from granted (kicked from room)
 *
 * If room is in the rejected + ROOM_EVENT => put in ws, remove from rejected (accepted a rejected room)
 * If room is in the rejected - ROOM_EVENT => invalid case
 * If room is in the rejected + ROOM_ACCOUNT_PERMISSION => invalid case
 * If room is in the rejected - ROOM_ACCOUNT_PERMISSION => remove from rejected (kicked from room)
 *
 * If room is in the ws + ROOM_EVENT => invalid case
 * If room is in the ws - ROOM_EVENT => put in rejected, remove from ws (leaved from room)
 * If room is in the ws + ROOM_ACCOUNT_PERMISSION => invalid case
 * If room is in the ws - ROOM_ACCOUNT_PERMISSION => set ws unavailable (kicked from room)
 *
 * If room is in the ws(unavailable) + ROOM_EVENT => invalid case
 * If room is in the ws(unavailable) - ROOM_EVENT => put in rejected, remove from ws (leaved from room)
 * If room is in the ws(unavailable) + ROOM_ACCOUNT_PERMISSION => ws available again (owner gave access)
 * If room is in the ws(unavailable) - ROOM_ACCOUNT_PERMISSION => invalid case
 *
 *
 *
 * In SUM these cases:
 *
 * incoming + ROOM_EVENT:
 *    if (!in ws):
 *      put in ws
 *    remove from granted
 *    remove from rejected
 *
 * incoming - ROOM_EVENT:
 *    if (in granted or in ws):
 *      remove from granted
 *      remove from ws
 *      put in rejected
 *
 * incoming + ROOM_ACCOUNT_PERMISSION:
 *    if (!in granted and !in ws):
 *      put in granted
 *    if (in ws):
 *      room is available
 *
 * incoming - ROOM_ACCOUNT_PERMISSION:
 *    if (in granted):
 *      remove from granted
 *    if (in rejected):
 *      remove from rejected
 *    if (in ws):
 *      room is unavailable
 *
 */
