import type { CSSProperties, HTMLAttributes, PropType } from 'vue';
import { computed, defineComponent, ref, watch } from 'vue';
import ResizeObserver from '../vc-resize-observer';
import classNames from '../_util/classNames';
import type { Key, VueNode } from '../_util/type';
import PropTypes from '../_util/vue-types';
import { OverflowContextProvider } from './context';
import Item from './Item';
import RawItem from './RawItem';
const RESPONSIVE = 'responsive' as const;
const INVALIDATE = 'invalidate' as const;
function defaultRenderRest(omittedItems: ItemType[]) {
  return `+ ${omittedItems.length} ...`;
}
export interface OverflowProps extends HTMLAttributes {
  prefixCls?: string;
  data?: ItemType[];
  itemKey?: Key;
  /** Used for `responsive`. It will limit render node to avoid perf issue */
  itemWidth?: number;
  renderItem?: (item: ItemType) => VueNode;
  /** @private Do not use in your production. Render raw node that need wrap Item by developer self */
  renderRawItem?: (item: ItemType, index: number) => VueNode;
  maxCount?: number | typeof RESPONSIVE | typeof INVALIDATE;
  renderRest?: VueNode | ((omittedItems: ItemType[]) => VueNode);
  /** @private Do not use in your production. Render raw node that need wrap Item by developer self */
  renderRawRest?: (omittedItems: ItemType[]) => VueNode;
  suffix?: VueNode;
  component?: any;
  itemComponent?: any;
  /** @private This API may be refactor since not well design */
  onVisibleChange?: (visibleCount: number) => void;
  /** When set to `full`, ssr will render full items by default and remove at client side */
  ssr?: 'full';
}
const Overflow = defineComponent({
  name: 'Overflow',
  inheritAttrs: false,
  props: {
    prefixCls: String,
    data: Array,
    itemKey: [String, Number, Function] as PropType Key)>,
    /** Used for `responsive`. It will limit render node to avoid perf issue */
    itemWidth: { type: Number, default: 10 },
    renderItem: Function as PropType<(item: any) => VueNode>,
    /** @private Do not use in your production. Render raw node that need wrap Item by developer self */
    renderRawItem: Function as PropType<(item: any, index: number) => VueNode>,
    maxCount: [Number, String] as PropType,
    renderRest: Function as PropType<(items: any[]) => VueNode>,
    /** @private Do not use in your production. Render raw node that need wrap Item by developer self */
    renderRawRest: Function as PropType<(items: any[]) => VueNode>,
    suffix: PropTypes.any,
    component: String,
    itemComponent: PropTypes.any,
    /** @private This API may be refactor since not well design */
    onVisibleChange: Function as PropType<(visibleCount: number) => void>,
    /** When set to `full`, ssr will render full items by default and remove at client side */
    ssr: String as PropType<'full'>,
  },
  emits: ['visibleChange'],
  setup(props, { attrs, emit }) {
    const fullySSR = computed(() => props.ssr === 'full');
    const containerWidth = ref(null);
    const mergedContainerWidth = computed(() => containerWidth.value || 0);
    const itemWidths = ref