import { SubscriptionServiceEvent, SubscriptionServiceEventType } from '../subscription-event';
import { MeRecord } from './account-records';
import { DecryptionState, ID, OrderableItem } from './common-records';
import { DialogueRecord, ReactionEnum, RoomData, RoomRecord } from './room-records';
import { SidebarResource } from './sidebar-records';
import { TimedOfferData } from './timed-offer-records';

/**
 * Raw Workspace Query records from direct the server
 *
 *
 *
 *
 *
 */
export interface RawWorkspaceRecord {
  contacts: ID[];
  grantedRoomIds: ID[];
  id: ID;
  me: MeRecord;
  newestApp: string;
  newestNano: string;
  rejectedRoomIds: ID[];
  resourceGroups: RawWorkspaceQueryGroupRecord[];
  timedOffers: RawWorkspaceQueryTimedOffers[];
  ungroupedResources: Array<WorkspaceQueryRoomRecord | WorkspaceQueryDialogueRecord>;
  waitingNanos: { [key: string]: number };
}

/**
 * Decrypted and parsed workspace query records
 *
 *
 *
 *
 *
 */
export interface WorkspaceQueryRecord {
  contacts: string[];
  grantedRooms: ID[];
  me: MeRecord;
  newestApp: string;
  newestNano: string;
  rejectedRooms: ID[];
  resourceGroups: WorkspaceQueryResourceGroupRecord[];
  ungroupedResources: Array<WorkspaceQueryRoomRecord | WorkspaceQueryDialogueRecord>;
  waitingNanos: { [key: string]: number };
  timedOffers: WorkspaceQueryTimedOffers[];
}

export interface AbstractWorkspaceQueryTimedOffers {
  id: ID;
  expiration: number;
}
export interface RawWorkspaceQueryTimedOffers extends AbstractWorkspaceQueryTimedOffers {
  /**
   * raw: JSON parsed data: {\"type\":\"license\",\"number\":1,\"months\":2}
   * after decryption: TimedOfferData
   */
  data: string;
}
export interface WorkspaceQueryTimedOffers extends AbstractWorkspaceQueryTimedOffers {
  /**
   * raw: JSON parsed data: {\"type\":\"license\",\"number\":1,\"months\":2}
   * after decryption: TimedOfferData
   */
  data: TimedOfferData;
}

export interface WorkspaceQueryRoomRecord extends SidebarResource, RoomRecord {}

export interface WorkspaceQueryDialogueRecord extends SidebarResource, DialogueRecord {}

export interface AbstractWorkspaceQueryGroupRecord extends OrderableItem {
  closed: boolean;
  id: ID;
  resources: Array<WorkspaceQueryRoomRecord | WorkspaceQueryDialogueRecord>;
}
export interface RawWorkspaceQueryGroupRecord extends AbstractWorkspaceQueryGroupRecord {
  name: Uint8Array;
}
export interface WorkspaceQueryResourceGroupRecord
  extends AbstractWorkspaceQueryGroupRecord,
    DecryptionState {
  name: string;
}

/**
 * Raw alive subsciption events from the server
 *
 *
 *
 *
 *
 *
 *
 */
export interface RawWorkspaceSubscriptionRecord {
  [SubscriptionServiceEvent.ACCOUNT_EVENT]?: RawWorkspaceSubscriptionAccountEventRecord;
  [SubscriptionServiceEvent.ACCOUNT_CONTACT_EVENT]?: RawWorkspaceSubscriptionAccountContactEventRecord;
  [SubscriptionServiceEvent.ACCOUNT_TRUST_EVENT]?: RawWorkspaceSubscriptionAccountTrustEventRecord;
  [SubscriptionServiceEvent.DIALOGUE_EVENT]?: RawWorkspaceSubscriptionDialogueEventRecord;
  [SubscriptionServiceEvent.DIALOGUE_MESSAGE_EVENT]?: RawWorkspaceSubscriptionDialogueMessageEventRecord;
  [SubscriptionServiceEvent.RESOURCE_GROUP_EVENT]?: RawWorkspaceSubscriptionResourceGroupEventRecord;
  [SubscriptionServiceEvent.ROOM_EVENT]?: RawWorkspaceSubscriptionRoomEventRecord;
  [SubscriptionServiceEvent.ROOM_MESSAGE_EVENT]?: RawWorkspaceSubscriptionRoomMessageEventRecord;
  [SubscriptionServiceEvent.ROOM_PERMISSION_EVENT]?: RawWorkspaceSubscriptionRoomPermissionEventRecord;
  [SubscriptionServiceEvent.ROOM_ACCOUNT_PERMISSION_EVENT]?: RawWorkspaceSubscriptionRoomAccountPermissionEventRecord;
  [SubscriptionServiceEvent.NANO_WAITING_EVENT]?: RawWorkspaceSubscriptionNanoWaitingEventRecord;
  [SubscriptionServiceEvent.ACCOUNT_OFFER_EVENT]?: RawWorkspaceSubscriptionAccountOfferEventRecord;
  [SubscriptionServiceEvent.DIALOGUE_TYPING_EVENT]?: RawWorkspaceSubscriptionDialogueTypingEventRecord;
  [SubscriptionServiceEvent.ROOM_TYPING_EVENT]?: RawWorkspaceSubscriptionRoomTypingEventRecord;
}

/**
 * Decrypted and parsed subscription events from the server
 *
 *
 *
 *
 */

export interface WorkspaceSubscriptionRecord {
  [SubscriptionServiceEvent.ACCOUNT_EVENT]?: WorkspaceSubscriptionAccountEventRecord;
  [SubscriptionServiceEvent.ACCOUNT_CONTACT_EVENT]?: WorkspaceSubscriptionAccountContactEventRecord;
  [SubscriptionServiceEvent.ACCOUNT_TRUST_EVENT]?: WorkspaceSubscriptionAccountTrustEventRecord;
  [SubscriptionServiceEvent.DIALOGUE_EVENT]?: WorkspaceSubscriptionDialogueEventRecord;
  [SubscriptionServiceEvent.DIALOGUE_MESSAGE_EVENT]?: WorkspaceSubscriptionDialogueMessageEventRecord;
  [SubscriptionServiceEvent.RESOURCE_GROUP_EVENT]?: WorkspaceSubscriptionResourceGroupEventRecord;
  [SubscriptionServiceEvent.ROOM_EVENT]?: WorkspaceSubscriptionRoomEventRecord;
  [SubscriptionServiceEvent.ROOM_MESSAGE_EVENT]?: WorkspaceSubscriptionRoomMessageEventRecord;
  [SubscriptionServiceEvent.ROOM_PERMISSION_EVENT]?: WorkspaceSubscriptionRoomPermissionEventRecord;
  [SubscriptionServiceEvent.ROOM_ACCOUNT_PERMISSION_EVENT]?: WorkspaceSubscriptionRoomAccountPermissionEventRecord;
  [SubscriptionServiceEvent.NANO_WAITING_EVENT]?: WorkspaceSubscriptionNanoWaitingEventRecord;
  [SubscriptionServiceEvent.ACCOUNT_OFFER_EVENT]?: WorkspaceSubscriptionAccountOfferEventRecord;
  [SubscriptionServiceEvent.DIALOGUE_TYPING_EVENT]?: WorkspaceSubscriptionDialogueTypingEventRecord;
  [SubscriptionServiceEvent.ROOM_TYPING_EVENT]?: WorkspaceSubscriptionRoomTypingEventRecord;
}

export interface WorkspaceSubscriptionRecordCMD {
  cmd: SubscriptionServiceEventType;
}

// account event ----------
export interface RawWorkspaceSubscriptionAccountEventRecord extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  scopesAdded?: string[];
  scopesRemoved?: string[];
  scopesReset?: string[];
  parentAccountId?: string; // not used/obsolete
  avatarImageKey?: string;
  avatarName?: string;
  email?: string;
  selectedStatus?: number; // not used
  walletAddress?: string;
}

export interface WorkspaceSubscriptionAccountEventRecord
  extends RawWorkspaceSubscriptionAccountEventRecord {}

// contact event ------------
export interface RawWorkspaceSubscriptionAccountContactEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  peerId: ID;
}
export interface WorkspaceSubscriptionAccountContactEventRecord
  extends RawWorkspaceSubscriptionAccountContactEventRecord {}

// account trust event -------
export interface RawWorkspaceSubscriptionAccountTrustEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  peerId: ID;
  trust: Uint8Array;
}

export interface WorkspaceSubscriptionAccountTrustEventRecord
  extends RawWorkspaceSubscriptionAccountTrustEventRecord {}

// dialogue event -----------
export interface RawWorkspaceSubscriptionDialogueEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  ordering?: number;
  ignore?: boolean;
  hidden?: boolean;
  groupId?: ID;
  seenMessageId?: ID;
  topMessageId?: ID;
  peerSeenId?: ID | null;
}

export interface WorkspaceSubscriptionDialogueEventRecord
  extends RawWorkspaceSubscriptionDialogueEventRecord {}

// dialogue message event -------------
export interface AbstractWorkspaceSubscriptionDialogueMessageEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  messageId: ID;
  posterId: ID;
  edited?: boolean;
  reactionsAdded?: { [userId: ID]: ReactionEnum };
  reactionsRemoved?: ID[];
}
export interface RawWorkspaceSubscriptionDialogueMessageEventRecord
  extends AbstractWorkspaceSubscriptionDialogueMessageEventRecord {
  content?: Uint8Array;
}

export interface WorkspaceSubscriptionDialogueMessageEventRecord
  extends AbstractWorkspaceSubscriptionDialogueMessageEventRecord,
    DecryptionState {
  content?: string;
  edited?: boolean;
}

// resource group event

export interface AbstractWorkspaceSubscriptionResourceGroupEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  /**
   * raw: Uint8Array
   * decrypted: string
   */
  ordering?: number;
  closed?: boolean;
}
export interface RawWorkspaceSubscriptionResourceGroupEventRecord
  extends AbstractWorkspaceSubscriptionResourceGroupEventRecord {
  /**
   * raw: Uint8Array
   * decrypted: string
   */
  name?: Uint8Array;
}

export interface WorkspaceSubscriptionResourceGroupEventRecord
  extends AbstractWorkspaceSubscriptionResourceGroupEventRecord,
    DecryptionState {
  /**
   * raw: Uint8Array
   * decrypted: string
   */
  name?: string;
}

// room event -------------
export interface AbstractWorkspaceSubscriptionRoomEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  topMessageId?: ID;
  /**
   * raw: Uint8Array
   * decrypted: roomDataQueryDataRecord
   */
  nanoSessionsAdded?: { [key: string]: number };
  nanoSessionsRemoved?: string[];
  nanoSessionsReset?: { [key: string]: number };
  ordering?: number;
  ignore?: boolean;
  /**
   * null means ungroupped-group
   */
  groupId?: ID;
  seenMessageId?: ID;
  rejected?: boolean;
  peerSeenIdsAdded?: { [userId: string]: string }; // userId->messageId
}

export interface RawWorkspaceSubscriptionRoomEventRecord
  extends AbstractWorkspaceSubscriptionRoomEventRecord {
  /**
   * raw: Uint8Array
   * decrypted: roomDataQueryDataRecord
   */
  data?: Uint8Array;
}

export interface WorkspaceSubscriptionRoomEventRecord
  extends AbstractWorkspaceSubscriptionRoomEventRecord {
  /**
   * raw: Uint8Array
   * decrypted: roomDataQueryDataRecord
   */
  data?: RoomData;
}

// room message event ----------------
export interface AbstractWorkspaceSubscriptionRoomMessageEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  messageId: ID;
  posterId: ID;
  edited?: boolean;
  reactionsAdded?: { [userId: ID]: ReactionEnum };
  reactionsRemoved?: ID[];
}

export interface RawWorkspaceSubscriptionRoomMessageEventRecord
  extends AbstractWorkspaceSubscriptionRoomMessageEventRecord {
  /**
   * raw: Uint8Array
   * decrypted: string
   */
  content?: Uint8Array;
}

export interface WorkspaceSubscriptionRoomMessageEventRecord
  extends AbstractWorkspaceSubscriptionRoomMessageEventRecord,
    DecryptionState {
  /**
   * raw: Uint8Array
   * decrypted: string
   */
  content?: string;
}

// typing event --------------------------
export interface RawWorkspaceSubscriptionDialogueTypingEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
}

export interface RawWorkspaceSubscriptionRoomTypingEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  accountId: ID;
}
export interface WorkspaceSubscriptionDialogueTypingEventRecord
  extends RawWorkspaceSubscriptionDialogueTypingEventRecord {}
export interface WorkspaceSubscriptionRoomTypingEventRecord
  extends RawWorkspaceSubscriptionRoomTypingEventRecord {}

// room permission event -----------------
export interface RawWorkspaceSubscriptionRoomPermissionEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  blockId: ID;
  ownerAccountId?: ID;
  allowAnonymous?: boolean;
  msgBrdReadOnly?: boolean;
  noReactions?: boolean;
}

export interface WorkspaceSubscriptionRoomPermissionEventRecord
  extends RawWorkspaceSubscriptionRoomPermissionEventRecord {}

// account permission event ----------------
export interface RawWorkspaceSubscriptionRoomAccountPermissionEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  accountId: ID;
  ownerAccountId?: ID;
  msgBrdModerate?: boolean;
  administrator?: boolean;
  driveWrite?: boolean;
  driveAdhoc?: boolean;
  driveUpload?: boolean;
}

export interface WorkspaceSubscriptionRoomAccountPermissionEventRecord
  extends RawWorkspaceSubscriptionRoomAccountPermissionEventRecord {}

// nano waiting event ------------------
export interface RawWorkspaceSubscriptionNanoWaitingEventRecord
  extends WorkspaceSubscriptionRecordCMD {
  id: ID;
  waiterId: string;
  aliveUntil: number;
}

export interface WorkspaceSubscriptionNanoWaitingEventRecord
  extends RawWorkspaceSubscriptionNanoWaitingEventRecord {}

// account offer event --------------
export interface RawWorkspaceSubscriptionAccountOfferEventRecord
  extends WorkspaceSubscriptionRecordCMD,
    RawWorkspaceQueryTimedOffers {}

export interface WorkspaceSubscriptionAccountOfferEventRecord
  extends WorkspaceSubscriptionRecordCMD,
    WorkspaceQueryTimedOffers {}
