"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useVirtualizer } from "@tanstack/react-virtual";

import { Button, Icon, IconName, Spinner } from "@/components/ui";
import { useChat } from "@/providers/chat-provider";

import { ChatMessage, Suggestions } from "..";

import styles from "./ChatMessagesWrapper.module.scss";

export default function ChatMessagesWrapper() {
  const messagesWrapperRef = useRef<HTMLDivElement>(null);

  const [isScrolledUp, setIsScrolledUp] = useState(false);

  const {
    messages: socketMessages,
    isLoadingAdvisorMessage,
    hasMoreOlderMessages,
    isLoadingOlder,
    // unreadMessagesCount,
    loadOlder,
    send,
  } = useChat();

  const messages = useMemo(() => {
    const msgs = [...socketMessages];
    if (isLoadingAdvisorMessage) {
      msgs.unshift({
        id: "typing",
        type: "text",
        text: "…",
        role: "assistant",
        isRead: false,
        createdDate: new Date().toISOString(),
      });
    }
    return msgs;
  }, [isLoadingAdvisorMessage, socketMessages]);

  const virtualizer = useVirtualizer({
    enabled: messages.length > 0,
    count: hasMoreOlderMessages ? messages.length + 1 : messages.length,
    getScrollElement: () => messagesWrapperRef.current,
    measureElement: el => el.getBoundingClientRect().height,
    getItemKey: idx => messages[idx]?.id ?? idx,
    estimateSize: _i => 100,
    overscan: 5,
    paddingStart: 36,
    paddingEnd: 36,
    gap: 8,
  });

  const items = virtualizer.getVirtualItems();

  const scrollToBottom = useCallback(() => {
    virtualizer.scrollToOffset(0);
  }, [virtualizer]);

  useEffect(() => {
    const handleScroll = (e: WheelEvent) => {
      e.preventDefault();
      const currentTarget = e.currentTarget as HTMLElement;

      if (currentTarget) {
        currentTarget.scrollTop -= e.deltaY;
      }
    };
    messagesWrapperRef.current?.addEventListener("wheel", handleScroll, {
      passive: false,
    });
    return () => {
      // eslint-disable-next-line react-hooks/exhaustive-deps
      messagesWrapperRef.current?.removeEventListener("wheel", handleScroll);
    };
  }, []);

  useEffect(() => {
    const [lastItem] = [...items].reverse();

    if (!lastItem) {
      return;
    }

    if (
      lastItem.index >= messages.length - 1 &&
      hasMoreOlderMessages &&
      !isLoadingOlder
    ) {
      loadOlder();
    }
  }, [hasMoreOlderMessages, loadOlder, messages.length, isLoadingOlder, items]);

  useEffect(() => {
    if (!messagesWrapperRef.current || messages.length === 0) return;

    setIsScrolledUp((virtualizer.scrollOffset || 0) > 600);
  }, [virtualizer.scrollOffset, messages.length, messagesWrapperRef]);

  return (
    <>
      {isScrolledUp && (
        <Button
          className={styles.scrollToBottomButton}
          onClick={scrollToBottom}
          aria-label="Scroll to bottom"
          style={{
            top: `${messagesWrapperRef.current?.clientHeight}px`,
          }}
        >
          <Icon
            name={IconName.Chevron}
            style={{ transform: "rotate(-90deg)" }}
          />
          {/* {!!unreadMessagesCount && (
            <Badge className={styles.badge}>
              <Typography weight="semiBold" size="xs" color="black">
                {unreadMessagesCount > 99 ? "99+" : unreadMessagesCount}
              </Typography>
            </Badge>
          )} */}
        </Button>
      )}
      <div ref={messagesWrapperRef} className={styles.messagesWrapper}>
        <Suggestions
          className={styles.suggestions}
          onSuggestionClick={suggestion => {
            send(suggestion);
          }}
        />
        <div
          style={{
            height: virtualizer.getTotalSize(),
            width: "100%",
            position: "relative",
          }}
        >
          {items.map(virtualRow => {
            const message = messages[virtualRow.index];
            const isLoaderRow = virtualRow.index > messages.length - 1;

            return (
              <div
                key={virtualRow.key}
                data-index={virtualRow.index}
                ref={virtualizer.measureElement}
                style={{
                  position: "absolute",
                  top: 0,
                  left: 0,
                  width: "100%",
                  paddingInline: "16px",
                  transform: `translateY(${virtualRow.start}px) scaleY(-1)`,
                }}
              >
                {!isLoaderRow && (
                  <ChatMessage key={message.id} message={message} />
                )}
                {isLoaderRow && (
                  <div className={styles.loaderTop}>
                    <Spinner size={16} />
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
}

export const ChatMessagesWrapperLoader = () => {
  return (
    <div className={styles.loaderContainer}>
      <Spinner />
    </div>
  );
};
