/** * 样式 */
(function (utils) {
    function inputHandle(e) {
        if (!utils.inCompositionEvent) {
            updateText(e)
        }
    }

    function compositionstartHandle(e) {
        // console.log("compositionstart")
        utils.inCompositionEvent = true
    }

    function compositionendHandle(e) {
        // console.log("compositionend")
        updateText(e)
        utils.inCompositionEvent = false
    }


    /**
     * 鼠标按下事件
     */
    function windowsCtrZHandle(e) {
        const event = e || window.event  //标准化事件处理
        const keyCode = event.keyCode || event.which || event.charCode
        const metaKey = event.metaKey
        // console.log("windows键盘事件 ", event, keyCombination, metaKey, keyCode)

        //撤销
        if (metaKey && keyCode === 90) {
            console.log('触发ctrl + Z 事件', e.target)
            if (utils.latestOpDoc !== undefined && utils.latestOpDoc !== null) {
                // //
                // let cNo = parseInt(utils.latestOpDoc.getAttribute("data-order"))
                // console.log("恢复", utils.latestOpDoc, cNo)
                // if (cNo > 1) {
                //     let qq = "#noteshare p[data-order='" + (cNo - 1) + "']"
                //     // console.log("qq: ", qq)
                //     utils.insertAfter(utils.latestOpDoc, document.querySelector(qq))
                // } else {
                //     //添加元素到首位
                //     yanxuelu.insertBefore(utils.latestOpDoc, utils.MyRoot.children[0])
                // }
                // utils.MyDocMap.get(cNo).setHidden(false)

                //恢复
                utils.latestOpDoc.recovery();

                // utils.MyDocMap.get(cNo).setSource(latestOpDoc.innerText)
                //
                showTestText()

                event.preventDefault()
                event.returnValue = false
            }

            utils.latestOpDoc = null
        }

    }

    /**
     * 鼠标按下事件 & 键盘组合事件
     * @param {*} e
     */
    function onkeydownHandle(e) {
        const event = e || window.event  //标准化事件处理
        // window.event 等价于 event参数
        // 有些浏览器除了通过keyCode获取输入键code,还可以通过which,charCode获取,这么写是出于浏览器兼容性考虑
        const keyCode = event.keyCode || event.which || event.charCode
        const keyCombination = event.ctrlKey
        const metaKey = event.metaKey
        // console.log("键盘事件 ", event, keyCombination, metaKey, keyCode)

        // ctrl + c 复制
        if (keyCombination && keyCode === 67) {
            // 阻止默认事件
            event.preventDefault()
            event.returnValue = false
            console.log('触发ctrl + c 事件', e.target)
        }

        //撤销
        if (metaKey && keyCode === 90) {
            // console.log('触发ctrl + Z 事件', e.target)
            if (utils.latestOpDoc !== undefined && utils.latestOpDoc !== null) {
                // console.log(utils.latestOpDoc)
                //恢复
                utils.latestOpDoc.recovery();
                //
                // console.log(MyDocMap.get(cNo))
                let cNo = parseInt(utils.latestOpDoc.getData().getAttribute("data-order"))
                utils.MyDocMap.get(cNo).setHidden(false)
                // utils.MyDocMap.get(cNo).setSource(latestOpDoc.innerText)
                //
                showTestText()

                //阻止事件
                event.preventDefault()
                event.returnValue = false
            }

            utils.latestOpDoc = null
        }

        //删除
        if (keyCode === 46 || keyCode === 8) {
            let curP = event.target
            let cNo = parseInt(curP.getAttribute("data-order"))

            //维护最近一次编辑的内容
            if (utils.latestOpDoc === undefined || utils.latestOpDoc === null || utils.latestOpDoc.getData().getAttribute("data-id") !== curP.getAttribute("data-id")) {
                utils.latestOpDoc = new utils.MyRecovery(curP.cloneNode(true), function () {
                    let cNo = parseInt(this.data.getAttribute("data-order"))
                    console.log("恢复", this.data, cNo)
                    if (cNo > 1) {
                        utils.insertAfter(this.data, document.querySelector("#noteshare p[data-order='" + (cNo - 1) + "']"))
                    } else {
                        //添加元素到首位
                        utils.MyRoot.insertBefore(this.data, utils.MyRoot.children[0])
                    }

                    // 恢复该元素展示
                    utils.MyDocMap.get(cNo).setHidden(false)
                })
            }


            //如果是第一行
            let previousSibling = curP.previousSibling
            // console.log(curP, previousSibling == undefined ,previousSibling.id == undefined)
            if (previousSibling === undefined || previousSibling.id === undefined) {
                //显示用户的输入内容
                showTestText()
                return
            }


            // console.log('触发删除', curP.innerHTML, cNo, utils.num, utils.MyDocMap.get(cNo + 1))
            let curS = window.getSelection()
            // console.log("当前内容: ", curP.innerHTML, " 当前选区 :", curS)
            //处理前面没有内容,后面还有内容需要拼接到上层的场景
            if ((curS.isCollapsed && curS.anchorOffset === 0) || curP.innerHTML === '<br>') {
                let curNodeRetainHtml = curP.innerHTML

                //异步修正顺序(第一行删除不掉)
                // if (curP.innerHTML === '<br>' ) {
                // console.log("删除当前行。选取信息: ", curS)
                //阻止事件传递
                event.preventDefault()
                event.returnValue = false

                //设置该元素隐藏
                utils.MyDocMap.get(cNo).setHidden(true)
                //删除当前元素
                curP.remove()
                //拼接
                if (curNodeRetainHtml !== '<br>') {
                    previousSibling.innerHTML = previousSibling.innerHTML + curNodeRetainHtml
                }

                //收起选区到一个点,光标落在一个可编辑元素上
                window.getSelection().setPosition(previousSibling, 1);
            }

            //显示用户的输入内容
            showTestText();
        }

        //回车事件
        if (keyCode === 13 /* && currentNode === key.lastElementChild */) {
            event.preventDefault()
            let uuid = utils.uuid()
            let curOrder = ++(utils.num)
            var newParagraph = document.createElement("p")
            newParagraph.setAttribute("contenteditable", "true")
            newParagraph.setAttribute("data-id", uuid)
            newParagraph.setAttribute("id", uuid)
            newParagraph.setAttribute("data-order", curOrder)
            newParagraph.onkeydown = onkeydownHandle
            newParagraph.focus()
            newParagraph.innerHTML = "<br>"
            utils.MyRoot.appendChild(newParagraph)
            utils.MyDocMap.set(curOrder, new utils.MyNode(uuid))

            //收起选区到一个点,光标落在一个可编辑元素上
            window.getSelection().setPosition(newParagraph, 0)
        }
    }


    /**
     *
     */
    function showTestText() {
        //显示用户的输入内容
        const obj = {};
        for ([k, v] of utils.MyDocMap.entries()) {
            if (v.getHidden() && v.getHidden() === true) {
                continue
            }
            obj[k] = v
        }

        // console.log("当前文档结构数: ",obj);

        // var userInput = document.getElementById("testInput")
        // userInput.value = JSON.stringify(obj)
    }

    /**
     * 更新文档
     * @param {*} e
     */
    function updateText(e) {
        let curP = e.target

        //是否需要变更元素类型
        utils.firstCmd(curP, onkeydownHandle)


        let cNo = parseInt(curP.getAttribute("data-order"))
        let cp = utils.MyDocMap.get(cNo)

        //内容不变则不处理
        let h5CurLen = curP.innerText.length
        let myDocNodeLen = (cp && cp.getSource()) ? cp.getSource().length : 0
        if (h5CurLen === myDocNodeLen) {
            return
        }

        cp.setSource(curP.innerText)
        // console.log("curPTx: ", curP.innerText, "MyDocMap : ", utils.MyDocMap)

        //显示用户的输入内容
        showTestText()
    }


    function surroundContentsByStyle() {
        let curS = utils.getSelection()
        let curSec = curS.getRangeAt(0)
        let styleName = this.getAttribute("data-value");
        let className = utils.parseStyleName2ClassName(styleName)
        //todo 只对 nodeType = p 执行
        // console.log("当前光标信息: ", curS, " 当前选区信息 : ", curSec)

        for (let i = 0; i < curS.rangeCount; i++) {
            let curSec = curS.getRangeAt(i)

            let curEleSize = curSec.commonAncestorContainer.childNodes.length

            let curStartP = curSec.startContainer.parentElement
            //todo 先支持 一行。
            let start = curSec.startOffset;
            let end = curSec.endOffset;
            // console.log(curStartP.cloneNode(true), styleName, start, end, " curEleSize: ", curEleSize)

            let curPEle = null;
            //第一次选择的时候将整行转换成<p><span></span></p>
            if (curEleSize === 0) {
                //没选择,则退出
                if (start === end) {
                    return
                }
                // console.log("debug1: ", curSec.commonAncestorContainer)
                //维护最近一次编辑的内容(暂时只支持恢复最近一次编辑)
                utils.latestOpDoc = new utils.MyRecovery(curStartP.cloneNode(true), function () {
                    console.log("恢复上一步样式1", this.innerHTML)
                    let curEl = document.getElementById(this.data.getAttribute("id"));
                    curEl.innerHTML = this.data.innerHTML;

                    //文本映射 直接覆盖 map 中的 childrenStyle
                    utils.syncOnePInfo(this.data);
                })

                let curHtml = ""
                for (let j = 0; j < curStartP.innerText.length; j++) {
                    // console.log(curStartP.innerText.charAt(j))
                    if (j >= start && j < end) {
                        curHtml += '<span contenteditable="true" class=' + className + '>' + curStartP.innerText.charAt(j) + '</span>';
                    } else {
                        curHtml += '<span>' + curStartP.innerText.charAt(j) + '</span>';
                    }
                }
                curStartP.innerHTML = curHtml;

                curPEle = curStartP;
            } else {
                // console.log("debug2: ", curSec.commonAncestorContainer)
                //维护最近一次编辑的内容(暂时只支持恢复最近一次编辑)
                utils.latestOpDoc = new utils.MyRecovery(curSec.commonAncestorContainer.cloneNode(true), function () {
                    console.log("恢复上一步样式1", this.data)
                    let curEl = document.getElementById(this.data.getAttribute("id"));
                    curEl.innerHTML = this.data.innerHTML;
                    //文本映射 直接覆盖 map 中的 childrenStyle
                    utils.syncOnePInfo(this.data);
                })

                let myChildren = curSec.commonAncestorContainer.children
                for (let j = 0; j < curEleSize; j++) {
                    let curEle = myChildren[j]
                    if (curS.containsNode(curEle, true)) {
                        curEle.classList.remove(className);
                        curEle.classList.add(className);
                    }
                }

                curPEle = curSec.commonAncestorContainer;
            }


            //文本映射 直接覆盖 map 中的 childrenStyle
            utils.syncOnePInfo(curPEle)
        }
    }

    window.styleCmd = {
        inputHandle, compositionstartHandle, compositionendHandle,
        onkeydownHandle, windowsCtrZHandle,
        surroundContentsByStyle,

        showTestText,
        updateText,

    }

})(utils)