import { App } from 'vue';
import store from '@/store/index.js';

// @ts-ignore
interface type_OBj {
	[key: string]: any
}
const screening_Brace = (el: HTMLElement) => {
	return new Promise((s, e) => {
		let sta = false, num = 1
		if (el.className.indexOf('el-slider') != -1 || el.className.indexOf('label') != -1 || el.className.indexOf('title') != -1) {
			num = 2
			sta = true
			return
		} else if (num === 1) sta = false
		s(sta)
	})
}
export default {
	install(Vue: App<Element>) {
		Vue.directive('drag', {
			mounted(el: HTMLElement, bind) {
				el.onmousedown = async function (e: any) {
					if (['INPUT', 'TEXTAREA', 'CANVAS'].includes(e.target.nodeName) || e.target.className.includes('el-slider')) {
						return;
					}
					const sta = await screening_Brace(e.target)
					if (sta) return
					let elLeft = el.offsetLeft;
					let elTop = el.offsetTop;
					let x = e.clientX;
					let y = e.clientY;
					el.style.transition='unset'
					document.onmousemove = (move: MouseEvent) => {
						let left = elLeft - (x - move.clientX);
						el.style.left = left + 'px'
						el.style.right = 'unset'
						let top = elTop - (y - move.clientY);
						el.style.top = top + 'px'
						el.style.bottom = 'unset'

						if (window.getSelection()) {
							// @ts-ignore
							window.getSelection() ? window.getSelection().removeAllRanges() : null
						}

					}
					document.onmouseup = (up: MouseEvent) => {
						store.dispatch('app/LOAD_IS_DRAG')
						document.onmousemove = null;
						document.onmouseup = null;
					}
				}
			},
			unmounted(el, bind) {
				el.onmousedown = null;
			}
		}),
		Vue.directive('wheelScale', {
			mounted(el: HTMLElement, bind) {
				const setTransformCss = (el, cssVarName) => {
					let transformCssString = el.style.transform
					let regScaleGlobal = /scale\(.*?[ )]*[)]+[ ]*/g //匹配 Scale属性 全局
					if (regScaleGlobal.test(transformCssString)) {
						transformCssString = transformCssString.replace(
							regScaleGlobal,
							` scale(var(${cssVarName})) `
						)
					} else {
						transformCssString += " " + `scale(var(${cssVarName}))`
					}
					el.style.transform = transformCssString
				}
				const setVarScale = (el, cssVarName, scale) => {
					let cssText = el.style.cssText
					let cssTextList = cssText.split(";")
					let isExist = false
					let isExistIndex = -1
					for (let index = 0; index < cssTextList.length; index++) {
						const element = cssTextList[index]
						if (element.includes(cssVarName + ":")) {
							isExist = true
							isExistIndex = index
							break
						}
					}
					if (isExist) {
						cssTextList[isExistIndex] = `--scale: ${scale}`
					} else {
						cssTextList.push(`--scale: ${scale}`)
						//   el.setAttribute("style", `--scale: ${scale}`)
					}
					cssText = cssTextList.join(";")
					el.style.cssText = cssText
				}
				const { maxScale = 5, minScale = 0.5, auto = false }: any = bind.value || {}
				let oldScale: number = 1
				const cssVarName = "--scale"
				if (el) {
					if (auto) {
						setTimeout(() => {
							if (el.parentElement) {
								const l = (el.parentElement.clientWidth - el.clientWidth) / 2
								const t = (el.parentElement.clientHeight - el.clientHeight) / 2
								if (l) {
									el.style.left = `${l}px`
								}
								if (t) {
									el.style.top = `${t}px`
								}
								const eRatio = el.clientWidth / el.clientHeight
								const eParRatio = el.parentElement.clientWidth / el.parentElement.clientHeight
								if (eRatio > eParRatio) {
									oldScale = el.parentElement.clientWidth / el.clientWidth
								} else {
									oldScale = el.parentElement.clientHeight / el.clientHeight
								}
								if (oldScale > maxScale) {
									oldScale = maxScale
								}
								if (oldScale < minScale) {
									oldScale = minScale
								}
								setVarScale(el, cssVarName, oldScale)
								setTransformCss(el, cssVarName)
							}
						}, 300)
					}
					el.onwheel = (e: any) => {
						let _scale: any = el.style.getPropertyValue(cssVarName) || 1
						if (e.wheelDelta > 0) {
							_scale = _scale * 1 + 0.1
						} else {
							_scale = _scale * 1 - 0.1
						}
						// 现在缩放范围
						if (_scale > maxScale) {
							_scale = maxScale
						} else if (_scale < minScale) {
							_scale = minScale
						}
						setVarScale(el, cssVarName, _scale)
						setTransformCss(el, cssVarName)
						// 缩放改变回调函数
						const wheelScaleChange = bind.value || null

						if (wheelScaleChange instanceof Function && _scale != oldScale) {
							oldScale = _scale
							wheelScaleChange({
								cssVarName,
								currentScale: _scale,
								maxScale,
								minScale,
							})
						}
					}
				}
			},
			unmounted(el, bind) {
				el.onwheel = null
			}
		})
	}
}
