/**
 * Interface for Vivocha React Native SDK class
 */
export default interface VivochaInterface {
  /**
   * Singleton instance
   */
  readonly instance: this;

  /**
   * Developer mode enabled
   */
  developerMode: boolean;

  /**
   * Local theme for the UI
   */
  theme: Object;

  /**
   * Show the side button
   */
  sideTab: boolean;

  /**
   * Use a different language
   */
  language: string;

  /**
   * Current agent or null
   */
  readonly agent: Object;

  /**
   * Current media or null
   */
  readonly media: Object;

  /**
   * current visit VVC-T
   */
  readonly vvcu: string;

  /**
   * current VVC-U identifier
   */
  readonly vvct: string;

  /**
   * Native SDK version
   */
  readonly SDK_VERSION: string;

  /**
   * Native SDK name
   */
  readonly SDK_NAME: string;

  /**
   * Native SDK base url
   */
  readonly SDK_BASE_URL: string;

  /**
   * Start Vivocha client
   *
   * @param accountId - Account ID
   * @param serviceId - Service ID
   * @param options - (optional) Vivocha options
   * @returns a Promise that resolve to an Object containing server configuration
   */
  start(
    accountId: string,
    serviceId: string,
    options?: Object
  ): Promise<Object>;

  /**
   * Stop Vivocha
   *
   * @returns true on success
   */
  stop(): boolean;

  /**
   * Add new translation
   *
   * @param language - language to ad or update
   * @param localization - new or updated localization object
   */
  addLocalization(language: String, localization: Object): this;

  /**
   * Set JWT token for customer verification
   *
   * @param jwt - JWT token
   */
  setCustomerToken(jwt: string): void;

  /**
   * Reset JWT token
   */
  unsetCustomerToken(): void;

  /**
   * Set the data collection that will be sent when a new contact is requested.
   *
   * @param data - Object representing data collection
   */
  setDataCollection(data: Array<Object>): void;

  /**
   * Get the data collection that will be sent when a new contact is requested.
   *
   * @return Object representing data collection
   */
  getDataCollection(): Object;

  /**
   * Create contact with given type
   *
   * @param data - data collection
   * @param type - contact type (es. "chat")
   * @param [params] - a dictionary with the parameters needed for the contact creation
   * @return a Promise that resolve to an Object representing Contact
   */
  createContact(data: Object, type: string, params?: Object): Promise<Object>;

  /**
   * Create Call Back Now
   *
   * @param phoneNumber - Customer's phone number
   * @param data - data collection
   * @return a Promise that resolve to an Object representing Contact
   */
  createCallBackNow(phoneNumber: string, data?: Object): Promise<Object>;

  /**
   * Create new Chat
   *
   * @param data - data collection
   * @return a Promise that resolve to an Object representing Contact
   */
  createChat(data?: Object): Promise<Object>;

  /**
   * Create new Video Chat
   *
   * @param data - data collection
   * @return a Promise that resolve to an Object representing Contact
   */
  createVideoChat(data?: Object): Promise<Object>;

  /**
   * Get current contact
   *
   * @returns an object representing current contact or null
   */
  getContact(): Object;

  /**
   * Get current conversation
   *
   * @returns an object representing current conversation
   */
  getConversation(): Object;

  /**
   * Get number of unread messages
   *
   * @returns unread message count
   */
  getUnreadMessageCount(): number;

  /**
   * Set Agent Desktop custom action callback
   *
   * @param code - action name
   * @param action - action callback
   */
  onAction(
    code: string,
    callback: (name: string, id: string, data: Object) => void
  ): this;

  /**
   * Set URL tap custom action
   *
   * @param callback - custom action callback that returns true if "tap" was managed by application
   */
  onUrlTapped(callback: (url: string) => boolean): this;

  /**
   * Send a custom action to the agent
   * @param name - action name
   * @param id - action unique identifier
   * @param data - action data array
   */
  sendAction(name: string, id: string, data?: Array<any>): this;

  /**
   * Send a message to the agent
   *
   * @param body - test message
   * @param type - message type
   * @param payload - additional payload
   */
  sendMessage(body: string, type: string | null, payload: string | null): this;

  /**
   * Send an attachment to the agend
   *
   * @param url - attachment remote url
   * @param referenceId - reference id for attachment
   * @param title - original file name
   * @param mimetype - attachment mime type
   * @param description - attachment description
   * @param size - attachment file size
   */
  sendAttachment(
    url: string,
    referenceId: string,
    title: string,
    mimetype: string,
    description: string,
    size: number
  ): this;

  /**
   * Hide chat view
   *
   * @param animated - it true preform animation in hiding (default true)
   */
  hideView(animated?: boolean): void;

  /**
   * Show chat view
   *
   * @param animated - it true preform animation in showing (default true)
   */
  showView(animated?: boolean): void;

  /**
   * Send survey result to Vivocha
   *
   * @param contactId - contact ID
   * @param data - survey data collection
   * @returns a Promise that resolve to true
   */
  storeSurvey(contactId: string, data: Object): Promise<boolean>;

  /**
   * Terminate contact
   *
   * @param hideView - hide chat if true (default true)
   */
  terminate(hideView?: boolean): void;

  /**
   * Stop current screenshot session
   */
  stopScreenshotSession(): void;

  /**
   * Check if user authorized screenshot
   *
   * @returns authorization status
   */
  isScreenshotSessionAuthorized(): boolean;

  /**
   * Set push Token (IOS)
   *
   * @param token - push token
   */
  setPushToken(token: string): void;

  /**
   * Set push registration ID (Android)
   *
   * @param regId - push registration ID
   */
  setPushRegistrationId(regId: string): void;

  /** This is fired when there is a new check for agent availability. */
  on(
    eventName: 'agentdata',
    listener: (available: boolean, numberofchats: number, data: Object) => void
  ): this;
  /** This is fired when a persistence from local or remote has been performed. */
  on(
    eventName: 'persistence',
    listener: (
      conversation: Object,
      currentcontact: Object,
      didresumecontactfromconversation: boolean
    ) => void
  ): this;
  /** An agent joined or left the contact. */
  on(eventName: 'agentpresence', listener: (presence: Object) => void): this;
  /** Notifies that the agent is typing */
  on(eventName: 'agenttyping', listener: (istyping: boolean) => void): this;
  /** Notifies that a message Ack (Received, Read) has arrived from the Agent. */
  on(eventName: 'chatackreceived', listener: (ack: Object) => void): this;
  /** Notifies that a message Ack (Received, Read) has been sent to the server. */
  on(eventName: 'chatacksent', listener: (ack: Object) => void): this;
  /** Notifies that the contact has been terminated by the agent. */
  on(eventName: 'closeremote', listener: (contactid: string) => void): this;
  /** Notifies that a custom action has been sent from the App to the Agent Desktop */
  on(eventName: 'actionsent', listener: (action: Object) => void): this;
  /** A message has been received. */
  on(eventName: 'messagereceived', listener: (message: Object) => void): this;
  /** Notifies that a message has been sent from the Customer. */
  on(eventName: 'messagesent', listener: (message: Object) => void): this;
  /** An attachment has been received. */
  on(
    eventName: 'attachmentreceived',
    listener: (attachment: Object) => void
  ): this;
  /** Notifies that an attachment has been sent from the Customer. */
  on(eventName: 'attachmentsent', listener: (attachment: Object) => void): this;
  /** Notifies that a Screenshot session has been authorized/stopped by the user */
  on(
    eventName: 'screenshotsession',
    listener: (authorized: boolean) => void
  ): this;
  /** Notifies that the contact has been terminated. */
  on(eventName: 'terminate', listener: (contactid: string) => void): this;
  /** Notifies that the contact has been transferred and it changed contact ID. */
  on(
    eventName: 'transferred',
    listener: (oldcontactid: string, newcontactid: string) => void
  ): this;
  /** The contact terminated was triggered by the user tapping on the Terminate button. */
  on(eventName: 'terminatebutton', listener: (contactid: string) => void): this;

  /**
   * Remove a single listener
   *
   * @param eventName - event name
   * @param listener - listener to be removed from the chain
   */
  removeListener(
    eventName: string | symbol,
    listener: (...args: any[]) => void
  ): this;
}
