import { computed, onMounted, ref } from 'vue'

/**
 * 获取真实DOM的高度
 * @returns [heightRef, VMRef, readyRef]
 */

export const getVMDomWH = (attr: string): any[] => {
    const origin = ref<number>(0)
    const domRef = ref<HTMLElement | null>(null)
    const ready = ref(false)
    const referWH = () => {
        origin.value = 0
        ready.value = false
        if (domRef.value) {
            const offsetWidth = domRef.value.offsetWidth
            const offsetHeight = domRef.value.offsetHeight
            setTimeout(() => {
                origin.value = attr === 'width' ? offsetWidth : offsetHeight
                setTimeout(() => (ready.value = true))
            })
        }
    }
    onMounted(referWH)

    return [origin, domRef, ready, referWH]
}

/**
 * 生成切换高度的方法
 * @returns [VMRef, fn, maxHeightRef, originHeightRef, showRef, readyRef]
 */
export const changeWHFactory = (isShow = false, attr = 'height') => {
    const [origin, domRef, ready, referWH] = getVMDomWH(attr)
    const max = ref(0)
    const show = computed({
        get: () => {
            return max.value == origin.value
        },
        set: val => {
            max.value = val ? origin.value : 0
        },
    })
    const changeShow = (val = !show.value) => {
        show.value = val
    }

    onMounted(() => {
        show.value = isShow
    })

    return [domRef, changeShow, max, origin, show, ready, referWH]
}

/**
 * 获取父级滚动
 * @param {*} node
 * @returns
 */
export const getScrollParent = (node: HTMLElement): HTMLElement | null => {
    if (node == null) {
        return null
    }
    if (node === document.documentElement) {
        return node
    }

    const cssScrollY = getComputedStyle(node).overflowY
    const cssScrollX = getComputedStyle(node).overflowX
    if (node.scrollHeight > node.clientHeight || cssScrollY === 'auto' || cssScrollY === 'scroll' || cssScrollX === 'auto' || cssScrollX === 'scroll') {
        return node
    } else {
        return getScrollParent(node.parentNode as HTMLElement)
    }
}

/**
 * 获取所有父级滚动
 * @param {*} origin
 * @param {*} target
 */
export const getScrollParents = (origin: any, target: HTMLElement) => {
    const parents: HTMLElement[] = []
    let temporary = origin
    while (temporary && temporary !== target && temporary !== document.documentElement && target.contains(temporary)) {
        const scrollParent = getScrollParent(temporary)
        if (scrollParent) {
            if (scrollParent !== origin) {
                parents.push(scrollParent)
            }
            temporary = scrollParent.parentNode
        } else {
            break
        }
    }

    return parents
}
