import $api from '@/api'
import store from '@/store'
import $tools from './public.js'
import E from 'wangeditor'
import createKityformula from "./kityformula";
import myscriptMath from "./myscript-math-web";
import { app } from '@/boot-app.js'
import {
	Message,
	Modal
} from 'view-design'
import {
	MessageBox
} from 'element-ui';


export default {
	/* 初始化自定义富文本配置项 */
	initMyEditor(editor,vm,isOption) {
		// 初始化公式、视频、音频、画板功能
		this.addFormula(vm,editor)
		this.addVideoUpload(vm,editor)
		this.addAudio(vm,editor)
		this.addCanvas(vm,editor)
		editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
		editor.config.uploadImgShowBase64 = true;
		editor.config.uploadImgMaxLength = 5 // 一次最多上传 5 个图片
		editor.config.showLinkImg = false
		editor.config.showFullScreen = true
		editor.config.menus = [
			'bold',
			'italic',
			'underline',
			'indent',
			'link',
			'list',
			'quote',
			'image',
			'video',
			'audio',
			'table',
			'splitLine',
			'canvas',
			'formula'
		]
		isOption && editor.config.menus.splice(editor.config.menus.indexOf('video'),1)
	},

	/* 初始化自定义富文本简版配置项 */
	initSimpleEditor(editor) {
		editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
		editor.config.uploadImgShowBase64 = true;
		editor.config.uploadImgMaxLength = 5 // 一次最多上传 5 个图片
		editor.config.showLinkImg = false
		editor.config.showFullScreen = false
		// 配置菜单栏，删减菜单，调整顺序
		editor.config.menus = [
			'bold',
			'italic',
			'underline',
			'indent',
			'link',
			'list',
			'quote',
			'image',
			'table',
			'splitLine',
		]
	},
	
	/* 添加自定义本地视频上传功能 */
	addVideoUpload(vm, editor) {
		// 获取必要的变量，这些在下文中都会用到
		const {
			$,
			PanelMenu,
			Panel
		} = E;

		// 标题菜单的 class ，可作为 DropList 菜单的参考代码
		class myPanel extends PanelMenu {
			constructor(editor) {
				// 菜单栏中，标题菜单的 DOM 元素
				// 注意，这里的 $ 不是 jQuery ，是 E.$ （wangEditor 自带的 DOM 操作工具，类似于 jQuery）
				const $elem = $('<div class="w-e-menu" style="color:red"><i class="w-e-icon-play"></i></div>');
				super($elem, editor);
			}

			clickHandler() {
				this.createPanel();
			}

			createPanel() {
				const conf = this.createPanelConf();
				const panel = new Panel(this, conf);
				panel.create();
			}

			createPanelConf() {
				const inputIFrameId = 'input-iframe' + Math.random().toString().slice(2);
				const upFileId = 'upFileId' + Math.random().toString().slice(2);
				var tabsConf = {
					// tab 的标题
					title: editor.i18next.t("menus.panelMenus.video.上传本地视频 "),
					// 模板
					tpl: '<div class="w-e-up-img-container">\n <div id="' + inputIFrameId +
						'" class="w-e-up-btn">\n<i class="w-e-icon-upload2"></i>\n</div>\n <div style="display:none;">\n<input id="' +
						upFileId +
						'" type="file" accept="video/*"/>\n</div>\n</div>',
					// 事件绑定
					events: [
						// 插入视频
						{
							selector: "#" + inputIFrameId,
							type: "click",
							fn: () => {
								var hasVideo = editor.txt.html().includes('class="richText-video"')
								if (hasVideo) {
									Message.warning(app.$t('utils.uploadVideoLimit'))
								} else {
									var $file = $('#' + upFileId);
									var fileElem = $file.elems[0];
									if (fileElem) {
										fileElem.click();
									} else {
										// 返回 true 可关闭 panel
										return true;
									}
								}

							},
						},
						{
							// 选择视频完毕
							selector: '#' + upFileId,
							type: 'change',
							fn: async function fn() {
								var that = this
								var $file = $('#' + upFileId);
								var fileElem = $file.elems[0];
								if (!fileElem) {
									// 返回 true 可关闭 panel
									return true;
								}
								// 获取选中的 file 对象列表
								var fileList = fileElem.files;
								console.log(fileList)
								if (fileList.length) {
									if (fileList[0].type.slice(0, 5) !== 'video') {
										Message.warning(app.$t('utils.videoFormatError'))
									} else {
										// var url = window.URL.createObjectURL(`https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn/item/f469d65d-b18b-273b-f137-e8aefab6990d/002N0NH6gx07LhTzM67l010412005WHv0E010.mp4?sv=2020-04-08&st=2021-03-23T02%3A28%3A01Z&se=2120-02-28T02%3A58%3A01Z&sr=b&sp=r&sig=R%2Ff7zhkh%2FKES%2BXZbc60IGyTadarW3n86poSeaA%2BIjKk%3D`);
										// editor.selection.getSelectionStartElem().elems[0].innerHTML += '<span><span>&nbsp;</span><video src=' +
										// 	url + ' class="richText-video" width="300" preload controls="controls"></video><span>&nbsp;</span></span>'
										// editor.change.emit()
										$tools.doUploadVideo(vm, fileList[0], editor)
									}
								}
								// 返回 true 可关闭 panel
								return true;
							}
						}
					],
				};

				const conf = {
					width: 300,
					height: 0,
					tabs: [tabsConf],
				};

				return conf;
			}

			command(value) {}

			// 菜单是否需要激活
			tryChangeActive() {}
		}

		// 注册菜单
		const videoUpload = "myPanel"; // 菜单 key ，各个菜单不能重复
		editor.menus.extend("video", myPanel);

		// 将菜单加入到 editor.config.menus 中
		// 也可以通过配置 menus 调整菜单的顺序，参考【配置菜单】部分的文档
		// editor.config.menus = editor.config.menus.concat(videoUpload);
	},

	/* 添加自定义本地音频上传功能 */
	addAudio(vm, editor) {
		// 获取必要的变量，这些在下文中都会用到
		const {
			$,
			PanelMenu,
			Panel
		} = E;

		// 标题菜单的 class ，可作为 DropList 菜单的参考代码
		class myPanel extends PanelMenu {
			constructor(editor) {
				// 菜单栏中，标题菜单的 DOM 元素
				// 注意，这里的 $ 不是 jQuery ，是 E.$ （wangEditor 自带的 DOM 操作工具，类似于 jQuery）
				const $elem = $(
					'<div class="w-e-menu" style="color:red"><i class="ivu-icon ivu-icon-ios-musical-notes" style="font-size: 20px;"></i></div>'
				);
				super($elem, editor);
			}

			clickHandler() {
				this.createPanel();
			}

			createPanel() {
				const conf = this.createPanelConf();
				const panel = new Panel(this, conf);
				panel.create();
			}

			createPanelConf() {
				const inputIFrameId = 'input-iframe' + Math.random().toString().slice(2);
				const upFileId = 'upFileId' + Math.random().toString().slice(2);
				var tabsConf = {
					// tab 的标题
					title: editor.i18next.t("menus.panelMenus.video.上传本地音频 "),
					// 模板
					tpl: '<div class="w-e-up-img-container">\n <div id="' + inputIFrameId +
						'" class="w-e-up-btn">\n<i class="w-e-icon-upload2"></i>\n</div>\n <div style="display:none;">\n<input id="' +
						upFileId +
						'" type="file" multiple="multiple" accept="audio/*"/>\n</div>\n</div>',
					// 事件绑定
					events: [
						// 插入视频
						{
							selector: "#" + inputIFrameId,
							type: "click",
							fn: () => {
								var $file = $('#' + upFileId);
								var fileElem = $file.elems[0];
								if (fileElem) {
									fileElem.click();
								} else {
									// 返回 true 可关闭 panel
									return true;
								}
							},
						},
						{
							// 选择视频完毕
							selector: '#' + upFileId,
							type: 'change',
							fn: async function fn() {
								var that = this
								var $file = $('#' + upFileId);
								var fileElem = $file.elems[0];
								if (!fileElem) {
									// 返回 true 可关闭 panel
									return true;
								}
								// 获取选中的 file 对象列表
								var fileList = fileElem.files;
								if (fileList.length) {
									if (fileList[0].type.slice(0, 5) !== 'audio') {
										Message.warning(app.$t('utils.audioFormatError'))
									} else {
										$tools.doUploadAudio(vm, fileList[0], editor)
									}
								}
								// 返回 true 可关闭 panel
								return true;
							}
						}
					],
				};

				const conf = {
					width: 300,
					height: 0,
					tabs: [tabsConf],
				};

				return conf;
			}

			command(value) {}

			// 菜单是否需要激活
			tryChangeActive() {}
		}

		// 注册菜单
		const videoUpload = "audio"; // 菜单 key ，各个菜单不能重复
		editor.menus.extend("audio", myPanel);

		// 将菜单加入到 editor.config.menus 中
		// 也可以通过配置 menus 调整菜单的顺序，参考【配置菜单】部分的文档
		editor.config.menus = editor.config.menus.concat(videoUpload);
	},

	/* 添加自定义本地音频上传功能 */
	addCanvas(vm, editor) {
		// 获取必要的变量，这些在下文中都会用到
		const {
			$,
			BtnMenu,
			Panel
		} = E;

		// 标题菜单的 class ，可作为 DropList 菜单的参考代码
		class myPanel extends BtnMenu {
			constructor(editor) {
				// 菜单栏中，标题菜单的 DOM 元素
				// 注意，这里的 $ 不是 jQuery ，是 E.$ （wangEditor 自带的 DOM 操作工具，类似于 jQuery）
				const $elem = $(
					'<div class="w-e-menu" style="color:red"><i class="ivu-icon ivu-icon-md-color-palette" style="font-size: 20px;"></i></div>'
				);
				super($elem, editor);
			}

			clickHandler() {
				// Modal.props.fullscreen.default = true
				Modal.info({
					width: 1300,
					okText: '取消',
					render: (h) => {
						return h('div', {
							style: {
								display: 'flex',
								flexDirection: 'column',
								maxWidth: '1200px',
								margin: '0 auto'
							},

						}, [
							h('div', {
								style: {
									display: 'flex',
									flexDirection: 'column',
									margin: '20px',
									fontSize: '18px'
								},
								domProps: {
									innerHTML: vm.itemInfo ? vm.itemInfo.question : ''
								}
							}),
							h('BaseMyCanvas', {
								props:{
									vm:vm
								},
								on: {
									onSaveCanvas(val) {
										// let widthPercent = val.width > 800 ? '50%' : '100%'
										editor.txt.append('<img  src=' + val.base64 + ' class="richText-canvas" style="max-width:100%"></img>');
										Modal.remove()
									},
									onCloseModal() {
										Modal.remove()
									}
								}
							})
						])
					}
				})
			}

			command(value) {}

			// 菜单是否需要激活
			tryChangeActive() {}
		}

		// 注册菜单
		const canvasDraw = "canvas"; // 菜单 key ，各个菜单不能重复
		editor.menus.extend("canvas", myPanel);

		// 将菜单加入到 editor.config.menus 中
		// 也可以通过配置 menus 调整菜单的顺序，参考【配置菜单】部分的文档
		editor.config.menus = editor.config.menus.concat(canvasDraw);
	},

	/* 添加公式编辑器功能 */
	addFormula(vm,editor){
		// 获取必要的变量，这些在下文中都会用到
		const {
			$,
			PanelMenu,
			Panel
		} = E;
		
		class Kityformula extends PanelMenu {
		      // 公式输入插件
		      constructor(editors) {
		        const $elem = $(
		        	'<div class="w-e-menu" style="color:red"><i class="ivu-icon ivu-icon-logo-tumblr" style="font-size: 20px;"></i></div>'
		        );
		        super($elem, editors);
		      }
		      // 菜单点击事件
		      clickHandler() {
		        // 做任何你想做的事情
		        // 可参考【常用 API】文档，来操作编辑器
		        const conf = createKityformula(editor);
		        const panel = new Panel(this, conf);
		        panel.create();
		      }
		
		      tryChangeActive() {}
		    }
		
		// 注册菜单
		const videoUpload = "formula"; // 菜单 key ，各个菜单不能重复
		editor.menus.extend("formula", Kityformula);
		
		// 将菜单加入到 editor.config.menus 中
		// 也可以通过配置 menus 调整菜单的顺序，参考【配置菜单】部分的文档
		editor.config.menus = editor.config.menus.concat(videoUpload);
	},
	
	/* 添加学生端画板自定义功能 */
	addStuBgBtn(vm,editor){
		// 获取必要的变量，这些在下文中都会用到
		const {
			$,
			PanelMenu,
			Panel
		} = E;
		
		class Kityformula extends PanelMenu {
		      // 公式输入插件
		      constructor(editors) {
		        const $elem = $(
		        	'<div class="w-e-menu" style="color:red"><i class="ivu-icon ivu-icon-logo-tumblr" style="font-size: 20px;"></i></div>'
		        );
		        super($elem, editors);
		      }
		      // 菜单点击事件
		      clickHandler() {
				 app.$EventBus.$emit('onStuCanvas', editor)
		      }
		
		      tryChangeActive() {}
		    }
		
		// 注册菜单
		const videoUpload = "connector"; // 菜单 key ，各个菜单不能重复
		editor.menus.extend("connector", Kityformula);
		
		// 将菜单加入到 editor.config.menus 中
		// 也可以通过配置 menus 调整菜单的顺序，参考【配置菜单】部分的文档
		//editor.config.menus = editor.config.menus.concat(videoUpload);
	},
	
	/* 移除上传的音视频富文本src中的HOST */
	doRemoveMideaHost(exerciseItem) {
		console.log('removeHost',exerciseItem.question)
		let isSubjective = exerciseItem.type === 'complete' || exerciseItem.type === 'subjective' || exerciseItem.type ===
			'compose'
		let richTextObj = {
			question: exerciseItem.question,
			answer: Array.isArray(exerciseItem.answer) && exerciseItem.answer.length ? exerciseItem.answer[0] : exerciseItem.answer,
			explain: exerciseItem.explain,
		}
		isSubjective && delete richTextObj.answer
		return new Promise((resolve, reject) => {
			let promiseArr = []
			// 遍历题目的所有富文本内容
			for (let key in richTextObj) {
				promiseArr.push(new Promise((r, j) => {
					let videoSrcList = this.getRichTextSrc(richTextObj[key], 'video')
					let audioSrcList = this.getRichTextSrc(richTextObj[key], 'audio')
					let srcList = videoSrcList.concat(audioSrcList)
					if (srcList.length) {
						srcList.forEach(src => {
							let withSas = src.split('/')[src.split('/').length - 1]
							let j = withSas.lastIndexOf('?')
							richTextObj[key] = richTextObj[key].replace(src, withSas.slice(0,j));
						})
						if (key === 'answer' && Array.isArray(exerciseItem.answer) && exerciseItem.answer.length) {
							exerciseItem.answer[0] = richTextObj[key]
						} else {
							exerciseItem[key] = richTextObj[key]
						}
						r(200)
					} else {
						r(200)
					}
				}))
			}
			Promise.all(promiseArr).then(result => {
				console.log('removeHost2',exerciseItem.question)
				resolve(exerciseItem)
			})
		})
	},

	/* 转换富文本内容中的base64数据 进行压缩处理 */
	transBase64Src(exerciseItem, editorWidth) {
		var srcReg = /<img [^>]*src=['"]([^'"]+)[^>]*>/g;
		var heightReg = /<img [^>]*height=['"]([^'"]+)[^>]*>/g;
		var widthReg = /<img [^>]*width=['"]([^'"]+)[^>]*>/g;
		let richTextObj = {
			question: exerciseItem.question,
			answer: Array.isArray(exerciseItem.answer) && exerciseItem.answer.length ? exerciseItem.answer[0] : exerciseItem.answer,
			explain: exerciseItem.explain,
			option: exerciseItem.option
		}
		console.log(richTextObj)

		return new Promise((resolve, reject) => {
			let promiseArr = []
			// 遍历题目的所有富文本内容
			for (let key in richTextObj) {
				if (key === 'option') {
					if (richTextObj[key].length) {
						promiseArr.push(new Promise(async (r2, j2) => {
							let optionsPromiseArr = []
							/* 如果是试题选项里面的富文本 */
							richTextObj[key].map(i => i.value).forEach(async (item, index) => {
								optionsPromiseArr.push(new Promise(async (r, j) => {
									// 先判断是否富文本内容里面是否存在图片
									let imgList = [];
									let srcList = []
									item.replace(srcReg, async (match, capture) => {
										imgList.push(match);
										srcList.push(capture)
									});
									// 如果富文本中有图片内容 则提取所有src的值
									if (imgList.length) {
										for (let j = 0; j < imgList.length; j++) {
											let img = imgList[j]
											let src = srcList[j]
											// 如果图片有被设置过宽高即有被拉伸过之后 则根据新的宽高来生成新的base64作为图片src
											if (heightReg.test(item) && widthReg.test(item)) {
												let srcHeight = ''
												let srcWidth = ''
												item.replace(heightReg, async (match, capture) => {
													srcHeight = capture
												});
												item.replace(widthReg, async (match, capture) => {
													srcWidth = capture
												});
												let newBase64 = await this.compressImg(src, srcWidth, srcHeight)
												item = item.replace(src, newBase64)
												r(item)
											} else if (!heightReg.test(item) && widthReg.test(item)) {
												// 取到宽度的百分比
												let srcWidth = ''
												item.replace(widthReg, async (match, capture) => {
													srcWidth = parseInt(capture)
												});
												let img = new Image();
												img.src = src;
												// 如果是宽度 则需要根据编辑器的宽度来计算出 拉伸后的高度和宽度
												img.onload = async () => {
													let newWidth = editorWidth.optionWidth * srcWidth * 0.01
													let newHeight = newWidth * (img.height / img.width)
													let newBase64 = await this.compressImg(src, newWidth, newHeight)
													item = item.replace(src, newBase64)
													r(item)
												}
											} else {
												// 如果没有拉伸或者点击百分比显示 则按照原图进行压缩 宽高不变
												let newBase64 = await this.compressImg(src, 0, 0)
												item = item.replace(src, newBase64)
												r(item)
											}
										}
									} else {
										console.log('没有获取到富文本图片')
										r(item)
									}
								}))
							})
							Promise.all(optionsPromiseArr).then(res => {
								console.log('选项promiseAll', res)
								richTextObj[key].forEach((i, index) => {
									i.value = res[index]
								})
								r2(200)
								console.log('选项转换完', richTextObj[key])
							})
						}))
					} else {
						promiseArr.push(new Promise(async (r2, j2) => {
							r2(200)
						}))
					}
				} else {
					promiseArr.push(new Promise(async (r, j) => {
						// 先判断是否富文本内容里面是否存在图片
						let imgList = [];
						let srcList = []
						let item = richTextObj[key]
						if (!item) {
							r('')
							return
						} else if (Array.isArray(item) && !item.length) {
							r([])
							return
						}
						item.replace(srcReg, async (match, capture) => {
							imgList.push(match);
							srcList.push(capture)
						});
						// 如果富文本中有图片内容 则提取所有src的值
						if (imgList.length) {
							for (let j = 0; j < imgList.length; j++) {
								let img = imgList[j]
								let src = srcList[j]
								// 如果图片有被设置过宽高即有被拉伸过之后 则根据新的宽高来生成新的base64作为图片src
								if (heightReg.test(item) && widthReg.test(item)) {
									let srcHeight = ''
									let srcWidth = ''
									item.replace(heightReg, async (match, capture) => {
										srcHeight = capture
									});
									item.replace(widthReg, async (match, capture) => {
										srcWidth = capture
									});
									let newBase64 = await this.compressImg(src, srcWidth, srcHeight)
									console.log('压缩后', newBase64)
									item = item.replace(src, newBase64)
									r(item)
								} else if (!heightReg.test(item) && widthReg.test(item)) {
									// 取到宽度的百分比
									let srcWidth = ''
									item.replace(widthReg, async (match, capture) => {
										srcWidth = parseInt(capture)
									});
									let img = new Image();
									img.src = src;
									// 如果是宽度 则需要根据编辑器的宽度来计算出 拉伸后的高度和宽度
									img.onload = async () => {
										let newWidth = editorWidth.optionWidth * srcWidth * 0.01
										let newHeight = newWidth * (img.height / img.width)
										let newBase64 = await this.compressImg(src, newWidth, newHeight)
										item = item.replace(src, newBase64)
										r(item)
									}
								} else {
									// 如果没有拉伸或者点击百分比显示 则按照原图进行压缩 宽高不变
									let newBase64 = await this.compressImg(src, 0, 0)
									console.log('压缩后', newBase64)
									item = item.replace(src, newBase64)
									r(item)
								}
							}
						} else {
							console.log('没有获取到富文本图片')
							r(item)
						}
					}))
				}
			}

			Promise.all(promiseArr).then(async result => {
				console.log('处理后的富文本集合')
				console.log(result)
				exerciseItem.question = result[0]
				if (Array.isArray(exerciseItem.answer) && exerciseItem.answer.length) {
					exerciseItem.answer[0] = result[1]
				} else {
					exerciseItem.answer = result[1]
				}
				exerciseItem.explain = result[2]
				const doRemoveItem = await this.doRemoveMideaHost(exerciseItem)
				resolve(doRemoveItem)
			})
		})
	},

	/**
	 * 压缩图片
	 * @param img 被压缩的img对象
	 * @param type 压缩后转换的文件类型
	 * @param mx 触发压缩的图片最大宽度限制
	 * @param mh 触发压缩的图片最大高度限制
	 */
	compressImg(imgSrc, targetWidth, targetHeight) {
		return new Promise((resolve, reject) => {
			if(imgSrc.includes('https://')){
				resolve(imgSrc)
			}else{
				// 调用压缩接口返回
				$api.newEvaluation.imageQuant([{
					base64: imgSrc,
					width: parseInt(targetWidth),
					height: parseInt(targetHeight)
				}]).then(res => {
					console.log(res)
					resolve(res[0].base64);
				}).catch(err => {
					reject(err)
				})
			}
			
		})
	},

	/* 获取富文本的资源src数据 */
	getRichTextSrc(richText, type) {
		if (!richText) {
			return []
		}
		var videoReg = /<video.*?(?:>|\/>)/gi;
		var imgReg = /<img.*?(?:>|\/>)/gi;
		var audioReg = /<audio.*?(?:>|\/>)/gi;
		//匹配src属性
		var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i;
		var arr = richText.match(type === 'img' ? imgReg : type === 'video' ? videoReg : audioReg);
		var result = []
		if (!arr || !arr.length) {
			return []
		} else {
			for (var i = 0; i < arr.length; i++) {
				var src = arr[i].match(srcReg);
				//获取图片地址
				if (src[1]) {
					result.push(src[1])
				}
			}
			return result
		}

	}
}
