import React, { useEffect, useMemo, useRef } from 'react';
import { ResizeWatcher } from './ResizeWatcher';
import { Scroller, ScrollerRef } from './Scroller';
import { useUpdate } from 'ahooks';

interface VirtualChatListProps<ItemType> {
  className?: string;
  style?: React.CSSProperties;
  innerStyle?: React.CSSProperties;
  getItemKey?: (item: ItemType) => string;
  items: ItemType[];
  itemContent: (item: ItemType, index: number) => React.ReactNode;
}

const defaultContainerStyle: React.CSSProperties = {
  overflow: 'hidden',
};

const defaultInnerStyle: React.CSSProperties = {
  height: '100%',
};

const scrollerStyle: React.CSSProperties = {
  height: '100%',
};

const InternalVirtualChatList = <ItemType extends object>(
  props: VirtualChatListProps<ItemType>
) => {
  const scrollerRef = useRef<ScrollerRef>(null);
  const itemHeightCache = useMemo(() => new Map<ItemType, number>(), []);
  const forceUpdate = useUpdate();
  const style = useMemo(
    () => ({
      ...defaultContainerStyle,
      ...props.style,
    }),
    [props.style]
  );
  const innerStyle = useMemo(
    () => ({
      ...defaultInnerStyle,
      ...props.innerStyle,
    }),
    [props.innerStyle]
  );

  useEffect(() => {
    // 挂载后滚动到底部
    scrollerRef.current?.scrollToBottom();
  }, []);

  return (
    <div className="virtual-chat-list" style={style}>
      <Scroller ref={scrollerRef} style={scrollerStyle} innerStyle={innerStyle}>
        {props.items.map((item, i) => (
          <div
            key={props.getItemKey ? props.getItemKey(item) : i}
            className="virtual-chat-list__item"
            style={{ height: itemHeightCache.get(item) }}
          >
            <ResizeWatcher
              onResize={(size) => {
                itemHeightCache.set(item, size.height);
                forceUpdate();
              }}
            >
              {props.itemContent(item, i)}
            </ResizeWatcher>
          </div>
        ))}
      </Scroller>
    </div>
  );
};

type VirtualChatListInterface = typeof InternalVirtualChatList & React.FC;

export const VirtualChatList: VirtualChatListInterface = React.memo(
  InternalVirtualChatList
) as any;
VirtualChatList.displayName = 'VirtualChatList';