import React, { useState, useEffect } from 'react';


/* 视口的大小，部分移动设备浏览器对innerWidth的兼容性不好，需要
 *document.documentElement.clientWidth或者document.body.clientWidth
 *来兼容（混杂模式下对document.documentElement.clientWidth不支持）。
 *使用方法 ： getViewPort().width;
 */
function getClientSize(scrollElement) {
    if (!['HTML', 'BODY'].includes(scrollElement.tagName)) {
        return {
            width: scrollElement.clientWidth,
            height: scrollElement.clientHeight
        };
    }
    if (document.compatMode == "BackCompat") {   // 浏览器嗅探，混杂模式
        return {
            width: document.body.clientWidth,
            height: document.body.clientHeight
        };
    } else {
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight
        };
    }
}

export default function useScrollEnd(callback, [thresholds, scrollElementSelector]) {

    useEffect(() => {
        const _thresholds = thresholds || 0;
        let scrollElement = scrollElementSelector ? document.querySelector(scrollElementSelector) : document.scrollingElement;
        const scrollHeightRecords = []; // 记录已经滚动的位置

        // 检查当前高度下是否已经执行过回调了
        const checkHasCallback = function (curScrollHeight) {
            if (!scrollHeightRecords.length) return false;
            let lastScrollHeight = scrollHeightRecords[scrollHeightRecords.length - 1];
            return Math.abs(lastScrollHeight - curScrollHeight) <= _thresholds;
        };
        let timer = null;
        const onScroll = (e) => {
            const scrollHeight = scrollElement.scrollHeight;
            if (checkHasCallback(scrollHeight)) return; // 避免重复调用
            const scrollTop = scrollElement.scrollTop || scrollElement.scrollY || 0;
            const containerHeight = getClientSize(scrollElement).height;
            const diff = scrollHeight - scrollTop - containerHeight;
            if (diff <= _thresholds) {
                if (timer) return;
                typeof callback === 'function' && callback();
                scrollHeightRecords.push(scrollHeight);
                timer = setTimeout(() => { // 节流 500ms内只执行一次
                    clearTimeout(timer);
                    timer = null;
                }, 100);

            }
        };
        if (!scrollElement) return;
        let listenerEl = scrollElementSelector ? scrollElement : document;
        listenerEl.addEventListener('scroll', onScroll);
        return function () {
            listenerEl.removeEventListener('scroll', onScroll);
        };
    }, [thresholds, scrollElementSelector]);
}