export class pubSub {
  /**
   * - This method can be used to publish a message to a specified topic within the meeting.
   *
   * @param topic The topic to which the message will be published.
   * @param message The message content to be published. This value must be a string.
   * @param options
   * @param options.persist When set to `true`, the message is stored for the entire session and is available to newly joined participants.
   * @param options.sendOnly An array of `participantId` that should receive the message. If not provided, the message is broadcast to all participants.
   * @param payload Additional data to be sent along with the message.
   *
   * @throws {Error}
   * Throws an error if:
   * - `message` is not a string
   * - `payload` is not an object
   * - the publish request fails
   *
   * @example
   * ```ts
   * const topic = "CHAT";
   *
   * const sendMessage = async (message) => {
   *   try {
   *     await meeting?.pubSub.publish(topic, message, { persist: true });
   *   } catch (error) {
   *     console.error("Error while sending message:", error);
   *   }
   * };
   *
   * sendMessage("Hello world!");
   * ```
   * @returns
   */
  publish(
    topic: string,
    message: string,
    options?: {
      persist?: boolean;
      sendOnly?: Array<string>;
    },
    payload?: object
  ): Promise<void>;

  /**
   * - This method can be used to subscribe to a specific topic and receive messages published under that topic.
   *
   * - The provided callback function is executed whenever a new message is received for the subscribed topic.
   *
   * @param topic The topic to subscribe to.
   * @param callback A function that handles incoming messages for the subscribed topic.
   * @returns A promise that resolves with previously published messages, if message persistence was enabled for the topic.
   *
   * @example
   * ```ts
   * const topic = "CHAT";
   *
   * const handleMessage = (message) => {
   *   console.log(message);
   * };
   *
   * const subscribe = async () => {
   *   const previousMessages = await meeting.pubSub.subscribe(topic, handleMessage);
   *   console.log(previousMessages);
   * };
   * ```
   */
  subscribe(
    topic: string,
    callback: (message: message) => void
  ): Promise<message[]>;

  /**
   * - This method can be used to unsubscribe from a previously subscribed topic and stop receiving messages for that topic.
   *
   * @param topic The topic from which to unsubscribe.
   * @param callback The same callback function that was provided when subscribing to the topic.
   *
   * @example
   * ```ts
   * const handleMessage = (message) => {
   *   console.log(message);
   * };
   *
   * await meeting.pubSub.unsubscribe("CHAT", handleMessage);
   * ```
   */
  unsubscribe(
    topic: string,
    callback: (message: message) => void
  ): Promise<void>;
}

export class message {
  /**
   * Unique identifier for the message.
   */
  id: string;

  /**
   * The message content.
   */
  message: string;

  /**
   * The ID of the participant who sent the message.
   */
  senderId: string;

  /**
   * The display name of the participant who sent the message.
   */
  senderName: string;

  /**
   * Timestamp indicating when the message was published.
   */
  timestamp: string;

  /**
   * The topic under which the message was published.
   */
  topic: string;

  /**
   * Optional additional data sent along with the message.
   */
  payload?: object;
}
