import { browser, getRandomKey } from "/src/utils";

export interface IPostMessage {
	api: string;
	content?: any;
}

/**
 * 劫持postMessage
 */

const originalPostMessage = window.postMessage;

window.postMessage = (message: IPostMessage) => {
	originalPostMessage(message, "*");
};

/**
 *
 * 目前已支持API
 *
 * openWebView
 *
 */

export type CallBack = (evt?: IPostMessage) => void;

const loop = () => {};

const calls: { [key: string]: CallBack | CallBack[] } = {};

const instance: any =
	(window as any).DAYA ||
	(window as any).webkit?.messageHandlers?.DAYA ||
	(window as any).COLEXIU ||
	(window as any).webkit?.messageHandlers?.COLEXIU ||
	(window as any).ORCHESTRA ||
	(window as any).webkit?.messageHandlers?.ORCHESTRA;

if (instance) {
	window.addEventListener("message", (evt) => {
		try {
			const data = evt.data ? (typeof evt.data === "object" ? evt.data : JSON.parse(evt.data)) : {};
			const uuid = data.content?.uuid || data.uuid;
			try {
				if (data.content) {
					data.content = JSON.parse(data.content);
				}
			} catch (error) {}
			console.log("h5_接受_api:", data?.api, data.content);
			if (!uuid) {
				const keys = Object.keys(calls).filter((key) => key.indexOf(data.api) === 0);
				for (const key of keys) {
					const callback = calls[key] || loop;
					typeof callback === "function" && callback(data);
					if (Array.isArray(callback)) {
						callback.forEach((cb) => {
							typeof cb === "function" && cb(data);
						});
					}
				}
				return;
			}
			const callid = data.content?.uuid || data.uuid || data.api + data.uuid;
			const callback = calls[callid] || loop;
			typeof callback === "function" && callback(data);
		} catch (error) {
			console.error("通信消息解析错误", error);
		}
	});
}

export const postMessage = (data: IPostMessage, callback?: CallBack) => {
	if (instance) {
		const uuid = getRandomKey();
		calls[uuid] = callback || loop;
		data.content = data.content ? { ...data.content, uuid } : { uuid };
		instance.postMessage(JSON.stringify(data));
		console.log("h5_请求_api:", data);
	}
};

export const listenerMessage = (api: string, callback: CallBack) => {
	const uuid = api;
	if (!calls[uuid]) {
		calls[uuid] = [];
	}
	(calls[uuid] as CallBack[]).push(callback || loop);
};

export const removeListenerMessage = (api: string, callback: CallBack) => {
	const uuid = api;
	if (Array.isArray(calls[uuid])) {
		const indexOf = (calls[uuid] as CallBack[]).indexOf(callback);
		(calls[uuid] as CallBack[]).splice(indexOf, 1);
	}
};

export const promisefiyPostMessage = (data: IPostMessage): Promise<IPostMessage | undefined> => {
	return new Promise((resolve) => {
		postMessage(data, (res) => resolve(res));
	});
};
