import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ScrollView, View } from "@tarojs/components";
import classNames from "classnames";
import { getWindowInfo } from "../../utils/taro/get-system-info";
import { initPositinoCache, updateItemSize } from "./utils";
import { ComponentDefaults } from "../../utils/typings";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
    list: [],
    itemHeight: 66,
    margin: 10,
    itemEqual: true,
    overscan: 2
});
export var VirtualList = function(props) {
    var _ref = _object_spread({}, defaultProps, props), list = _ref.list, itemRender = _ref.itemRender, itemHeight = _ref.itemHeight, margin = _ref.margin, itemEqual = _ref.itemEqual, overscan = _ref.overscan, key = _ref.key, onScroll = _ref.onScroll, className = _ref.className, origContainerHeight = _ref.containerHeight, rest = _object_without_properties(_ref, [
        "list",
        "itemRender",
        "itemHeight",
        "margin",
        "itemEqual",
        "overscan",
        "key",
        "onScroll",
        "className",
        "containerHeight"
    ]);
    var clientHeight = useMemo(function() {
        return getWindowInfo().windowHeight - 5 || 667;
    }, []);
    var containerHeight = useMemo(function() {
        return origContainerHeight !== null && origContainerHeight !== void 0 ? origContainerHeight : clientHeight;
    }, [
        origContainerHeight,
        clientHeight
    ]);
    var _useState = _sliced_to_array(useState(0), 2), startOffset = _useState[0], setStartOffset = _useState[1];
    var start = useRef(0);
    // 虚拟列表容器ref
    var scrollRef = useRef(null);
    // 虚拟列表显示区域ref
    var itemsRef = useRef(null);
    // 列表位置信息
    var _useState1 = _sliced_to_array(useState([
        {
            index: 0,
            left: 0,
            top: 0,
            bottom: 0,
            width: 0,
            height: 0,
            right: 0
        }
    ]), 2), positions = _useState1[0], setPositions = _useState1[1];
    var _useState2 = _sliced_to_array(useState(containerHeight || 0), 2), offSetSize = _useState2[0], setOffSetSize = _useState2[1];
    //   初始计算可视区域展示数量
    useEffect(function() {
        setPositions(function(options) {
            return _object_spread_props(_object_spread({}, options), {
                endIndex: visibleCount()
            });
        });
    }, [
        itemHeight,
        overscan,
        offSetSize
    ]);
    useEffect(function() {
        if (containerHeight) return;
        setOffSetSize(getContainerHeight());
    }, [
        containerHeight
    ]);
    useEffect(function() {
        var pos = initPositinoCache(itemHeight + margin, list.length);
        setPositions(pos);
    }, [
        itemHeight,
        list
    ]);
    // 可视区域总高度
    var getContainerHeight = function() {
        // 初始首页列表高度
        var initH = (itemHeight + margin) * list.length;
        // 未设置containerHeight高度，判断首页高度小于设备高度时，滚动容器高度为首页数据高度，减5为分页触发的偏移量
        return initH < clientHeight ? initH + overscan * (itemHeight + margin) - 5 : Math.min(containerHeight, clientHeight) // Math.min(containerHeight, clientHeight)
        ;
    };
    // 可视区域条数
    var visibleCount = function() {
        return Math.ceil(getContainerHeight() / (itemHeight + margin)) + overscan;
    };
    var end = function() {
        return start.current + visibleCount();
    };
    var listHeight = function() {
        return list.length * (itemHeight + margin);
    };
    var visibleData = function() {
        return list.slice(start.current, Math.min(end(), list.length));
    };
    var updateTotalSize = useCallback(function() {
        if (!itemsRef.current) return;
        var items = itemsRef.current.children;
        if (!items.length) return;
        // 更新缓存
        updateItemSize(positions, items, 'height', margin);
    }, [
        positions
    ]);
    // 滚动监听
    var listScroll = function(e) {
        var scrollTop = e.target.scrollTop;
        if (scrollTop <= 0) {
            e.target.scrollTop = 0;
            return setStartOffset(0);
        }
        if (!itemEqual) {
            updateTotalSize();
        }
        start.current = Math.floor(scrollTop / (itemHeight + margin));
        setStartOffset(scrollTop - scrollTop % (itemHeight + margin));
        var endIndex = end();
        // list 变动说明触底
        if (endIndex > list.length - 1) {
            onScroll && onScroll();
        }
    };
    return /*#__PURE__*/ React.createElement(View, _object_spread_props(_object_spread({
        className: classNames('nut-virtualList-box', className)
    }, rest), {
        style: {
            height: containerHeight ? "".concat(offSetSize, "px") : ''
        }
    }), /*#__PURE__*/ React.createElement(ScrollView, {
        scrollY: true,
        bounces: false,
        type: "list",
        ref: scrollRef,
        className: "nut-virtuallist",
        style: {
            height: "".concat(getContainerHeight(), "px")
        },
        onScroll: listScroll
    }, /*#__PURE__*/ React.createElement(View, {
        className: "nut-virtuallist-phantom",
        style: {
            height: "".concat(listHeight(), "px")
        }
    }), /*#__PURE__*/ React.createElement(View, {
        className: "nut-virtuallist-container",
        ref: itemsRef,
        style: {
            transform: "translate3d(0, ".concat(startOffset, "px, 0)")
        }
    }, visibleData().map(function(data, index) {
        var dataIndex = start.current + index;
        var keyVal = key && data[key] ? data[key] : dataIndex;
        return /*#__PURE__*/ React.createElement(View, {
            "data-index": "".concat(dataIndex),
            className: "nut-virtuallist-item",
            key: "".concat(keyVal),
            style: {
                height: "".concat(itemEqual ? "".concat(itemHeight, "px") : 'auto')
            }
        }, itemRender ? itemRender(data, dataIndex, index) : data);
    }))));
};
VirtualList.displayName = 'NutVirtualList';
