import { useLiveblocks } from "@/hooks/useLiveblocks";
import { useUser } from "@/hooks/useUser";
import { MutableRefObject, useEffect } from "react";

import { Cursor } from "./Cursor";

const colors = [
  "#07f",
  "#0bf",
  "#0c8",
  "#8c1",
  "#fb0",
  "#f81",
  "#e14",
  "#e4b",
  "#85f",
];

interface Props {
  // The element that's used for pointer events and scroll position
  element: MutableRefObject<HTMLElement | null>;
}

/**
 * This file shows you how to create a reusable live cursors component for your product.
 * The component takes a reference to another element ref `element` and renders
 * cursors according to the location and scroll position of this panel.
 */
export function Cursors({ element }: Props) {
  /**
   * useMyPresence returns a function to update  the current user's presence.
   * updateMyPresence is different to the setState function returned by the useState hook from React.
   * You don't need to pass the full presence object to update it.
   * See https://liveblocks.io/docs/api-reference/liveblocks-react#useUpdateMyPresence for more information
   */

  const {
    liveblocks: { enterRoom, leaveRoom },
  } = useLiveblocks();

  /**
   * Return all the other users in the room and their presence (a cursor position in this case)
   */
  const others = useLiveblocks((state) => state.liveblocks.others);
  const othersCursors = others.map((user) => user.presence);
  const reset = useLiveblocks((state) => state.reset);
  const updateMyPresence = useLiveblocks((state) => state.setCursor);

  const { user: currentUser, isLoading, setUser, setIsLoading } = useUser();

  const getName = () => {
    if (currentUser && currentUser?.email) {
      return currentUser.email.split("@")[0].replace(".", "");
    } else {
      return "";
    }
  };

  useEffect(() => {
    if (!element.current) {
      return;
    }

    console.log("other>>>>", others);

    // If element, add live cursor listeners
    const updateCursor = (event: PointerEvent) => {
      if (!element?.current) {
        return;
      }

      const { top, left } = element.current.getBoundingClientRect();

      const x = event.clientX - left + element.current.scrollLeft;
      const y = event.clientY - top + element.current.scrollTop;

      updateMyPresence(
        {
          x: Math.round(x),
          y: Math.round(y),
        },
        getName(),
        currentUser.user_id,
        currentUser.profile_picture_url
      );
    };

    const removeCursor = () => {
      updateMyPresence(
        null,
        getName(),
        currentUser.user_id,
        currentUser.profile_picture_url
      );
    };

    element.current.addEventListener("pointermove", updateCursor);
    element.current.addEventListener("pointerleave", removeCursor);

    // Clean up event listeners
    const oldRef = element.current;
    return () => {
      if (!oldRef) {
        return;
      }
      oldRef.removeEventListener("pointermove", updateCursor);
      oldRef.removeEventListener("pointerleave", removeCursor);
    };
  }, [updateMyPresence, element, currentUser]);

  return (
    <>
      {
        /**
         * Iterate over other users and display a cursor based on their presence
         */

        others
          .filter((x) => !!x)
          .map(({ connectionId, presence }) => {
            if (presence == null || presence.cursor == null) {
              return null;
            }

            return (
              <Cursor
                color={colors[connectionId % colors.length]}
                key={`cursor-${presence.id}`}
                image={presence?.image as string}
                // connectionId is an integer that is incremented at every new connections
                // Assigning a color with a modulo makes sure that a specific user has the same colors on every clients
                name={presence?.name as string}
                // x={presence.cursor.x}
                // y={presence.cursor.y}
                x={0}
                y={0}
              />
            );
          })
      }
    </>
  );
}
