export const networkReg = /^(http|\/\/)/;
export const isBase64 = (path) => /^data:image\/(\w+);base64/.test(path);
export function sleep(delay) {
	return new Promise(resolve => setTimeout(resolve, delay))
}
const isDev = ['devtools'].includes(uni.getSystemInfoSync().platform)
// 缓存图片
let cache = {}
export function isNumber(value) {
	return /^-?\d+(\.\d+)?$/.test(value);
}
export function toPx(value, baseSize, isDecimal = false) {
	// 如果是数字
	if (typeof value === 'number') {
		return value
	}
	// 如果是字符串数字
	if (isNumber(value)) {
		return value * 1
	}
	// 如果有单位
	if (typeof value === 'string') {
		const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g
		const results = reg.exec(value);
		if (!value || !results) {
			return 0;
		}
		const unit = results[3];
		value = parseFloat(value);
		let res = 0;
		if (unit === 'rpx') {
			res = uni.upx2px(value);
		} else if (unit === 'px') {
			res = value * 1;
		} else if (unit === '%') {
			res = value * toPx(baseSize) / 100;
		} else if (unit === 'em') {
			res = value * toPx(baseSize || 14);
		}
		return isDecimal ? res.toFixed(2) * 1 : Math.round(res);
	}
	return 0
}

// 计算版本
export function compareVersion(v1, v2) {
	v1 = v1.split('.')
	v2 = v2.split('.')
	const len = Math.max(v1.length, v2.length)
	while (v1.length < len) {
		v1.push('0')
	}
	while (v2.length < len) {
		v2.push('0')
	}
	for (let i = 0; i < len; i++) {
		const num1 = parseInt(v1[i], 10)
		const num2 = parseInt(v2[i], 10)

		if (num1 > num2) {
			return 1
		} else if (num1 < num2) {
			return -1
		}
	}
	return 0
}
// #ifdef MP
export const prefix = () => {
	// #ifdef MP-TOUTIAO
	return tt
	// #endif
	// #ifdef MP-WEIXIN
	return wx
	// #endif
	// #ifdef MP-BAIDU
	return swan
	// #endif
	// #ifdef MP-ALIPAY
	return my
	// #endif
	// #ifdef MP-QQ
	return qq
	// #endif
	// #ifdef MP-360
	return qh
	// #endif
}
// #endif


const base64ToArrayBuffer = (data) => {
	// #ifndef MP-WEIXIN || APP-PLUS
	/**
	 * Base64Binary.decode(base64_string);  
	 * Base64Binary.decodeArrayBuffer(base64_string); 
	 */
	const Base64Binary = {
		_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
		/* will return a  Uint8Array type */
		decodeArrayBuffer(input) {
			const bytes = (input.length / 4) * 3;
			const ab = new ArrayBuffer(bytes);
			this.decode(input, ab);
			return ab;
		},
		removePaddingChars(input) {
			const lkey = this._keyStr.indexOf(input.charAt(input.length - 1));
			if (lkey == 64) {
				return input.substring(0, input.length - 1);
			}
			return input;
		},
		decode(input, arrayBuffer) {
			//get last chars to see if are valid
			input = this.removePaddingChars(input);
			input = this.removePaddingChars(input);

			const bytes = parseInt((input.length / 4) * 3, 10);

			let uarray;
			let chr1, chr2, chr3;
			let enc1, enc2, enc3, enc4;
			let i = 0;
			let j = 0;

			if (arrayBuffer)
				uarray = new Uint8Array(arrayBuffer);
			else
				uarray = new Uint8Array(bytes);

			input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

			for (i = 0; i < bytes; i += 3) {
				//get the 3 octects in 4 ascii chars
				enc1 = this._keyStr.indexOf(input.charAt(j++));
				enc2 = this._keyStr.indexOf(input.charAt(j++));
				enc3 = this._keyStr.indexOf(input.charAt(j++));
				enc4 = this._keyStr.indexOf(input.charAt(j++));

				chr1 = (enc1 << 2) | (enc2 >> 4);
				chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
				chr3 = ((enc3 & 3) << 6) | enc4;

				uarray[i] = chr1;
				if (enc3 != 64) uarray[i + 1] = chr2;
				if (enc4 != 64) uarray[i + 2] = chr3;
			}
			return uarray;
		}
	}
	return Base64Binary.decodeArrayBuffer(data)
	// #endif
	// #ifdef MP-WEIXIN || APP-PLUS
	return uni.base64ToArrayBuffer(data)
	// #endif
}


/**
 * base64转路径
 * @param {Object} base64
 */
export function base64ToPath(base64) {
	const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];

	return new Promise((resolve, reject) => {
		// #ifdef MP
		const fs = uni.getFileSystemManager()
		//自定义文件名
		if (!format) {
			reject(new Error('ERROR_BASE64SRC_PARSE'))
		}
		const time = new Date().getTime();
		let pre = prefix()
		const filePath = `${pre.env.USER_DATA_PATH}/${time}.${format}`
		//let buffer = base64ToArrayBuffer(bodyData)
		fs.writeFile({
			filePath,
			data: base64.split(',')[1], //base64.replace(/^data:\S+\/\S+;base64,/, ''),
			encoding: 'base64',
			// data: buffer,
			// encoding: 'binary',
			success() {
				resolve(filePath)
			},
			fail(err) {
				reject(err)
			}
		})
		// #endif

		// #ifdef H5
		// mime类型
		let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
		//base64 解码
		let byteString = atob(base64.split(',')[1]);
		//创建缓冲数组
		let arrayBuffer = new ArrayBuffer(byteString.length);
		//创建视图
		let intArray = new Uint8Array(arrayBuffer);
		for (let i = 0; i < byteString.length; i++) {
			intArray[i] = byteString.charCodeAt(i);
		}
		resolve(URL.createObjectURL(new Blob([intArray], {
			type: mimeString
		})))
		// #endif

		// #ifdef APP-PLUS
		const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
		bitmap.loadBase64Data(base64, () => {
			if (!format) {
				reject(new Error('ERROR_BASE64SRC_PARSE'))
			}
			const time = new Date().getTime();
			const filePath = `_doc/uniapp_temp/${time}.${format}`
			bitmap.save(filePath, {},
				() => {
					bitmap.clear()
					resolve(filePath)
				},
				(error) => {
					bitmap.clear()
					reject(error)
				})
		}, (error) => {
			bitmap.clear()
			reject(error)
		})
		// #endif
	})
}

/**
 * 路径转base64
 * @param {Object} string
 */
export function pathToBase64(path) {
	if (/^data:/.test(path)) return path
	return new Promise((resolve, reject) => {
		// #ifdef H5
		let image = new Image();
		image.setAttribute("crossOrigin", 'Anonymous');
		image.onload = function() {
			let canvas = document.createElement('canvas');
			canvas.width = this.naturalWidth;
			canvas.height = this.naturalHeight;
			canvas.getContext('2d').drawImage(image, 0, 0);
			let result = canvas.toDataURL('image/png')
			resolve(result);
			canvas.height = canvas.width = 0
		}
		image.src = path + '?v=' + Math.random()
		image.onerror = (error) => {
			reject(error);
		};
		// #endif

		// #ifdef MP
		if (uni.canIUse('getFileSystemManager')) {
			uni.getFileSystemManager().readFile({
				filePath: path,
				encoding: 'base64',
				success: (res) => {
					resolve('data:image/png;base64,' + res.data)
				},
				fail: (error) => {
					reject(error)
				}
			})
		}
		// #endif

		// #ifdef APP-PLUS
		plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => {
			entry.file((file) => {
				const fileReader = new plus.io.FileReader()
				fileReader.onload = (data) => {
					resolve(data.target.result)
				}
				fileReader.onerror = (error) => {
					reject(error)
				}
				fileReader.readAsDataURL(file)
			}, reject)
		}, reject)
		// #endif
	})
}



export function getImageInfo(path, useCORS) {
	return new Promise(async (resolve, reject) => {
		let src = path
		if (cache[path] && cache[path].errMsg) {
			resolve(cache[path])
		} else {
			try {
				// if (!isBase64 && PLATFORM == UNI_PLATFORM.PLUS && !/^\/?(static|_doc)\//.test(src)) {
				// 	src = await downloadFile(path) as string
				// } else 
				// #ifdef MP || APP-PLUS
				if (isBase64(path)) {
					src = await base64ToPath(path)
				}
				// #endif
				// #ifdef H5
				if(useCORS) {
					src = await pathToBase64(path)
				}
				// #endif
				
			} catch (error) {
				reject({
					...error,
					src
				})
			}
			uni.getImageInfo({
				src,
				success: (image) => {
					const localReg = /^\.|^\/(?=[^\/])/;
					// #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
					image.path = localReg.test(src) ?  `/${image.path}` : image.path;
					// #endif
					// #ifdef H5
					image.path = image.path.replace(/^\./, window.location.origin)
					// #endif
					
					if(this.canvas.createImage) {
						const img = this.canvas.createImage()
						img.src = image.path
						img.onload = function() {
							image.path = img
							cache[path] = image
							resolve(cache[path])
						}
						img.onerror = function(err) {
							reject({err,path})
						}
					} else if (isDev) {
						resolve(image)
					} else {
						cache[path] = image
						resolve(cache[path])
					}
				},
				fail(err) {
					console.error({err, path})
					reject({err,path})
				}
			})
		}
	})
}

export function downloadFile(url) {
	if (!url) return Promise.reject({
		err: 'no url'
	})
	return new Promise((resolve, reject) => {
		if (cache[url]) {
			return reject()
		}
		cache[url] = 1
		uni.downloadFile({
			url,
			success(res) {
				resolve(res)
			},
			fail(err) {
				reject(err)
			}
		})
	})
}

// #ifdef APP-PLUS
const getLocalFilePath = (path) => {
	if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path
		.indexOf('_downloads') === 0) {
		return path
	}
	if (path.indexOf('file://') === 0) {
		return path
	}
	if (path.indexOf('/storage/emulated/0/') === 0) {
		return path
	}
	if (path.indexOf('/') === 0) {
		const localFilePath = plus.io.convertAbsoluteFileSystem(path)
		if (localFilePath !== path) {
			return localFilePath
		} else {
			path = path.substr(1)
		}
	}
	return '_www/' + path
}
const getFile = (url) => {
	return new Promise((resolve, rejcet) => {
		plus.io.resolveLocalFileSystemURL(url, resolve, (err) => {
			resolve(false)
		})
	})
}
const createFile = ({
	fs,
	url,
	target,
	name
}) => {
	return new Promise((resolve, reject) => {
		plus.io.resolveLocalFileSystemURL(url, res1 => {
			fs.root.getDirectory(target, {
				create: true
			}, fileEntry => {
				const success = () => {
					res1.remove()
					resolve()
				}
				getFile(target + name).then(res => {
					if (res) {
						res.remove((res2) => {
							res1.moveTo(fileEntry, name, success, reject)
						})
					}
					res1.moveTo(fileEntry, name, success, reject)
				})
			})
		}, reject)
	})
}
export function useNvue(target, version, timeout) {
	return new Promise((resolve, reject) => {
		plus.io.requestFileSystem(plus.io.PRIVATE_DOC, async (fs) => {
			try {
				cache['lime-painter'] = 0
				let names = ['uni.webview.1.5.3.js', 'painter.js', 'index.html']
				let urls = ['https://gitee.com/dcloud/uni-app/raw/dev/dist/',
					'https://static-6d65bd90-8508-4d6c-abbc-a4ef5c8e49e7.bspapp.com/lime-painter/'
				]
				const oldVersion = plus.storage.getItem('lime-painter')
				const isFile = await getFile(`${target}${names[1]}`)
				if (isFile && oldVersion && compareVersion(oldVersion, version) >= 0) {
					resolve()
				} else {
					for (var i = 0; i < names.length; i++) {
						const name = names[i]
						const file = await downloadFile(urls[i >= 1 ? 1 : 0] + name)
						await createFile({
							fs,
							url: file.tempFilePath,
							target,
							name: name.includes('uni.webview') ? 'uni.webview.js' : name
						})
					}
					plus.storage.setItem('lime-painter', version)
					cache['lime-painter'] = version
					resolve()
				}
			} catch (e) {
				let index = parseInt(timeout / 20)
				while (!cache['lime-painter'] && index) {
					await sleep(20)
					index--
				}
				if (cache['lime-painter']) {
					resolve()
				} else {
					reject(e)
				}
			}
		}, reject)
	})
}
// #endif