import { defineComponent, ref, computed, onBeforeUnmount, cloneVNode } from 'vue';
import useResize from '../_util/use/useResize';
import { getFirstValidNode } from '../_util/vnode';
import getElementFromVueInstance from '../_util/getElementFromVueInstance';
import { itemProps } from './props';

/**
 * item component, we need to know their size change at any time
 */

// wrapping for item
const FVirtualListItem = defineComponent({
  name: 'FVirtualListItem',
  props: itemProps,
  setup(props, _ref) {
    let {
      attrs
    } = _ref;
    const itemRef = ref();
    let lastReportedSize = 0;
    let sizeCheckTimer = null;

    // 优化的尺寸变化检测和上报
    const dispatchSizeChange = () => {
      if (!itemRef.value) {
        return;
      }
      const shapeKey = props.horizontal ? 'offsetWidth' : 'offsetHeight';
      const currentSize = itemRef.value[shapeKey] || 0;

      // 只有当尺寸显著变化时才上报，避免频繁的微小变化
      // 阈值可以根据实际情况调整，例如设置为2px
      const sizeThreshold = 2;
      if (Math.abs(currentSize - lastReportedSize) >= sizeThreshold) {
        lastReportedSize = currentSize;
        attrs.onItemResized(props.uniqueKey, currentSize);
      }
    };

    // 防抖的尺寸检查，并确保在组件卸载时清除定时器
    const debouncedSizeCheck = () => {
      if (sizeCheckTimer) {
        clearTimeout(sizeCheckTimer);
      }
      // 稍微增加延迟，减少高频触发，例如 30ms
      sizeCheckTimer = setTimeout(dispatchSizeChange, 16);
    };

    // 使用原有的useResize，但添加防抖
    useResize(itemRef, debouncedSizeCheck, computed(() => !props.observeResize));

    // 清理定时器
    onBeforeUnmount(() => {
      if (sizeCheckTimer) {
        clearTimeout(sizeCheckTimer);
        sizeCheckTimer = null;
      }
    });
    return {
      itemRef
    };
  },
  render() {
    var _$slots$default, _$slots$default2;
    const {
      index,
      source,
      $slots
    } = this;
    const vNode = getFirstValidNode((_$slots$default = (_$slots$default2 = $slots.default) === null || _$slots$default2 === void 0 ? void 0 : _$slots$default2.call($slots, {
      index,
      source
    })) !== null && _$slots$default !== void 0 ? _$slots$default : []);
    if (!vNode) {
      return;
    }
    return cloneVNode(vNode, {
      ref: el => {
        if (el) {
          this.itemRef = getElementFromVueInstance(el);
        }
      }
    }, true);
  }
});

export { FVirtualListItem };
