import { unref, Ref } from 'vue'
import { isIOS } from './validate'

export type ScrollElement = Element | Window

// 获取元素 滚动出去的高度
export function getScrollTop(el: ScrollElement): number {
    const top = 'scrollTop' in el ? el.scrollTop : el.pageYOffset

    // iOS scroll bounce cause minus scrollTop
    return Math.max(top, 0)
}

// 设置元素滚动出去的距离
export function setScrollTop(el: ScrollElement, value: number) {
    if ('scrollTop' in el) {
        el.scrollTop = value
    } else {
        el.scrollTo(el.scrollX, value)
    }
}

// 获取根元素 滚动出去的高度
export function getRootScrollTop(): number {
    return (
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop ||
        0
    )
}

// 设置根元素滚动出去的距离
export function setRootScrollTop(value: number) {
    setScrollTop(window, value)
    setScrollTop(document.body, value)
}

// hack for iOS12 page scroll
// see: https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800
export function resetScroll() {
    if (isIOS) {
        setRootScrollTop(getRootScrollTop())
    }
}

// 阻止事件冒泡
export const stopPropagation = (event: Event) => event.stopPropagation()

// 阻止默认行为
export function preventDefault(event: Event, isStopPropagation?: boolean) {
    /* istanbul ignore else */
    if (typeof event.cancelable !== 'boolean' || event.cancelable) {
        event.preventDefault()
    }

    if (isStopPropagation) {
        stopPropagation(event)
    }
}

// 判断元素是否隐藏
export function isHidden(
    elementRef: HTMLElement | Ref<HTMLElement | undefined>
) {
    const el = unref(elementRef)
    if (!el) {
        return false
    }

    const style = window.getComputedStyle(el)
    const hidden = style.display === 'none'

    // offsetParent returns null in the following situations:
    // 1. The element or its parent element has the display property set to none.
    // 2. The element has the position property set to fixed
    const parentHidden = el.offsetParent === null && style.position !== 'fixed'

    return hidden || parentHidden
}
