import { compact } from "es-toolkit/compat";
import { observer } from "mobx-react";
import * as React from "react";
import type Comment from "~/models/Comment";
import useHover from "~/hooks/useHover";
import useStores from "~/hooks/useStores";
import Logger from "~/utils/Logger";
import Flex from "../Flex";
import { ResizingHeightContainer } from "../ResizingHeightContainer";
import Reaction from "./Reaction";

type Props = {
  /** Model for which to show the reactions. */
  model: Comment;
  /** Callback when the user intends to add a reaction. */
  onAddReaction: (emoji: string) => Promise<void>;
  /** Callback when the user intends to remove a reaction. */
  onRemoveReaction: (emoji: string) => Promise<void>;
  /** classname generated by styled-components. */
  className?: string;
  /** Picker to render as the last element */
  picker?: React.ReactElement;
};

const ReactionList: React.FC<Props> = ({
  model,
  onAddReaction,
  onRemoveReaction,
  className,
  picker,
}) => {
  const { users } = useStores();
  const listRef = React.useRef<HTMLDivElement>(null);

  const hovered = useHover({
    ref: listRef,
    duration: 250,
  });

  React.useEffect(() => {
    const loadReactedUsersData = async () => {
      try {
        await model.loadReactedUsersData();
      } catch (_err) {
        Logger.warn("Could not prefetch reaction data");
      }
    };

    if (hovered) {
      void loadReactedUsersData();
    }
  }, [hovered, model]);

  const hasReactions = !!model.reactions.length;
  const style = React.useMemo(() => {
    if (hasReactions) {
      return { minHeight: 28 };
    }
    return undefined;
  }, [hasReactions]);

  return (
    <ResizingHeightContainer style={style}>
      <Flex ref={listRef} className={className} align="center" gap={6} wrap>
        {model.reactions.map((reaction) => {
          const reactedUsers = compact(
            reaction.userIds.map((id) => users.get(id))
          );

          return (
            <Reaction
              key={reaction.emoji}
              reaction={reaction}
              reactedUsers={reactedUsers}
              disabled={model.isResolved}
              onAddReaction={onAddReaction}
              onRemoveReaction={onRemoveReaction}
            />
          );
        })}
        {picker}
      </Flex>
    </ResizingHeightContainer>
  );
};

export default observer(ReactionList);
