import { UTSAndroid } from 'io.dcloud.uts';
import Context from 'android.content.Context';
import TIMPushManager from 'com.tencent.qcloud.tim.push.TIMPushManager';
import TIMPushConfig from 'com.tencent.qcloud.tim.push.config.TIMPushConfig';
import { PushCallbackOptions } from './push-callback-options.uts';
import { PushListenerOptions } from './push-listener-options.uts';
import PushCallback from './push-callback.uts';
import PushListener from './push-listener.uts';

const context: Context | null = UTSAndroid.getAppContext();
console.warn('Push | package.name:', context?.getPackageName());
TIMPushConfig.getInstance().setRunningPlatform(2);
const Push = TIMPushManager.getInstance();

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

let disableNotification = false;
export function disablePostNotificationInForeground(disable: boolean): void {
  console.log('Push | disablePostNotificationInForeground', disable);
	disableNotification = disable;
	Push.disablePostNotificationInForeground(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');
    }
    const pushCbOptions: PushCallbackOptions = {
        apiName: 'registerPush',
        success: (res?: any) => {
            Push.disablePostNotificationInForeground(disableNotification);
            // 强转下类型，避免类型推断错误
            let token: string = res as string;
            onSuccess(token);
        },
        fail: (errCode: number, errMsg: string) => {
            onError?.(errCode, errMsg);
        }
    };
    // 注意！！！ 这里不要写成 new PushCallback({ api, success, fail })，否则会因类型推断不一致导致编译错误
    Push.registerPush(context, SDKAppID.toInt(), appKey, new PushCallback(pushCbOptions));
}

export function setRegistrationID(registrationID: string,  onSuccess: () => void): void {
    const pushCbOptions: PushCallbackOptions = {
        apiName: 'setRegistrationID',
        success: (res?: any) => {
            onSuccess();
        },
        fail: (errCode: number, errMsg: string) => {
            // 空实现
        }
    };
    // 注意！！！ 这里不要写成 new PushCallback({ api, success, fail })，否则会因类型推断不一致导致编译错误
    Push.setRegistrationID(registrationID, new PushCallback(pushCbOptions));
}

export function getRegistrationID(onSuccess: (registrationID: string) => void): void {
    const pushCbOptions: PushCallbackOptions = {
        apiName: 'getRegistrationID',
        success: (res?: any) => {
            // 强转下类型，避免类型推断错误
            let registrationID: string = res as string;
            onSuccess(registrationID);
        },
        fail: (errCode: number, errMsg: string) => {
            // 空实现
        }
    };
    // 注意！！！ 这里不要写成 new PushCallback({ api, success, fail })，否则会因类型推断不一致导致编译错误
    Push.getRegistrationID(new PushCallback(pushCbOptions));
}

export function unRegisterPush(onSuccess: () => void, onError?: (errCode: number, errMsg: string) => void): void {
    const pushCbOptions: PushCallbackOptions = {
        apiName: 'unRegisterPush',
        success: (res?: any) => {
            onSuccess();
        },
        fail: (errCode: number, errMsg: string) => {
            // 空实现
        },
    };
    // 注意！！！ 这里不要写成 new PushCallback({ api, success, fail })，否则会因类型推断不一致导致编译错误
    Push.unRegisterPush(new PushCallback(pushCbOptions));
}

export function createNotificationChannel(options: any, onSuccess: (extInfo: string) => void): void {
	const pushCbOptions: PushCallbackOptions = {
	    apiName: 'createNotificationChannel',
	    success: (res?: any) => {
	        let ret: string = res as string;
	        onSuccess(ret);
	    },
	    fail: (errCode: number, errMsg: string) => {
	        // 空实现
	    },
	};
	Push.callExperimentalAPI('createNotificationChannel', JSON.stringify(options), new PushCallback(pushCbOptions));
}

export function getNotificationExtInfo(onSuccess: (extInfo: string) => void): void {
    const pushCbOptions: PushCallbackOptions = {
        apiName: 'getNotificationExtInfo',
        success: (res?: any) => {
            let ret: string = res as string;
            onSuccess(ret);
        },
        fail: (errCode: number, errMsg: string) => {
            // 空实现
        },
    };
    Push.callExperimentalAPI('getNotificationExtInfo', null, new PushCallback(pushCbOptions));
}

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 {
	if(listenerMap.size === 0) {
		Push.addPushListener(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 {
	listenerMap.delete(eventName);
	if(listenerMap.size === 0) {
		Push.removePushListener(pushListener);
	}
}
