<script setup>
	import {
		ref,
		reactive,
		onMounted,
		onUnmounted,
		getCurrentInstance,
		defineProps,
		defineEmits,
		defineExpose,
	} from 'vue'
	// 工具库
	import util from '@/common/js/util'
	// 调色板
	import pickerColor from '@/components/public/pickerColor/pickerColor.vue'

	const {
		proxy
	} = getCurrentInstance()
	const props = defineProps({
		modelValue: String
	})
	// 
	const emit = defineEmits(['update:modelValue']);
	// 编辑器内容
	const formats = reactive({})
	// 编辑器上下文对象
	const editorCtx = ref(null)
	// 设置颜色板
	const color = reactive({
		// 前景色
		forecolor: '#ff0000',
		// 背景色
		backgroundColor: '#ff0000',
	})
	// 颜色板键值
	const colorKey = ref('forecolor')
	// 富文本编辑器宽度
	const editorWidth = ref(0)

	onMounted(() => {
		// 创建编辑器上下文对象
		onEditorReady()
		// 获取编辑器节点信息
		getEditorInfo()
	})

	// 创建编辑器上下文对象
	function onEditorReady() {
		uni.createSelectorQuery().select('#editor').context((res) => {
			editorCtx.value = res.context
		}).exec()
	}

	// 获取编辑器节点信息 用来处理图片
	function getEditorInfo() {
		const query = uni.createSelectorQuery().in(proxy);
		query.select("#editor").boundingClientRect((data) => {
			editorWidth.value = data.width
		}).exec();
	}

	// 初始化编辑器上下文对象
	function init(html) {
		editorCtx.value.setContents({
			html,
		})
	}

	// 撤销
	function undo() {
		editorCtx.value.undo()
	}

	// 重做
	function redo() {
		editorCtx.value.redo()
	}

	/**
	 * 执行editor方法
	 * @param {Object} event
	 */
	function handleEditor(event) {
		let {
			name,
			value
		} = event.target.dataset
		if (!name) return
		editorCtx.value.format(name, value)
	}

	/**
	 * 编辑器状态被变化
	 * @param {Object} e
	 */
	function onStatusChange(e) {
		Object.assign(formats, e.detail)
	}

	// 插入下划线
	function handleInsertDivider() {
		editorCtx.value.insertDivider()
	}

	// 清空编辑器内容
	function handleClear() {
		editorCtx.value.clear()
	}

	// 清除所有格式
	function handleRemoveFormat() {
		editorCtx.value.removeFormat()
	}

	// 插入图片
	function handleImage() {
		util.upload_image({
			type: 1,
			success: rs => {
				editorCtx.value.insertImage({
					src: rs.value,
					alt: '图像',
					width: Math.min(rs.width, editorWidth.value),
					extClass: 'editorImg',
				})
			}
		})
	}

	/**
	 * 选择颜色
	 * @param {Object} key 需要修改颜色的键
	 */
	function handleColor(key) {
		colorKey.value = key

		proxy.$refs.pickerColorRef.open()
	}

	/**
	 * 选择颜色
	 * @param {Object} event
	 */
	function handlePickerColorConfirm(event) {
		// console.log('event', event)
		color[colorKey.value] = event
	}

	// 设置标题
	function handleHeader() {
		const config = [{
				name: '一级标题',
				value: '1'
			},
			{
				name: '二级标题',
				value: '2'
			},
			{
				name: '三级标题',
				value: '3'
			},
			{
				name: '四级标题',
				value: '4'
			},
			{
				name: '五级标题',
				value: '5'
			},
			{
				name: '六级标题',
				value: '6'
			}
		]

		// 多选菜单
		uni.showActionSheet({
			itemList: config.map(item => item.name),
			success: (res) => {
				editorCtx.value.format('header', config[res.tapIndex].value)
			}
		})
	}

	// 富文本编辑
	function handleEditorInput(event) {
		emit('update:modelValue', event.detail.html)
	}

	defineExpose({
		init,
	})
</script>

<template>
	<view class="container ptb30">
		<view class='toolbar' @click="handleEditor">
			<!-- 加粗 -->
			<view class="item" data-name="bold">加粗</view>
			<!-- 倾斜 -->
			<!-- <view class="item" data-name="italic">倾斜</view> -->
			<!-- 下划线 -->
			<view class="item" data-name="underline">下划线</view>
			<!-- 删除线 -->
			<view class="item" data-name="strike">删除线</view>
			<!-- 左对齐 -->
			<view class="item" data-name="align" data-value="left">左对齐</view>
			<!-- 居中 -->
			<view class="item" data-name="align" data-value="center">居中</view>
			<!-- 右对齐 -->
			<view class="item" data-name="align" data-value="right">右对齐</view>
			<!-- 两端对齐 -->
			<!-- <view class="item" data-name="align" data-value="justify">两端对齐</view> -->
			<!-- 清除格式 -->
			<view class="item" @tap="handleRemoveFormat">清除所有格式</view>
			<!-- 字体颜色 -->
			<view class="item df aic" data-name="color" :data-value="color.forecolor">
				文本颜色
				<view class="colorBox ml10" :style="{backgroundColor:color.forecolor}"
					@click.stop="handleColor('forecolor')"></view>
			</view>
			<!-- 字体背景 -->
			<view class="item df aic" data-name="backgroundColor" :data-value="color.backgroundColor">
				文本背景
				<view class="colorBox ml10" :style="{backgroundColor: color.backgroundColor}"
					@click.stop="handleColor('backgroundColor')"></view>
			</view>
			<!-- 有序列表 -->
			<view class="item" data-name="list" data-value="ordered">数字列表</view>
			<!-- 点列表 -->
			<view class="item" data-name="list" data-value="bullet">点列表</view>
			<!-- 撤销 -->
			<view class="item" @tap="undo">撤销</view>
			<!-- 重做 -->
			<view class="item" @tap="redo">重做</view>
			<!-- 增加缩进 -->
			<!-- <view class="item" data-name="indent" data-value="+1">增加缩进</view> -->
			<!-- 减少缩进 -->
			<!-- <view class="item" data-name="indent" data-value="-1">减少缩进</view> -->
			<!-- 分割线 -->
			<view class="item" @tap="handleInsertDivider">分割线</view>
			<!-- 插入图片 -->
			<view class="item" @tap="handleImage">插入图片</view>
			<!-- 大标题 -->
			<view class="item" @click.stop="handleHeader">插入标题</view>
			<!-- 下标 -->
			<!-- <view class="item" data-name="script" data-value="sub">下标</view> -->
			<!-- 上标 -->
			<!-- <view class="item" data-name="script" data-value="super">上标</view> -->
			<!-- 清空 -->
			<view class="item" @tap="handleClear">清空内容</view>
		</view>

		<!-- 内容 -->
		<view class="main">
			<editor id="editor" class="ql-container" placeholder="在此输入产品详情" showImgSize showImgToolbar showImgResize
				@statuschange="onStatusChange" @ready="onEditorReady" @input="handleEditorInput">
			</editor>
		</view>
	</view>

	<!-- 调色板 -->
	<pickerColor ref="pickerColorRef" @change="handlePickerColorConfirm" />
</template>

<style lang="scss" scoped>
	// 富文本编辑区
	.container {

		.toolbar {
			box-sizing: border-box;
			display: flex;
			flex-wrap: wrap;
		}

		// 列表项
		.item {
			margin: 0 20rpx 20rpx 0;
			font-size: 26rpx;
		}

		// 内容
		.active {
			color: #FF9B27;
		}

		// 内容
		.main {
			background: #fff;
		}

		// 色块
		.colorBox {
			width: 26rpx;
			height: 26rpx;
		}
	}

	// 富文本区
	.ql-container {
		box-sizing: border-box;
		width: 100%;
		height: 50vh;
		padding: 10rpx;
		font-size: 16px;
		// background-color: #f4f4f4;
		border-radius: 10rpx;
		border: 2rpx solid #ccc;
	}
</style>