import { SessionType } from "@openim/wasm-client-sdk";
import { Button, Layout, Spin } from "antd";
import clsx from "clsx";
import { t } from "i18next";
import { memo, useEffect, useRef } from "react";
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";

import { SystemMessageTypes } from "@/constants/im";
import { useUserStore } from "@/store";
import emitter from "@/utils/events";
import { formatMessageTime } from "@/utils/imCommon";

import MessageItem from "./MessageItem";
import NotificationMessage from "./NotificationMessage";
import { useHistoryMessageList } from "./useHistoryMessageList";

// 两条消息间隔超过 5 分钟则显示时间分隔
const TIME_DIVIDER_GAP = 5 * 60 * 1000;

const ChatContent = () => {
  const virtuoso = useRef<VirtuosoHandle>(null);
  const selfUserID = useUserStore((state) => state.selfInfo.userID);

  const scrollToBottom = () => {
    setTimeout(() => {
      virtuoso.current?.scrollToIndex({
        index: 9999,
        align: "end",
        behavior: "auto",
      });
    });
  };

  const {
    SPLIT_COUNT,
    conversationID,
    loadState,
    moreOldLoading,
    getMoreOldMessages,
    loadError,
  } = useHistoryMessageList();

  useEffect(() => {
    emitter.on("CHAT_LIST_SCROLL_TO_BOTTOM", scrollToBottom);
    return () => {
      emitter.off("CHAT_LIST_SCROLL_TO_BOTTOM", scrollToBottom);
    };
  }, []);

  const loadMoreMessage = () => {
    if (!loadState.hasMoreOld || moreOldLoading) return;

    getMoreOldMessages().catch(() => undefined);
  };

  const renderBody = () => {
    if (loadState.initLoading) {
      return (
        <div className="flex h-full w-full flex-col items-center justify-center">
          <Spin spinning />
          <div className="mt-4 text-sm">{t("states.loading")}</div>
          <div className="mt-1 text-xs text-[var(--sub-text)]">
            {t("states.loadingTip")}
          </div>
        </div>
      );
    }
    if (loadError) {
      return (
        <div className="flex h-full w-full flex-col items-center justify-center">
          <div className="text-sm">{t("states.loadFailed")}</div>
          <div className="mt-1 text-xs text-[var(--sub-text)]">
            {t("states.loadFailedTip")}
          </div>
          <Button
            className="mt-4"
            onClick={() => getMoreOldMessages(false).catch(() => undefined)}
          >
            {t("retry")}
          </Button>
        </div>
      );
    }
    return (
      <Virtuoso
        id="chat-list"
        className="w-full overflow-x-hidden"
        followOutput="smooth"
        firstItemIndex={loadState.firstItemIndex}
        initialTopMostItemIndex={SPLIT_COUNT - 1}
        startReached={loadMoreMessage}
        ref={virtuoso}
        data={loadState.messageList}
        components={{
          Header: () =>
            loadState.hasMoreOld ? (
              <div
                className={clsx(
                  "flex justify-center py-2 opacity-0",
                  moreOldLoading && "opacity-100",
                )}
              >
                <Spin />
              </div>
            ) : null,
        }}
        computeItemKey={(_, item) => item.clientMsgID}
        itemContent={(index, message) => {
          const dataIndex = index - loadState.firstItemIndex;
          const prevMessage = loadState.messageList[dataIndex - 1];
          const showTimeDivider =
            !prevMessage ||
            message.sendTime - prevMessage.sendTime > TIME_DIVIDER_GAP;

          return (
            <div>
              {showTimeDivider && (
                <div className="pt-4 text-center text-xs text-[var(--sub-text)]">
                  {formatMessageTime(message.sendTime)}
                </div>
              )}
              {SystemMessageTypes.includes(message.contentType) ? (
                <NotificationMessage key={message.clientMsgID} message={message} />
              ) : (
                <MessageItem
                  key={message.clientMsgID}
                  conversationID={conversationID}
                  message={message}
                  messageUpdateFlag={
                    (message.senderNickname ?? "") + (message.senderFaceUrl ?? "")
                  }
                  isSender={selfUserID === message.sendID}
                />
              )}
            </div>
          );
        }}
      />
    );
  };

  return (
    <Layout.Content
      className="relative flex h-full overflow-hidden !bg-[var(--chat-bg)]"
      id="chat-main"
    >
      {renderBody()}
    </Layout.Content>
  );
};

export default memo(ChatContent);
