import { TIMPushManager } from "TIMPush"
import { NSObject } from "DCloudUTSFoundation"
import PushListener from './push-listener.uts'
import { PushListenerOptions } from './push-listener-options.uts'

const LOG_PREFIX = 'Push |';

export class EVENT {
  static MESSAGE_RECEIVED: string = 'message_received'
  static MESSAGE_REVOKED: string = 'message_revoked'
  static NOTIFICATION_CLICKED: string = 'notification_clicked'
}

function setRunningPlatform(): void {
    console.log(LOG_PREFIX, 'setRunningPlatform');
    const param = new NSString("{\"runningPlatform\":2}");   
    TIMPushManager.callExperimentalAPI('setPushConfig', param = param, succ = (ext?: NSObject): void => {
      let platform: string = ext as string;
      console.log(LOG_PREFIX, 'setRunningPlatform ok. platform:', platform);
    }, fail = (code?: Int32 ,desc?:String): void => {
      console.log(LOG_PREFIX, `setRunningPlatform fail. code: ${code}, desc: ${desc}`);
    }
  );
}

let disableNotification = false;

export function disablePostNotificationInForeground(_disable: boolean): void {
  console.log(LOG_PREFIX, 'disablePostNotificationInForeground', _disable);
  disableNotification = _disable;
  TIMPushManager.disablePostNotificationInForeground(disable = disableNotification);
}

export function registerPush(SDKAppID: number, appKey: string, onSuccess: (data: string) => void, onError?: (errCode: number, errMsg: string) => void): void {
    if (SDKAppID == 0) {
        onError?.(9010001, 'Invalid SDKAppID');
    } else if (appKey == '') {
        onError?.(9010002, 'Invalid appKey');
    }
  setRunningPlatform();
    TIMPushManager.registerPush(SDKAppID.toInt32(), appKey = appKey, succ = (deviceToken?: Data): void => {
            TIMPushManager.disablePostNotificationInForeground(disable = disableNotification);
            console.log('devicetoken ->', deviceToken, deviceToken?.count);
            onSuccess('');
        }, fail = (code?: Int32 ,desc?:String): void => {
            onError?.(code as number, desc as string);
        }
    );
}

export function unRegisterPush(onSuccess: () => void, onError: (errCode: number, errMsg: string) => void): void {
    TIMPushManager.unRegisterPush((): void => {
            onSuccess();
        }, fail = (code?: Int32 ,desc?:String): void => {
            onError(code as number, desc as string);
        }
    );
}

export function setRegistrationID(registrationID: string, onSuccess: () => void): void {
    console.log(LOG_PREFIX, 'setRegistrationID', `registrationID:${registrationID}`);
    TIMPushManager.setRegistrationID(registrationID, callback = (): void => {
        console.log(LOG_PREFIX, 'setRegistrationID ok');
        onSuccess();
    });
}

export function getRegistrationID(onSuccess: (registrationID: string) => void): void {
    TIMPushManager.getRegistrationID((value ?: string): void => {
    // 这里需要转一下，否则会有问题
    let ret: string = value as string;
    onSuccess(ret);
    });
}

export function createNotificationChannel(options: any, onSuccess: (data: string) => void): void {
  // 空实现
}

// 注意！！！这里的 extInfo 不能写成 ext，否则会跟内部的 ext?:NSObject 有冲突；也不能写成 extension，否则会导致编译错误
export function getNotificationExtInfo(onSuccess: (extInfo: string) => void): void {
    console.log(LOG_PREFIX, 'getNotificationExtInfo');
    TIMPushManager.callExperimentalAPI('getNotificationExtInfo', param = {}, succ = (ext?: NSObject): void => {
      let str: string = ext as string;
      console.log(LOG_PREFIX, 'getNotificationExtInfo ok. ext:', str);
      onSuccess(str);
    }, fail = (code?: Int32 ,desc?:String): void => {
      // 空实现
    }
  );
}


const listenerMap = new Map<string, Array<(res: any) => void>>();

const pushListenerOptions: PushListenerOptions = {
  listener: (eventName: string, data: any) => {
    listenerMap.get(eventName)?.forEach(item => {
      item(data);
    });
  },
};

const pushListener = new PushListener(pushListenerOptions);

@UTSJS.keepAlive
export function addPushListener(eventName: string, _listener: (res: any) => void): void {
  console.log(LOG_PREFIX, 'addPushListener', eventName);
  if(listenerMap.size === 0) {
    TIMPushManager.addPushListener(listener = pushListener);
  }
  const listeners:Array<(res: any) => void> = [_listener];
  listenerMap.get(eventName)?.forEach(item => {
    listeners.push(item);
  })
  listenerMap.set(eventName, listeners);
}

export function removePushListener(eventName: string, _listener?: (res: any) => void): void {
  console.log(LOG_PREFIX, 'removePushListener', eventName);
  listenerMap.delete(eventName);
  if(listenerMap.size === 0) {
    TIMPushManager.removePushListener(listener = pushListener);
  }
}