import NIM from '../NIM';

type MergeUtilsKeys = 'mergeFriends'
  | 'mergeLoginPorts'
  | 'mergeMsgs'
  | 'mergeRelations'
  | 'mergeSessions'
  | 'mergeSysMsgs'
  | 'mergeTeamMembers'
  | 'mergeTeams'
  | 'mergeUsers';

type CutUtilsKeys = 'cutFriends'
  | 'cutMsgs'
  | 'cutSessions'
  | 'cutFriendsByAccounts'
  | 'cutLoginPorts'
  | 'cutRelations'
  | 'cutTeamMembers'
  | 'cutTeamMembersByAccounts'
  | 'cutTeams';

/**
 * 云信内置工具函数
 * - [相关文档](https://dev.yunxin.163.com/docs/interface/即时通讯Web端/NIMSDK-Web/util.html)
 */
export interface NIMUtils extends Pick<NIM, MergeUtilsKeys | CutUtilsKeys> {
  /**
   * 从数组里面去除某些项
   * @param arr1 数组1
   * @param arr2 数组2
   * @param options 配置参数; keyPath 去重的字段, 默认为 id
   */
  cutObjArray<T extends {}>(arr1: T[], arr2: T[], options?: { keyPath: keyof T }): T[];
  /**
   * 在数组里面找 keyPath 对应的属性值为 value 的元素
   * - 数组的每一项均为对象, 并且必须有由 keyPath 指定的属性
   * @param array
   * @param options
   */
  findObjInArray<T extends {}, O extends { keyPath: keyof T, value: T[O['keyPath']] }>(array: T[], options: O): null | T;
  /** 生成一个 32 位的 GUID/UUID */
  guid(): string;
  /**
   * 合并数组
   * - 此方法接收不定量参数
   * - 最后一个参数如果是对象, 那么就是配置参数
   * - 除了配置参数之外, 所有其它的参数都必须是数组, 它们都会被合并
   * - 如果两个对象keyPath字段对应的属性值相同, 后面的对象会被合并到前面的对象
   */
  mergeObjArray<T>(...args: T[][]): T[];
  mergeObjArray<T>(arr1: T[], arr2: T[], options?: {}): T[];
  mergeObjArray<T>(arr1: T[], arr2: T[], arr3: T[], options?: {}): T[];
  mergeObjArray<T>(arr1: T[], arr2: T[], arr3: T[], arr4: T[], options?: {}): T[];
  /**
   * 数组的每一项都为 Object, 并且必须有由 sortPath 指定的属性
   * @param array 待排序的数组
   * @param options 配置参数
   */
  sortObjArray<T>(array: T[], options?: {}): T[];
}
