/**
 * 字体加载
 */
import {checkParamPromise} from "./util/commonFn";
import {callNative, getUid} from './util';


export default {
	/**
	 * 小程序加载字体
	 * @param {Object} options
	 * @param {Function} options.success 成功回调
	 * @param {Function} options.fail 失败回调
	 */
	loadFontFace(options = {
		global: false,
		family: '',
		source: '',
		desc: {
			style: 'normal',
			weight: 'normal',
			variant: 'normal'
		},
		scopes: ['webview'],
		success() {
		},
		fail() {
		},
		complete() {
		},
	}) {
		// api 参数类型校验
		checkParamPromise([options], [
			{
				key: 'options',
				type: ['Object']
			}
		], {name: 'loadFontFace'})
			.then(() => {
				return checkParamPromise([options.family, options.source], [
					{
						key: 'family',
						type: 'String',
						require: true
					},
					{
						key: 'source',
						type: 'String'
					}
				], {
					name: 'loadFontFace'
				});
			}, (rej) => {
				typeof options.fail === 'function' ? options.fail({
					errMsg: rej.errorMessage,
					status: 'loaded'
				}) : null;
				typeof options.complete === 'function' ? options.complete({
					errMsg: rej.errorMessage,
					status: 'loaded'
				}) : null;
			})
			.then(() => {
				if (options.global !== true) options.global = false;
				if (!options.desc) options.desc = {
					style: 'normal',
					weight: 'normal',
					variant: 'normal',
				};
				if (!options.scopes) options.scopes = ['webview'];
				let urlResult = /https.+(ttf|woff)/gi.exec(options.source);
				let hasUrl = /^url/gi.test(options.source);
				let _successFn = () => {
				};
				let _callbackFn = () => {
				};
				let webviewPromise = {
					isRun: false,
					promise: null
				}, nativePromise = {
					isRun: false,
					promise: null
				};
				if (urlResult && hasUrl) {
					const callbackId = getUid();

					const callback = (result) => {
						webviewPromise.promise = new Promise((resolve, reject) => {
							if (result.code === 0) {
								if (typeof options.success === "function") {
									resolve(result.data);
									// options.success(result.data);
								}

								if (typeof _successFn === 'function' && options.global) _successFn();
							} else {
								if (typeof options.fail === "function") {
									reject(result.data);
									// options.fail(result.data);
								}
							}
						});

						// 调用统一回调
						_callbackFn();
					};

					Service.callbacks[callbackId] = callback;

					let _desc = Object.assign({
						style: 'normal',
						weight: 'normal',
						variant: 'normal',
						stretch: 'normal',
						featureSetting: 'normal',
						unicodeRange: 'U+0-10FFFF'
					}, options.desc);

					if (!Array.isArray(options.scopes)) options.scopes = ['webview']
					if (options.scopes.indexOf('webview') === -1 && options.scopes.indexOf('native') === -1) options.scopes = ['webview']

					bl.downloadFile({
						url: urlResult[0],
						success(res) {
							if (options.scopes.indexOf('webview') > -1) {
								webviewPromise.isRun = true;
								if (!options.global) {
									Service.postMessage(JSON.stringify({
										type: 'api-render',
										event: 'loadFont',
										data: {
											family: options["family"],
											source: `url("${res.tempFilePath}")`,
											desc: _desc,
											callbackId: callbackId,
											isSendMsg: true
										}
									}), global.__biliCacheData.getCurrentPageId());
								} else {
									// 全局注入，给新加载界面使用加载字体。
									Service.executeJSOnPreLoadRender = function () {
										return `window.__biliCacheData.loadFontOnWebview({
                                        family: '${options["family"]}',
                                        source: 'url("${res.tempFilePath}")',
                                        desc: ${JSON.stringify(_desc)},
                                        isSendMsg: false
                                    })`;
									};

									// 给当前页面发送加载字体消息。
									Service.postMessage(JSON.stringify({
										type: 'api-render',
										event: 'loadFont',
										data: {
											family: options["family"],
											source: `url("${res.tempFilePath}")`,
											desc: _desc,
											callbackId: callbackId,
											isSendMsg: true,
										}
									}), global.__biliCacheData.getCurrentPageId());

									// 给所有已打开页面发送消息加载字体。
									_successFn = () => {
										let _system = bl.getSystemInfoSync().system.toLowerCase();
										// 标记开启全局字体加载了（仅给IOS9用）
										if (/ios 9/.test(_system)) global.__biliCacheData.font.openGlobal = true;
										// ios9 无法在后台加载字体文件，所以需要特殊处理，放到页面的onShow里去加载字体
										Service.postMessage(JSON.stringify({
											type: 'api-render',
											event: 'loadFont',
											data: {
												family: options["family"],
												source: `url("${res.tempFilePath}")`,
												desc: _desc,
												callbackId: callbackId,
												isSendMsg: false,
											},
											isIOS9: /ios 9/.test(_system)
										}), '-1');
									};
								}
							}

							if (options.scopes.indexOf('native') > -1) {
								nativePromise.isRun = true;
								nativePromise.promise = new Promise((resolve, reject) => {
									setTimeout(()=>{
										callNative('loadFontFace', {
											family: options["family"],
											source: res.tempFilePath,
											desc: {},
											global: options["global"],
											pageId: global.__biliCacheData.getCurrentPageId(),
											success: () => {
												resolve();
												_callbackFn();
											},
											fail: () => {
												reject();
												_callbackFn();
											}
										});
									}, 0)
								});
							}

							_callbackFn = () => {
								if (webviewPromise.isRun && webviewPromise.promise && nativePromise.isRun && nativePromise.promise) {
									Promise.all([webviewPromise, nativePromise])
										.then(res => {
											typeof options.success === 'function' ? options.success({
												errMsg: "loadFontFace:ok",
												status: 'loaded'
											}) : null;
										}, rej => {
											typeof options.fail === 'function' ? options.fail({
												errMsg: "loadFontFace:fail Font download failed.",
												status: 'loaded'
											}) : null;
										})
										.finally(() => {
											typeof options.complete === 'function' ? options.complete({
												errMsg: 'loadFontFace:complete',
												status: 'loaded'
											}) : null;
										});
								} else {
									if (webviewPromise.isRun && webviewPromise.promise) {
										webviewPromise.promise
											.then(res => {
												typeof options.success === 'function' ? options.success({
													errMsg: "loadFontFace:ok",
													status: 'loaded'
												}) : null;
											}, rej => {
												typeof options.fail === 'function' ? options.fail({
													errMsg: "loadFontFace:fail Font download failed.",
													status: 'loaded'
												}) : null;
											})
											.finally(() => {
												typeof options.complete === 'function' ? options.complete({
													errMsg: 'loadFontFace:complete',
													status: 'loaded'
												}) : null;
											});
									}

									if (nativePromise.isRun && nativePromise.promise) {
										nativePromise.promise
											.then(res => {
												typeof options.success === 'function' ? options.success({
													errMsg: "loadFontFace:ok",
													status: 'loaded'
												}) : null;
											}, rej => {
												typeof options.fail === 'function' ? options.fail({
													errMsg: "loadFontFace:fail Font download failed.",
													status: 'loaded'
												}) : null;
											})
											.finally(() => {
												typeof options.complete === 'function' ? options.complete({
													errMsg: 'loadFontFace:complete',
													status: 'loaded'
												}) : null;
											});
									}
								}
							};
						},
						fail() {
							typeof options.fail === 'function' ? options.fail({
								errMsg: "loadFontFace:fail Invalid parameter: Is not a valid link.",
								status: 'loaded'
							}) : null;
						}
					});
				} else {
					typeof options.fail === 'function' ? options.fail({
						errMsg: "loadFontFace:fail Font download failed.",
						status: 'loaded'
					}) : null;
					typeof options.complete === 'function' ? options.complete({
						errMsg: rej.errorMessage,
						status: 'loaded'
					}) : null;
				}
			}, (rej) => {
				typeof options.fail === 'function' ? options.fail({
					errMsg: rej.errorMessage,
					status: 'loaded'
				}) : null;
				typeof options.complete === 'function' ? options.complete({
					errMsg: rej.errorMessage,
					status: 'loaded'
				}) : null;
			});
	}
};
