import {createApp} from "vue/dist/vue.esm-bundler.js";
import {getTokenHeader} from '~src/api/request/header';
import {toParse, isArray} from "js-fast-way"

//自定义组件或二次封装的组件
import HcTableFormUpload from "~com/plugins/table-form/hc-form-upload.vue"
import HcFormSelectSearch from "~com/plugins/table-form/hc-form-select-search.vue"
import HcFormCheckboxGroup from "~com/plugins/table-form/hc-form-checkbox-group.vue"
import ElTimePicker from "~com/plugins/table-form/hc-time-picker.vue"
import ElDatePicker from "~com/plugins/table-form/hc-date-picker-1.vue"
import ElRadioGroup from "~com/plugins/table-form/hc-form-radio-group.vue"

//修改过的组件
import {ElSelect, ElOption} from 'z-element-plus'

import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'

const components = {
    ElSelect, ElOption, ElDatePicker, ElTimePicker, HcTableFormUpload, ElRadioGroup,
    HcFormSelectSearch, HcFormCheckboxGroup
}

//表单渲染
export default class HTableForm {

    static tableFormApp = null
    static tableFormVM = null

    static createForm({template, tableForm, keys, appId, pid, onRight, onBlur, onLeftClick, onFormDataChange})
    {
        const _this = this;
        const app = createApp({
            data() {
                return {
                    getTokenHeader: getTokenHeader(),
                    formData: tableForm,
                }
            },
            //html标签数据
            template,
            //自定义组件，需要把饿了么的组件，或者自定义组件手动传递进来绑定，否则渲染时，自定义组件不会生效
            components,
            //监听数据，伪双向绑定（v-model）
            watch: {
                formData: {
                    handler(obj) {
                        tableForm = obj
                        this.formDataChange(obj)
                    },
                    deep: true
                },
            },
            methods: {
                //表单数据改变
                formDataChange(obj) {
                    if (onFormDataChange) {
                        onFormDataChange(obj)
                    }
                },
                //改变表单数据
                setFormData(obj) {
                    this.formData = obj
                },
                //鼠标右键菜单
                contextmenuClick(a, b, c, d, e, f, event) {
                    event.preventDefault();
                },
                //鼠标右键事件
                RightClick(a, b, c, d, e, f, event) {
                    setTimeout(() => {
                        const KeyName = event?.target?.getAttribute('keyname') || ''
                        if (onRight) {
                            event.preventDefault();
                            onRight(event, KeyName)
                        }
                    }, 100)
                },
                //焦点事件
                getInformation() {
                },
                //日期选择事件
                datePickerChange(val, key) {
                    this.formData[key] = val
                },
                //上传完成
                formUploadSuccess({src, key}) {
                    this.formData[key] = src
                },
                //删除上传的文件
                delTableFormFile(key) {
                    this.formData[key] = ''
                },
                //失去焦点事件
                getRegularExpression(event, reg, msg, a, b, leng) {
                    const KeyName = event?.target?.getAttribute('keyname') || ''
                    if (onBlur) {
                        onBlur(event, KeyName, reg, this.formData[KeyName], msg, leng)
                    }
                },
                //远程搜索处理
                formRemoteChange(data) {
                    Object.keys(data).forEach(key => {
                        this.formData[key] = data[key]
                    })
                },
                //多选框处理
                checkboxGroupChange({key, val}) {
                    this.formData[key] = val
                },
                //键盘事件 上键
                keyupShiftUp(event) {
                    _this.setKeyupData(event, 'up', keys, pid)
                },
                //键盘事件 下键
                keyupShiftDown(event) {
                    _this.setKeyupData(event, 'down', keys, pid)
                },
                //键盘事件 左键
                keyupShiftLeft(event) {
                    _this.setKeyupData(event, 'left', keys, pid)
                },
                //键盘事件 右键
                keyupShiftRight(event) {
                    _this.setKeyupData(event, 'right', keys, pid)
                },
                //日期时间框键盘事件
                dateKeydown({type, name}) {
                    _this.setKeyupData(name, type, keys, pid)
                },
                //输入左键点击事件
                inputLeftClick(event, key) {
                    setTimeout(() => {
                        if (onLeftClick) {
                            onLeftClick(key)
                        }
                    }, 100)
                },
            }
        })
        // 饿了么UI框架
        app.use(ElementPlus, {
            locale: zhCn,
        })
        const vm = app.mount(appId)
        this.tableFormApp = app
        this.tableFormVM = vm
        return {app, vm}
    }

    //处理日期范围数据
    static setPickerKey(data)
    {
        const pickerKey = data['pickerKey'] || ''
        if (pickerKey) {
            const pickerKeys = pickerKey.split(',')
            for (let i = 0; i < pickerKeys.length; i++) {
                const val = data[pickerKeys[i]] || ''
                if (val) {
                    const dataVal = val.replace(/'/g, '"');
                    data[pickerKeys[i]] = toParse(dataVal) || []
                } else {
                    data[pickerKeys[i]] = []
                }
            }
        }
        return data
    }

    //处理日期时间框的切换事件
    static setByClassKeyup(keys, pid = '')
    {
        try {
            let poppers = document.getElementsByClassName('hc-table-form-date-picker')
            for (let i = 0; i < poppers.length; i++) {
                let item = poppers[i], key = '';
                const ids = item.getAttribute('class').split('-form-id-')
                if (ids.length >= 1) {
                    key = ids[1]
                }
                if (ids) {
                    let panels = item.getElementsByClassName('el-picker-panel__content')
                    this.setElementsEvent(panels, key, keys, pid)
                }
            }
        } catch (e) {
            console.log(e)
        }
    }

    //设置事件
    static setElementsEvent(elements, key, keys, pid = '')
    {
        if (elements.length > 0) {
            const _this = this;
            elements[0].addEventListener("keydown", e => {
                e.stopPropagation()
                if (e.key === 'ArrowUp') {
                    _this.setKeyupData({target: {id: key}}, 'up', keys, pid)
                } else if (e.key === 'ArrowDown') {
                    _this.setKeyupData({target: {id: key}}, 'down', keys, pid)
                } else if (e.key === 'ArrowLeft') {
                    _this.setKeyupData({target: {id: key}}, 'left', keys, pid)
                } else if (e.key === 'ArrowRight') {
                    _this.setKeyupData({target: {id: key}}, 'right', keys, pid)
                }
            }, {
                capture: true
            });
        }
    }

    //计算上下左右快捷键的
    static setKeyupData({target}, type, keys, pid = '')
    {
        const key = target.id
        //处理快捷键数据和事件
        if (key && type && isArray(keys)) {
            //计算当前的位置
            let left = -1, top = -1;
            for (let i = 0; i < keys.length; i++) {
                if (isArray(keys[i])) {
                    const index = keys[i].findIndex(id => id === key)
                    if (index !== -1) {
                        left = index
                        top = i
                        break;
                    }
                }
            }
            if (type === 'up') {
                //向上移动
                if (top > 0) {
                    let keyId = '';
                    const tops = keys[top - 1]
                    const keyLength = tops.length - 1;
                    if (keyLength < left) {
                        keyId = tops[keyLength]
                    } else {
                        keyId = tops[left]
                    }
                    this.setElementFocus(keyId, pid)
                }
            } else if (type === 'down') {
                //向下移动
                const tops = keys.length - 1;
                if (tops > top) {
                    let keyId = '';
                    const tops = keys[top + 1]
                    const keyLength = tops.length - 1;
                    if (keyLength < left) {
                        keyId = tops[keyLength]
                    } else {
                        keyId = tops[left]
                    }
                    this.setElementFocus(keyId, pid)
                }
            } else if (type === 'left') {
                //向左移动
                if (left > 0) {
                    const keyId = keys[top][left - 1]
                    this.setElementFocus(keyId, pid)
                }
            } else if (type === 'right') {
                //向右移动
                const lefts = keys[top]
                const leftLength = lefts.length - 1;
                if (leftLength > left) {
                    const keyId = lefts[left + 1]
                    this.setElementFocus(keyId, pid)
                }
            }
        }
    }

    //设置元素焦点
    static setElementFocus(key, pid)
    {
        if (key) {
            try {
                this.getQuerySelector(key, pid)?.focus();
            } catch {
            }
        }
    }

    //获取表单元素
    static getQuerySelector(key, pid = '')
    {
        let dom;
        if (pid) {
            dom = document.querySelector('#' + pid + ' #' + (key + ''))
        } else {
            dom = document.getElementById(key + '')
        }
        return dom
    }

    //设置表单样式
    static setFormStyle(key, name = 'hc-red-border', pid = '', add = false)
    {
        const dom = this.getQuerySelector(key, pid)
        const parent = dom?.parentElement ?? ''
        if (dom.tagName === 'INPUT') {
            const parentElement = parent?.parentElement ?? ''
            this.setFormClass(parentElement, name, add)
        } else if (dom.tagName === 'TEXTAREA') {
            this.setFormClass(dom, name, add)
        }
    }

    static setFormClass(dom, name = 'hc-red-border', add = false)
    {
        const classStr = dom.getAttribute('class')
        const classArr = classStr.split(' ')
        const index = classArr.indexOf(name)
        if (index === -1 && add) {
            classArr.push(name)
        } else if (index !== -1 && add === false) {
            classArr.splice(index, 1)
        }
        dom.setAttribute('class', classArr.join(' '))
    }

    //设置选中样式
    static setCheckKeyStyle(key, pid = '', remove = false)
    {
        if (remove) {
            this.setFormStyle(key, 'hc-green-border', pid)
        } else {
            this.setFormStyle(key, 'hc-green-border', pid, true)
        }
    }

    //设置全局按键监听
    static setOnEventKey({onCtrlDown, onCtrlDownC, onCtrlDownV, onCtrlUp})
    {
        //全局按键按下监听
        document.onkeydown = (event) => {
            if(onCtrlDown || onCtrlDownC || onCtrlDownV) {
                const {key, ctrlKey, metaKey} = event
                const isCtrl = window.isMac ? metaKey : window.isWin ? ctrlKey : false
                //window.$HcLog('全局按键', 'isCtrl', isCtrl)
                //按下ctrl键 或 control 键
                if (onCtrlDown && isCtrl && key === window?.isCtrl) {
                    onCtrlDown(event)
                }
                //按下复制快捷键
                if (onCtrlDownC && isCtrl && key === 'c') {
                    onCtrlDownC(event)
                }
                //按下粘贴快捷键
                if (onCtrlDownV && isCtrl && key === 'v') {
                    onCtrlDownV(event)
                }
            }
        }
        //全局键盘放开监听
        document.onkeyup = (event) => {
            if(onCtrlUp) {
                const {key, ctrlKey, metaKey} = event
                const isCtrl = window.isMac ? metaKey : window.isWin ? ctrlKey : false
                if (!isCtrl && key === window?.isCtrl) {
                    onCtrlUp(event)
                }
            }
        }
    }

    //卸载全局按键监听
    static unmountEventKey() {
        document.onkeydown = null
        document.onkeyup = null
    }

    //卸载实例
    static unmountFormApp() {
        if (this.tableFormApp) {
            this.tableFormApp?.unmount()
            this.tableFormApp = null
        }
    }

}
