<template>
	<div class="editor-container">
		<Toolbar :editor="editorRef" :mode="mode" />
		<Editor
			:mode="mode"
			:defaultConfig="state.editorConfig"
			:style="{ height }"
			v-model="state.editorVal"
			@onCreated="handleCreated"
			@onChange="handleChange"
		/>
	</div>
</template>
<script lang="ts" setup name="wngEditor">
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { onBeforeUnmount, reactive, shallowRef, watch, nextTick } from 'vue';
import { IDomEditor, Boot } from '@wangeditor/editor';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import {Cookie} from '/@/utils/storage';
// import useUserStore from '@/store/modules/user'
//  全局配置
// 定义父组件传过来的值
const props = defineProps({
	// 是否禁用
	disable: {
		type: Boolean,
		default: () => false,
	},
	// 内容框默认 placeholder
	placeholder: {
		type: String,
		default: () => '请输入内容...',
	},
	// https://www.wangeditor.com/v5/getting-started.html#mode-%E6%A8%A1%E5%BC%8F
	// 模式，可选 <default|simple>，默认 default
	mode: {
		type: String,
		default: () => 'default',
	},
	// 高度
	height: {
		type: String,
		default: () => '310px',
	},
	// 双向绑定，用于获取 editor.getHtml()
	getHtml: String,
	// 双向绑定，用于获取 editor.getText()
	getText: String,
});
// 定义子组件向父组件传值/事件
const emit = defineEmits(['update:getHtml', 'update:getText']);

const editorRef = shallowRef<RefType>();
const state = reactive<any>({
	editorConfig: {
		placeholder: props.placeholder,
		MENU_CONF: {},
	},
	editorVal: props.getHtml,
});
// 图片上传
state.editorConfig.MENU_CONF['uploadImage'] = {
	server: import.meta.env.VITE_API_UPLOAD_URL,
	// form-data fieldName ，默认值 'wangeditor-uploaded-image'
	fieldName: 'file',
	// 单个文件的最大体积限制，默认为 2M
	maxFileSize: 5 * 1024 * 1024, // 1M
	// 最多可上传几个文件，默认为 100
	maxNumberOfFiles: 10,
	// 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
	allowedFileTypes: ['image/*'],
	// 将 meta 拼接到 url 参数中，默认 false
	metaWithUrl: false,
	// 自定义增加 http  header
	headers: {
		Authorization: 'Bearer ' + Cookie.get('token'),
		userid: '',
	},
	// 跨域是否传递 cookie ，默认为 false
	withCredentials: true,
	// 超时时间，默认为 10 秒
	timeout: 5 * 1000, // 5 秒
	// 自定义插入图片
	customInsert(res: any, insertFn: any) {
		// 从 res 中找到 url alt href ，然后插图图片
		insertFn(res.data.url);
	},
};

// //上传视频
state.editorConfig.MENU_CONF['uploadVideo'] = {
	server: import.meta.env.VITE_API_UPLOAD_URL,
	// form-data fieldName ，默认值 'wangeditor-uploaded-video'
	fieldName: 'file',

	// 单个文件的最大体积限制，默认为 10M
	maxFileSize: 5 * 1024 * 1024, // 5M

	// 最多可上传几个文件，默认为 5
	maxNumberOfFiles: 3,

	// 选择文件时的类型限制，默认为 ['video/*'] 。如不想限制，则设置为 []
	allowedFileTypes: ['video/*'],

	// 将 meta 拼接到 url 参数中，默认 false
	metaWithUrl: false,

	// 自定义增加 http  header
	headers: {
		Authorization: 'Bearer ' + Cookie.get('token'),
		userid: '',
	},

	// 跨域是否传递 cookie ，默认为 false
	withCredentials: true,
	// 超时时间，默认为 30 秒
	timeout: 15 * 1000, // 15 秒
	// 自定义插入视频
	customInsert(res: any, insertFn: any) {
		// 从 res 中找到 url alt href ，然后插图图片
		insertFn(res.data.url);
	},
};
// 行高
state.editorConfig.MENU_CONF['lineHeight'] = {
	lineHeightList: ['1', '1.5', '2', '2.5'],
};
// 编辑器回调函数
const handleCreated = (editor: IDomEditor) => {
	editorRef.value = editor;
};
// 编辑器内容改变时
const handleChange = (editor: IDomEditor) => {
	emit('update:getHtml', editor.getHtml());
	emit('update:getText', editor.getText());
};
// 页面销毁时
onBeforeUnmount(() => {
	const editor = editorRef.value;
	if (editor == null) return;
	editor.destroy();
});
nextTick(() => {
	// 监听双向绑定值改变，用于回显
	watch(
		() => props.getHtml,
		(val) => {
			state.editorVal = val;
		},
		{
			deep: true,
		}
	);
	// 监听是否禁用改变
	// https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I
	watch(
		() => props.disable,
		(bool) => {
			const editor = editorRef.value;
			if (editor == null) return;

			bool ? editor.disable() : editor.enable();
		},
		{
			deep: true,
			immediate: true,
		}
	);
});
// 默认为空字符串
function withEmptyHtml<T extends IDomEditor>(editor: T): T {
	const { getHtml } = editor;
	const newEditor = editor;

	newEditor.getHtml = () => {
		if (newEditor.isEmpty()) {
			return '';
		}
		return getHtml();
	};

	return newEditor;
}
// 注册插件
Boot.registerPlugin(withEmptyHtml);
// 暴露变量
defineExpose({
	editorRef,
});
</script>
<style scoped lang="scss">
.editor-container {
	z-index: 99;
	border-radius: 5px;
	width: 100%;
	height: 100%;
}
</style>
