import { createRef, MouseEventHandler, useEffect, useState } from "react";
import { useSession } from "./Session";
import { User } from "./api";

interface ContextMenuItem {
  label: string;
  onClick: () => void;
}

const UserInfo = (user: User) => {
  return (
    <div className="user-info">
      <div>
        <b>username: </b>
      </div>
      <div>{user?.username}</div>
      <div>
        <b>display name: </b>
      </div>
      <div>{user?.display_name}</div>
      <div>
        <b>number: </b>
      </div>
      <div>{user?.number ? user?.number : "-"}</div>
      <div>
        <b>email: </b>
      </div>
      <div>{user?.email ? user?.email : "-"}</div>
    </div>
  );
};

export default function Avatar() {
  const { user, onLogout } = useSession();
  const [contextMenu, setContextMenu] = useState<{
    open: boolean;
    allowOpen: boolean;
    mouseX: number;
    mouseY: number;
  }>({ open: false, allowOpen: true, mouseX: 0, mouseY: 0 });
  const contextMenuRef = createRef<HTMLUListElement>();
  const avatarRef = createRef<HTMLDivElement>();

  const contextMenuItems: ContextMenuItem[] = [
    { label: "View Profile", onClick: handleViewProfile },
    { label: "Logout", onClick: onLogout },
  ];

  const handleMenuClick: MouseEventHandler<HTMLDivElement> = (event) => {
    if (!contextMenu.allowOpen) return;
    event.preventDefault();
    setContextMenu({
      open: !contextMenu.open,
      allowOpen: contextMenu.allowOpen,
      mouseX: event.clientX + 4,
      mouseY: event.clientY + 2,
    });
  };

  useEffect(() => {
    if (contextMenu.open) {
      document.addEventListener("click", handleCloseContextMenuOutside);
    }
    return () => {
      document.removeEventListener("click", handleCloseContextMenuOutside);
    };
  }, [contextMenu.open]);

  const handleMenuClose = () => {
    setContextMenu({ ...contextMenu, open: false });
    setContextMenu((prevContextMenu) => ({
      ...prevContextMenu,
      allowOpen: false,
    }));
    setTimeout(() => {
      setContextMenu((prevContextMenu) => ({
        ...prevContextMenu,
        allowOpen: true,
      }));
    }, 100);
  };

  const handleCloseContextMenuOutside: (event: MouseEvent) => void = (ev) => {
    if (
      !(
        contextMenuRef.current?.contains(ev.target as Node) ||
        avatarRef.current?.contains(ev.target as Node)
      )
    )
      handleMenuClose();
  };

  const [dialog, setDialog] = useState(<></>);
  const dialogRef = createRef<HTMLDialogElement>();

  function handleViewProfile() {
    handleMenuClose();
    if (user) {
      dialogRef.current?.showModal();
      setDialog(UserInfo(user));
    }
  }

  return (
    <div
      className="avatar"
      onContextMenu={handleMenuClick}
      style={{ display: user ? "block" : "none" }}
      onClick={(event) => {
        if (contextMenu.open && event.target === avatarRef.current) {
          handleMenuClose();
        } else {
          handleMenuClick(event);
        }
      }}
      ref={avatarRef}
    >
      👤 {user?.username}
      {contextMenu.open && (
        <ul
          className="context-menu"
          ref={contextMenuRef}
          style={{
            zIndex: 3,
            position: "absolute",
            top: contextMenu.mouseY,
            left: contextMenu.mouseX,
            background: "white",
            border: "1px solid #ddd",
            padding: 0,
            margin: 0,
            listStyle: "none",
          }}
        >
          {contextMenuItems.map((item, index) => (
            <li
              key={index}
              style={{
                padding: "10px",
                borderBottom: "1px solid #ddd",
                cursor: "pointer",
              }}
              onClick={() => {
                item.onClick();
                handleMenuClose();
              }}
            >
              {item.label}
            </li>
          ))}
        </ul>
      )}
      <dialog
        id="AvatarDialog"
        ref={dialogRef}
        onClick={(event) => {
          event.stopPropagation();
          event.currentTarget.close();
        }}
      >
        {dialog}
      </dialog>
    </div>
  );
}
