import Application from 'android.app.Application';
import QtTrackAgent from "com.quick.qt.analytics.QtTrackAgent";
import QtConfigure from "com.quick.qt.commonsdk.QtConfigure";
import ShareResultHandler from "com.quick.qt.analytics.share.ShareResultHandler"
import TextUtils from 'android.text.TextUtils';
import View from "android.view.View";
import ExposureCallback from 'com.quick.qt.analytics.exposure.QTExposureConfig.ExposureCallback';
import { ExposureConfig, ExposureData, ShareResults, LOG_TAG } from "../interface.uts"
import QTExposureConfig from 'com.quick.qt.analytics.exposure.QTExposureConfig';
import QTExposureData from 'com.quick.qt.analytics.exposure.QTExposureData';
import JSONObject from 'org.json.JSONObject';

// 设置AppKey
const APP_KEY = "应用APPKEY";
// 设置收数域名和备用收数
const TRACK_DOMAIN = "收数域名";
const TRACK_DOMAIN_2 = "备用收数域名";

// 设置应用市场
const CHANNEL = "xiaomi";

// Context 管理器
class ContextManager {
	private static instance : ContextManager | null = null
	private context : Application | null = null

	static getInstance() : ContextManager {
		if (this.instance == null) {
			this.instance = new ContextManager()
		}
		return this.instance!
	}

	setContext(context : Application) : void {
		this.context = context
	}

	getContext() : Application | null {
		return this.context
	}

	requireContext() : Application {
		if (this.context == null) {
			// 尝试从 UTSAndroid 获取
			const ctx = UTSAndroid.getAppContext()
			if (ctx instanceof Application) {
				this.context = ctx
				return ctx
			}
			throw new Error('Context 未初始化')
		}
		return this.context!
	}
}

// 全局访问的 context 变量
const getContext = () : Application | null => {
	return ContextManager.getInstance().getContext()
}

export class AppHookProxy implements UTSAndroidHookProxy {
	override onCreate(application : Application) {
		// 保存 context
		ContextManager.getInstance().setContext(application)

		console.log(LOG_TAG, "AppHookProxy.onCreate called, application:", application.packageName)

		// 当前应用是否取得用户同意隐私协议
		// 收数域名需要放到初始化之前设置
		QtConfigure.setCustomDomain(TRACK_DOMAIN, TRACK_DOMAIN_2)
		// 预初始化需要在application注入
		QtConfigure.preInit(application, APP_KEY, CHANNEL)
	}
}

export class ShareCallback implements ShareResultHandler {
	private callback : ShareResults;

	constructor(call : ShareResults) {
		this.callback = call;
	}
	override onShareResultSuccess(retObj ?: JSONObject) : void {
		if (retObj != null) {
			const ret = retObj.toString();
			const result : UTSJSONObject = JSON.parseObject(ret)!
			this.callback.onShareResultSuccess(result)
		} else {
			this.callback.onShareResultFail("参数解析失败")
		}
	}
	override onShareResultFail(exception : Throwable) : void {
		this.callback.onShareResultFail(exception.toString())
	}
}

export class ExpCallback implements ExposureCallback {
	override onExposure(view : View) {
		console.log(LOG_TAG, "控件已经曝光", view)
	}
}

/**
 * 将 JSON 字符串转换为 Map<string, V>
 * @param jsonString JSON 字符串
 * @returns Map<string, V>
 */
function jsonToMap(jsonString : string) : Map<string, any> {
	let map : Map<string, any> = new Map();
	try {
		if (!TextUtils.isEmpty(jsonString)) {
			let obj = JSON.parse<UTSJSONObject>(jsonString)!
			obj.toMap().forEach((value : any | null, key : string) => {
				if (value !== null) {
					map.set(key, value);
				}
			})
		}
	} catch (error) {
		console.error(LOG_TAG, "Invalid JSON string:", error);
		throw error; // 可选择抛出或返回空Map
	}
	return map
}

export function preInit(appKey : string, trackDomain : string, trackDomain2 : string) {
	console.log(LOG_TAG, "preInit called")

	const context = ContextManager.getInstance().requireContext()
	console.log(LOG_TAG, "context in preInit:", context.packageName)

	QtConfigure.setCustomDomain(trackDomain, trackDomain2)
	// 预初始化需要在application注入
	QtConfigure.preInit(context, appKey, CHANNEL);
}

/**
 * 执行QT SDK核心初始化流程
 */
export function init() {
	console.log(LOG_TAG, "init called")

	const context = ContextManager.getInstance().requireContext()
	console.log(LOG_TAG, "context in init:", context.packageName)

	QtConfigure.init(context, APP_KEY, CHANNEL, 1, '');
}

/**
 * 控制QT日志开关状态
 * @param enabled 启用(true)/禁用(false)日志记录
 */
export function setLogEnabled(enabled : boolean) {
	QtConfigure.setLogEnabled(enabled)
}

/**
 * 注册全局属性配置
 * @param jsonString 包含属性键值对的JSON格式字符串
 */
export function registerGlobalProperties(jsonString : string) {
	if (!TextUtils.isEmpty(jsonString)) {
		const context = ContextManager.getInstance().requireContext()
		const map : Map<string, any> = jsonToMap(jsonString);
		QtTrackAgent.registerGlobalProperties(context, map);
	}
}

/**
 * 移除指定全局属性
 * @param key 需要删除的属性唯一标识
 */
export function unregisterGlobalProperty(key : string) {
	if (!TextUtils.isEmpty(key)) {
		const context = ContextManager.getInstance().requireContext()
		QtTrackAgent.unregisterGlobalProperty(context, key);
	}
}

export function getGlobalProperty(key : string) : any {
	if (!TextUtils.isEmpty(key)) {
		const context = ContextManager.getInstance().requireContext()
		return QtTrackAgent.getGlobalProperty(context, key)
	} else {
		return ""
	}
}

export function getGlobalProperties() : string {
	const context = ContextManager.getInstance().requireContext()
	return QtTrackAgent.getGlobalProperties(context)
}

export function clearGlobalProperties() {
	const context = ContextManager.getInstance().requireContext()
	QtTrackAgent.clearGlobalProperties(context);
}

/**
 * 用户登录事件
 * @param userId 用户身份唯一标识
 * @param provider 登录服务提供商名称(可选)
 */
export function onProfileSignIn(userId : string, provider : string = '') {
	if (!TextUtils.isEmpty(userId)) {
		QtTrackAgent.onProfileSignIn(provider, userId);
	}
}

/**
 * 登出
 */
export function onProfileSignOff() {
	QtTrackAgent.onProfileSignOff();
}

/**
 * 发送自定义埋点
 * @param eventId 事件编码
 * @param params 参数，jsonstring
 */
export function onEventObject(eventId : string, params ?: string) {
	const context = ContextManager.getInstance().requireContext()

	if (params != null && !TextUtils.isEmpty(params)) {
		const map : Map<string, any> = jsonToMap(params);
		QtTrackAgent.onEventObject(context, eventId, map);
	} else {
		QtTrackAgent.onEventObject(context, eventId, null);
	}
}

/**
 * 页面埋点 进入页面，需要和离开页面配合使用
 * @param pageName 页面唯一标识名称
 */
export function onPageStart(pageName : string) {
	if (!TextUtils.isEmpty(pageName)) {
		QtTrackAgent.onPageStart(pageName)
	}
}

/**
 * 页面埋点 离开页面，需要和进入页面配合使用
 * @param pageName 页面唯一标识名称
 */
export function onPageEnd(pageName : string) {
	if (!TextUtils.isEmpty(pageName)) {
		QtTrackAgent.onPageEnd(pageName)
	}
}

export function enableExposureCollection() {
	QtTrackAgent.setAutoEventEnabled(true)
	QtTrackAgent.enableExposureCollection()
}

export function disableExposureCollection() {
	QtTrackAgent.disableExposureCollection()
}

export function setExposureConfig(config : ExposureConfig) {
	const { minDuration = 300, minVisibleRatio = 0.5, repeated = false } = config
	const qtConfig : QTExposureConfig = new QTExposureConfig.Builder()
		.setMinDuration(minDuration.toLong())
		.setMinVisibleRatio(minVisibleRatio.toFloat())
		.setRepeated(repeated)
		.build()
	QtTrackAgent.setExposureConfig(qtConfig);
}

export function addExposureView(view : View, exposureData : ExposureData) {
	const eventID = exposureData.eventId;
	const jsonString = exposureData.propertiesString;
	const qtExpData = new QTExposureData(eventID);
	let map : Map<string, any> = Map<string, any>();
	if (jsonString != null) {
		const obj = JSON.parse(jsonString) as UTSJSONObject;
		if (exposureData.item_reused_id != null && !TextUtils.isEmpty(exposureData.item_reused_id)) {
			const reuseId = exposureData.item_reused_id;
			obj['$$item_reused_id'] = reuseId
		}
		map = jsonToMap(JSON.stringify(obj));
	}
	qtExpData.setProperties(map.toMap());
	QtTrackAgent.addExposureView(view, qtExpData);
}

export function getRefShareParams() : Map<string, string> {
	const context = ContextManager.getInstance().requireContext()
	const kotlinMap = QtTrackAgent.getRefShareParams(context);
	let utsMap = new Map<string, string>()
	if (kotlinMap != null) {
		kotlinMap.forEach((key : string, value : string) => {
			utsMap.set(key, value);
		})
	}
	utsMap.putAll(kotlinMap)
	return utsMap;
}

export function requestShareParams(url : string, params ?: Map<String, String>, timeout : number = 30000, callback ?: ShareResults) {
	if (!TextUtils.isEmpty(url)) {
		const context = ContextManager.getInstance().requireContext()

		const realCall : ShareResults = {
			onShareResultSuccess: (ret : UTSJSONObject) => {
				if (callback != null)
					callback.onShareResultSuccess(ret)
			},
			onShareResultFail: (errMsg : string) => {
				if (callback != null)
					callback.onShareResultFail(errMsg)
			}
		}
		const shareCall = new ShareCallback(realCall);
		QtTrackAgent.requestShareParams(context, url, params?.toMutableMap(), timeout.toInt(), shareCall)
	}
}

/**
 * 禁用页面自动埋点
 */
export function disableActivityPageCollection() {
	QtTrackAgent.disableActivityPageCollection();
}

/**
 * 是否启用SDKMonitor
 */
export function enableSDKMonitor(enable : boolean) {
	QtConfigure.enableSDKMonitor(enable);
}

/**
 * 获取设备id
 */
export function getUMIDString() : string {
	const context = ContextManager.getInstance().requireContext()
	return QtConfigure.getUMIDString(context);
}

/**
 * @pageName 目标页面名，必须和当前页面名一致。如不一致，函数执行无效
 * @params jsonString 包含属性键值对的JSON格式字符串 并且不支持多层嵌套对象
 *
 * @warning 调用说明:必须在onHide之前调用
 */
export function setPageProperty(pageName : string, params : string) {
	if (!TextUtils.isEmpty(pageName) && !TextUtils.isEmpty(params)) {
		const context = ContextManager.getInstance().requireContext()
		const map : Map<string, any> = jsonToMap(params);
		QtTrackAgent.setPageProperty(context, pageName, map)
	}
}