<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { onBeforeUnmount, ref, shallowRef, onMounted, watch, reactive, nextTick } from 'vue';
import OSS from 'ali-oss';
import { nanoid } from 'nanoid';
import { getSsoUrl } from '/@/api/api';
import { ElMessage } from 'element-plus';
// import { ossSystem, ossIndex } from '@/utils/utils'

// defineOptions({
//   name: "BaseEditor"
// });
const emits = defineEmits(['changeMsg']);
const props = defineProps({
	ueditorData: {
		type: String,
		default: '',
	},
	disabled: {
		type: Boolean,
		default: false,
	},
	readOnly: {
		type: Boolean,
		default: false,
	},
});
const mode = 'default';
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();
const isDisable = ref(false);

// 内容 HTML
const valueHtml = ref('');

const ossData = reactive({
	accessKeyId: '',
	accessKeySecret: '',
	securityToken: '',
});
let ossClient;
//限制上传格式
const beforeImgUpload = async (file_) => {
	const accept1 = '.jpeg,.jpg,.png,,';
	const file = file_;
	const fileType = file?.name.split('.');
	const fileDate = fileType.slice(-1);
	const docsArr = accept1?.split(',');
	if (!docsArr?.includes(`.${fileDate[0]}`)) {
		ElMessage.error(`图片仅支持文件格式：${accept1}格式附件!`);
		return false;
	}
	const isLt2M = file.size / 1024 / 1024 < 500;
	if (!isLt2M) {
		ElMessage.error(`图片大小不能超过500MB!`);
		return false;
	}
	return true;
};
//限制上传格式
const beforeVideoUpload = async (file_) => {
	const accept2 = '.mp4,.avi,.mov,.wmv,';
	const file = file_;
	const fileType = file?.name.split('.');
	const fileDate = fileType.slice(-1);
	const docsArr = accept2?.split(',');
	if (!docsArr?.includes(`.${fileDate[0]}`)) {
		ElMessage.error(`视频仅支持文件格式：${accept2}格式附件!`);
		return false;
	}
	const isLt2M = file.size / 1024 / 1024 < 100;
	if (!isLt2M) {
		ElMessage.error(`视频大小不能超过100MB!`);
		return false;
	}
	return true;
};
//覆盖默认上传
const uploadFile = async (file, fileType) => {
	let type;
	if (fileType == 0) {
		type = await beforeImgUpload(file);
	} else {
		type = await beforeVideoUpload(file);
	}
	if (!type) {
		return;
	}
	let res = await upload(file);
	return res;
};
//获取oss临时上传
async function getOSSUrl() {
	await getSsoUrl({}).then((res: any) => {
		if (res.code == 200) {
			let ossData = res.data;
			ossClient = new OSS({
				endPoint: ossData.endPoint,
				region: ossData.region, // 为存储空间对应的地域域名，根据你的实际情况填写，如https://oss-cn-hangzhou.aliyuncs.com
				accessKeyId: ossData.accessKeyId, //  你的阿里云accessKeyId
				accessKeySecret: ossData.accessKeySecret, //  临时token  accessKeySecret: credentials.accessKeySecret,  //  你的阿里云accessKeySecret
				stsToken: ossData.securityToken,
				bucket: ossData.bucket, //  oss存储桶的名称
				secure: true, //http是false，https是true
			});
		}
	});
}
//oss切片上传
async function upload(file) {
	await getOSSUrl();
	const uuid = nanoid();
	const index = file.name.lastIndexOf('.');
	const suffix = file.name.substring(index + 1);
	let fileName = 'other' + '/' + uuid + '.' + suffix;
	return ossClient.multipartUpload(fileName, file, {
		progress: function (p) {},
		partSize: 20 * 1024 * 1024,
	});
}
// 模拟 ajax 异步获取内容
onMounted(() => {
	if (props.readOnly == false) {
		isDisable.value = false;
	} else {
		isDisable.value = true;
	}
});
watch(
	() => props.ueditorData,
	(newValue) => {
		if (newValue) {
			valueHtml.value = newValue;
		}
	}
);
watch(
	() => valueHtml.value,
	(newValue) => {
		if (newValue && newValue != '<p><br></p>') {
			nextTick(() => {
				emits('changeMsg', {
					html: valueHtml.value,
					text: editorRef.value.getText(),
				});
			});
		} else {
			emits('changeMsg', '');
		}
	},
	{ immediate: true }
);
watch(
	() => props.readOnly,
	(newValue) => {
		const editor = editorRef.value;
		if (newValue == false) {
			isDisable.value = false;
			editor.enable();
		} else {
			isDisable.value = true;
			editor.disable();
		}
	}
);
const toolbarConfig: any = {
	excludeKeys: 'fullScreen',
	toolbarKeys: [
		'undo',
		'redo',
		'headerSelect',
		'indent',
		'lineHeight',
		'bgColor',
		'color',
		'fontSize',
		'bold',
		'italic',
		'through',
		'bulletedList',
		'numberedList',
		'uploadImage',
		'insertImage',
		'clearStyle',
		'divider',
	],
};
const editorConfig = {
	placeholder: '请输入内容...',
	readOnly: props.readOnly,
	MENU_CONF: {
		uploadImage: {
			// 设置上传图片的服务端地址
			// server: 'http://124.223.11.95:8081/admin/common/upload2',
			// 单个文件大小限制，单位 byte
			maxFileSize: 500 * 1024 * 1024, // 2MB
			// 上传时附带的参数
			// fieldName: 'file',
			customInsert(res: any, insertFn) {
				// TS 语法
				// customInsert(res, insertFn) {                  // JS 语法
				// res 即服务端的返回结果
				if (res.code == 200) {
					// 从 res 中找到 url alt href ，然后插入图片
					insertFn(res.data.showUrl);
				}
			},
			customUpload: async (file, insertFn) => {
				let res = await uploadFile(file, 0);
				if (res.res.status == 200) {
					ElMessage({
						message: '上传成功！',
						type: 'success',
					});
				} else {
					ElMessage.error('上传失败！');
				}
				insertFn(res.res.requestUrls[0].split('?')[0]);
			},
		},
		uploadVideo: {
			// 设置上传图片的服务端地址
			// server: 'http://124.223.11.95:8081/admin/common/upload2',
			// 单个文件大小限制，单位 byte
			maxFileSize: 500 * 1024 * 1024, // 2MB
			// 上传时附带的参数
			// fieldName: 'file',
			customInsert(res: any, insertFn) {
				// TS 语法
				// customInsert(res, insertFn) {                  // JS 语法
				// res 即服务端的返回结果
				if (res.code == 200) {
					// 从 res 中找到 url alt href ，然后插入图片
					insertFn(res.data.showUrl);
				}
			},
			customUpload: async (file, insertFn) => {
				let res = await uploadFile(file, 1);
				if (res.res.status == 200) {
					ElMessage({
						message: '上传成功！',
						type: 'success',
					});
				} else {
					ElMessage.error('上传失败！');
				}
				insertFn(res.res.requestUrls[0].split('?')[0]);
			},
		},
	},
};

const handleCreated = (editor) => {
	// 记录 editor 实例，重要！
	editorRef.value = editor;
	if (props.disabled) {
		isDisable.value = true;
		editorRef.value.disable();
	}
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
	const editor = editorRef.value;
	if (editor == null) return;
	editor.destroy();
});
</script>

<template>
	<div :class="['wangeditor', { 'editor-disable': isDisable }]">
		<Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" style="border-bottom: 1px solid #ccc" />
		<Editor
			v-model="valueHtml"
			:defaultConfig="editorConfig"
			:mode="mode"
			style="height: 500px; overflow-wrap: break-word; word-break: break-all"
			@onCreated="handleCreated"
		/>
	</div>
</template>

<style lang="scss" scoped>
.editor-disable {
	:deep(.w-e-text-container) {
		color: #a8abb2;
	}
}
</style>
