<template>
	<view class="container">
		<view class="page-body">
			<view class='wrapper'>
				<view class='toolbar' @tap="format">
					<view v-if="icons.zitijiacu" :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu" data-name="bold"></view>
					<view v-if="icons.zitixieti" :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti" data-name="italic"></view>
					<view v-if="icons.zitixiahuaxian" :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian" data-name="underline"></view>
					<view v-if="icons.zitishanchuxian" :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian" data-name="strike"></view>
					<view v-if="icons.juzhongduiqi" :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi" data-name="align" data-value="center"></view>
					<view v-if="icons.youduiqi" :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi" data-name="align" data-value="right"></view>
					<view v-if="icons.zuoyouduiqi" :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi" data-name="align" data-value="justify"></view>
					<view v-if="icons.clearedformat" class="iconfont icon-clearedformat" @tap="removeFormat"></view>
					<view v-if="icons.text_color" :class="formats.color === '#0000ff' ? 'ql-active' : ''" class="iconfont icon-text_color" data-name="color" data-value="#0000ff"></view>
					<view v-if="icons.fontbgcolor" :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''" class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view>
					<view v-if="icons.date" class="iconfont icon-date" @tap="insertDate"></view>
					<view v-if="icons.checklist" class="iconfont icon--checklist" data-name="list" data-value="check"></view>
					<view v-if="icons.youxupailie" :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie" data-name="list" data-value="ordered"></view>
					<view v-if="icons.wuxupailie" :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie" data-name="list" data-value="bullet"></view>
					<view v-if="icons.undo" class="iconfont icon-undo" @tap="undo"></view>
					<view v-if="icons.redo" class="iconfont icon-redo" @tap="redo"></view>
					<view v-if="icons.outdent" class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
					<view v-if="icons.indent" class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
					<view v-if="icons.fengexian" class="iconfont icon-fengexian" @tap="insertDivider"></view>
					<view v-if="icons.charutupian" class="iconfont icon-charutupian" @tap="insertImage"></view>
					<view v-if="icons.format_header" :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1" data-name="header" :data-value="1"></view>
					<view v-if="icons.zitixiabiao" :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao" data-name="script" data-value="sub"></view>
					<view v-if="icons.zitishangbiao" :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao" data-name="script" data-value="super"></view>
					<view v-if="icons.shanchu" class="iconfont icon-shanchu" @tap="clear"></view>
					<view v-if="icons.direction" :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl" data-name="direction" data-value="rtl"></view>
				</view>
 
				<view class="editor-wrapper">
					<editor
						id="editor"
						class="ql-container"
						placeholder="开始输入..."
						show-img-size show-img-toolbar show-img-resize
						@statuschange="onStatusChange"
						@ready="onEditorReady"
						@input="onInputChange"
						@blur="handleBlur"
					></editor>
				</view>
			</view>
		</view>
		<view v-if="max && max-0" class="word-count" :class="currentWordCount > max-0 ? 'warn' : 'normal'">
			<text>{{ currentWordCount }}</text>
			<text> / </text>
			<text>{{ max }}</text>
		</view>
	</view>
</template>
 
<script>
	/*
	@blur 富文本失焦事件 会传出一个自定义事件 携带富文本
	richValue 富文本回显数据
	*/
	export default {
		props:{
			max: {
				type: Number,
				default: 0,
				validator: value => value >= 0
			},
			richValue: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				icons: {
          zitijiacu: true,
          zitixieti: true,
          zitixiahuaxian: true,
          zitishanchuxian: false,
          juzhongduiqi: true,
          youduiqi: true,
          zuoyouduiqi: true,
          clearedformat: true,
          text_color: false,
          fontbgcolor: false,
          date: false,
          checklist: false,
          youxupailie: true,
          wuxupailie: true,
          undo: true,
          redo: true,
          outdent: true,
          indent: true,
          fengexian: true,
          charutupian: false,
          format_header: false,
          zitixiabiao: false,
          zitishangbiao: false,
          shanchu: true,
          direction: false
        },
				inputTimer: null,
				currentWordCount: 0,
				readOnly: false,
				formats: {}
			}
		},
		watch: {
			richValue: {
				handler(newVal) {
					this.setEditorContent(newVal || '')
				},
				immediate: true,
				deep: true
			}
		},
		methods: {
			isExceedValidate(alert = false, isReturn = false, title = '字数超出限制') {
				const bool = Boolean(this.max-0 && (this.currentWordCount-0 > this.max-0)) 
				if (alert && bool) uni.showToast({ title, icon: 'none', duration: 2000 })
				if (isReturn && bool) return true
			},
			handleBlur() {
				this.editorCtx.getContents({
					success: (res) => {
						this.$emit('blur', res.html === '<p><br></p>' ? '' : res.html)
					}
				})
			},
			onInputChange(e) {
				clearTimeout(this.inputTimer)
				this.inputTimer = setTimeout(() => {
					const text = e?.detail?.text ? e.detail.text : null
					const html = e?.detail?.html ? e.detail.html : null
					if (!text || !html) return
					this.currentWordCount = text.length || 0
					if (this.max-0 && (text.length >= this.max-0)) {
						uni.showToast({ icon: 'none', title: `最多可输入${this.max}个字符` })
					}
					// this.$emit('change', html)
				}, 500)
			},
			setEditorContent(content) {
				this.editorCtx.setContents({
					html: content
				});
				this.editorCtx.getContents({
					success: (res) => {
						this.currentWordCount = res?.text?.length || 0
					}
				})
			},
			onEditorReady() {
				// #ifdef APP-PLUS || MP-WEIXIN || H5
				this.createSelectorQuery().select('#editor').context((res) => {
					this.editorCtx = res.context
					
					this.setEditorContent(this.richValue)
				}).exec()
				// #endif	
			},
			undo() {
				this.editorCtx.undo()
			},
			redo() {
				this.editorCtx.redo()
			},
			format(e) {
				let {name,value} = e.target.dataset
				if (!name) return
				this.editorCtx.format(name, value)
			},
			onStatusChange(e) {
				const formats = e.detail
				this.formats = formats
			},
			insertDivider() {
				this.editorCtx.insertDivider({
					success: function() {
						console.log('insert divider success')
					}
				})
			},
			clear() {
				uni.showModal({
					title: '清空编辑器',
					content: '确定清空全部内容？',
					success: res => {
						if (res.confirm) {
							this.editorCtx.clear({
								success: function(res) {
									console.log("clear success")
								}
							})
						}
					}
				})
			},
			removeFormat() {
				this.editorCtx.removeFormat()
			},
			insertDate() {
				const date = new Date()
				const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
				this.editorCtx.insertText({
					text: formatDate
				})
			},
			insertImage() {
				// 上传图片方法 这里需要调用上传图片接口，拿到图片url并插入
				this.$utils.uploadImage(1, (res) => {
					this.editorCtx.insertImage({
						src: res,
						alt: '图像',
						success: (res) => {
							console.log('insert image success')
						}
					})
				});
			}
		}
	}
</script>
 
<style>
@import "./editor-icon.css";

.container {
  width: 100%;
  border: solid 1px #eee;
}

#editor {
  width: 100%;
  height: 300px;
  border: solid 1px #eee;
  word-break: break-all;
}

.wrapper {
  padding: 5px;
}

.iconfont {
  display: inline-block;
  padding: 8px 8px;
  /* width: 24px;
  height: 24px; */
  cursor: pointer;
  font-size: 16px;
}

.toolbar {
  box-sizing: border-box;
  border-bottom: 0;
  font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
}

.ql-container {
  box-sizing: border-box;
  padding: 10px;
  width: 100%;
  min-height: 30vh;
  height: auto;
  background: #fff;
  /* margin-top: 10px; */
  font-size: 14px;
  line-height: 1.5;
}

.ql-active {
  color: #06c;
}

.warn { color: #fe574a; }
.normal { color: #999; }

.word-count {
	margin-top: 10px;
  font-size: 12px;
	text-align: right;
	margin: 4px;
}
</style>