
/***
 *
 * js媒体查询
 * @param opt
 * @return {{}}
 * @example:
 createMediaList({
        480(ctx){
            console.log('is 480',ctx)
        },
        880(ctx){
            console.log('is 880',ctx)
        },
        1220(ctx){
            console.log('is 1220',ctx)
        },
        1440(ctx){
            console.log('is 1440',ctx)
        },
    })
 *
 */

    export function createMediaList(opt) {
        for (let optKey in opt) {
            let mediaCtx = window !== undefined ? window.matchMedia(`(max-width: ${optKey}px)`) : global.matchMedia(`(max-width: ${optKey}px)`)
            if (mediaCtx ?.matches) {
                opt[optKey](mediaCtx)
            }
            mediaCtx.addListener(opt[optKey])
        }
    }
    
    
    /**
     *
     * 对象转换成css样式变量
     * @param obj
     * @param prefix
     * @return {{}}
     */
    export function conversionStyleVal(obj, prefix) {
        let res = {}
        for (let key in obj) {
            if (obj[key] instanceof Object) {
                !prefix ? res[key] = conversionStyleVal(obj[key], key) :
                    Object.assign(res, conversionStyleVal(obj[key], key))
            } else {
                prefix ? res['--' + prefix + key] = obj[key] :
                    res['--' + key] = obj[key]
            }
        }
        return res
    }
    
    
    /**
     * 滑动到指定位置触发动画
     * 需要放到onMounted使用
     * @param {*} tagDom (需要触发的class盒子，可读取子级，一般填最外层盒子) 
     * author: hyw
     * 
     * 用法：
     * <div data-animation="animate__animated animate__fadeInLeft" class="box op0">
     *  htmlAddAnimations('box') 
     * 
     * 参数说明：
     * data-animation: 填写需要添加的动画效果class名 （https://animate.style/）（https://blog.csdn.net/a1056244734/article/details/113884374）
     * op0：除 /可视区域/ 外在class加上此class名
     */
    export function htmlAddAnimations(opt) {
        let oTagDomList = opt?.tagDom ? [...document.getElementsByClassName(opt.tagDom)[0].querySelectorAll('*')] : [...document.body.querySelectorAll('*')],
            domAnimationInfoPool = []
        oTagDomList.map((domItem, idx) => {
            let animationName = domItem.getAttribute('data-animation')
            if (animationName) {
                domAnimationInfoPool.push({
                    dom: domItem,
                    animationName
                })
            }
        })

        let windowScrollEvent = function (e) {
            for (let i = domAnimationInfoPool.length - 1; i >= 0; i--) {
                let infoItem = domAnimationInfoPool[i]
                if (infoItem.dom.getBoundingClientRect().top +
                    infoItem.dom.getBoundingClientRect().height <
                    window.innerHeight * (opt?.preload || 1.5)) {
                    infoItem.dom.classList.remove('op0')
                    infoItem.animationName.split(' ').map(item => {
                        if (item) {
                            infoItem.dom.classList.add(item)
                        }
                    })
                }
            }
        }
        window.addEventListener('scroll', windowScrollEvent, false)
        windowScrollEvent()
    }
    
    
    /**
     *
     * @param opt
     * opt:{
     *     触发的分辨率：要减少的字体
     * }
     * 需要放到onMounted使用
     * @example：
     * 使用前要在对应的容器加上类名：font-size-box
     * fontSizeReactive({
     *     880:1,
     *     480:2
     * })
     * 这里要注意的是，减少的字体是会叠加减少的，例如：
     * 我初始字体是15px，我的配置项为
     * {
     *     880：1，
     *     480：2
     * }，一般来说按照这个配置项的话，我字体在屏幕小于880px的时候会变成14px，在小于480的时候会变成13px
     * 但实际的话是在小于880的时候会变成14px，小于480的时候会变成12px，也就是会把880也算上
     */
    export function fontSizeReactive(opt = {
        880: 1,
        480: 1,
    }) {
        let oBox = document.getElementsByClassName('font-size-box')[0]
        let tag = oBox ? [...oBox.querySelectorAll('*')] : [...document.querySelectorAll('*')]
        tag.map(item => {
            let fontSize = getComputedStyle(item, null)['fontSize'].replace('px', '')
            item.style.setProperty('font-size', fontSize + 'px')
        })


        let fnTpl = ''
        for (let key in opt) {
            fnTpl += `
              ${key}(ctx) {
                if (ctx.matches) {
                  tag.map(item => {
                    item.style.fontSize = item.style.fontSize.replace('px', '') - ${opt[key]} + 'px'

                  })
                } else {
                  tag.map(item => {
                    item.style.fontSize = Number(item.style.fontSize.replace('px', '')) + ${opt[key]} + 'px'

                  })
                }
              },`
        }
        (new Function('fn,tag', `
              fn({
              ${fnTpl}
            })
            `))(function (opt) {
                for (let optKey in opt) {
                    let mediaCtx = window !== undefined ? window.matchMedia(`(max-width: ${optKey}px)`) : global.matchMedia(`(max-width: ${optKey}px)`)
                    if (mediaCtx ?.matches) {
                        opt[optKey](mediaCtx)
                    }
                    mediaCtx.addListener(opt[optKey])
                }
        }, tag)
    }