import TUICore, { TUILogin, TUIConstants } from '@tencentcloud/tui-core';
import TUIChatEngine, { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
import { TUIGlobal } from '@tencentcloud/universal-api';
import { ITUIComponents, ITUIPlugins } from './interface';
import TUILocales from './locales';
import { isFunction, isObject } from './utils';
import { isApp } from './utils/env';
import CallkitPluginServer from './plugins/extension-server/callkit';
export default class TUIChatKit {
  static isInitialized: boolean;
  public chat: any;

  public SDKAppID: number;
  public TUICore: any;
  public TUIChatEngine: any;
  public TUIGlobal: any;
  public TUIComponents: ITUIComponents = {};
  public TUIPlugins: ITUIPlugins = {};

  constructor() {
    this.TUICore = TUICore;
    this.TUIChatEngine = TUIChatEngine;
    this.TUIGlobal = TUIGlobal;
    this.SDKAppID = 0;
    this.TUIGlobal._isTIMCallKit = true;
    TUICore.registerEvent(
      TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED,
      TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS,
      this,
    );
    // register translate and voiceToText service event tracking
    TUICore.registerService(TUIConstants.TUITranslatePlugin.SERVICE.NAME, 1);
    TUICore.registerService(TUIConstants.TUIVoiceToTextPlugin.SERVICE.NAME, 1);
  }

  /**
   * 监听 TUILogin.login 的成功通知
   * @param { TUIInitParam } params 初始化参数
   */
  public onNotifyEvent(eventName: string, subKey: string) {
    if (eventName === TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED) {
      switch (subKey) {
        case TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS:
          this.login();
          break;
      }
    }
  }

  /**
   * init 初始化
   */
  public init() {
    // 向下兼容，新版本在 index.ts 中默认执行 init 操作
    if (TUIChatKit.isInitialized) {
      return;
    }
    TUIChatKit.isInitialized = true;
    // 原生插件 TUICallKit 存在时执行 call server
    if (isApp) {
      new CallkitPluginServer();
    }
    // TUITranslateService init
    TUITranslateService.provideLanguages({ ...TUILocales });
    TUITranslateService.useI18n();
    // TUIComponents global install
    TUIGlobal.TUIComponents = this.TUIComponents;
    // TUIPlugins global install
    TUIGlobal.TUIPlugins = this.TUIPlugins;
    console.warn('[TUIChatKit]: init success.');
  }

  /**
   * login 登录
   */
  public login() {
    const { chat, SDKAppID, userID, userSig } = TUILogin.getContext();
    this.SDKAppID = SDKAppID;
    this.TUIChatEngine.login({
      chat,
      SDKAppID,
      userID,
      userSig,
    });
    this.chat = chat;
    return this.TUIChatEngine;
  }

  /**
   * 单个组件挂载
   *
   * @param {string} componentName  挂载的组件名
   * @param {any} component 挂载的组件
   * @param {any=} env Vue2/Vue3环境
   * @returns {TUICore} 挂载后的实例
   */
  public component(componentName: string, component: any, env?: any) {
    if (this?.TUIComponents?.componentName) {
      console.warn(
        `[TUIChatKit]: ${this?.TUIComponents?.componentName} component has already been applied to target TUIChatEngine.`,
      );
    } else {
      this.TUIComponents[componentName] = component;
      env?.component(componentName, component);
    }
    if (env) {
      !TUIGlobal.Vue && (TUIGlobal.Vue = env);
    }
    return this.TUIChatEngine;
  }

  /**
   * 组件列表挂载
   *
   * @param {object} components 挂载的组件列表
   * @param {any=} env Vue2/Vue3环境
   * @returns {TUICore} 挂载后的实例
   */
  public components(components: object, env?: any) {
    if (!components || !isObject(components)) {
      console.warn('[TUIChatKit]: components is empty or not object.');
    } else {
      Object?.keys(components)?.forEach((key: string) => {
        this.component(key, components[key as keyof typeof components], env);
      });
    }
    return this.TUIChatEngine;
  }

  /**
   * 插件注入
   *
   * @param {any} TUIPlugin 需要挂载模块的服务
   * @param {any} options 其他参数
   * @returns {TUICore} 挂载后的实例
   */
  public use(TUIPluginName: string, TUIPlugin: any, options?: any) {
    if (!this.TUICore) {
      console.warn(
        `[TUIChatKit]: Plugin ${this.TUIPlugins[TUIPluginName]} can't be used before init.`,
      );
      return;
    }
    if (this.TUIPlugins[TUIPluginName]) {
      console.warn(
        `[TUIChatKit]: Plugin ${this.TUIPlugins[TUIPluginName]} has already been applied to target TUIChatEngine.`,
      );
    } else if (TUIPlugin && isFunction(TUIPlugin?.plugin)) {
      this.TUIPlugins[TUIPluginName] = TUIPlugin;
      TUIPlugin?.plugin(this, options);
    } else if (isFunction(TUIPlugin)) {
      this.TUIPlugins[TUIPluginName] = TUIPlugin;
      TUIPlugin(this, options);
    } else {
      console.warn(
        '[TUIChatKit]: A plugin must either be a function or an object with an "plugin" '
        + 'function.'
        + this.TUIPlugins[TUIPluginName]
        + 'does not comply with the above rules.',
      );
    }
    return this.TUIChatEngine;
  }
}
