import { createRef, MouseEventHandler, useEffect, useState } from "react";
import { TeamState, useSession } from "./Session";
import { User } from "./api";
import { useTheme } from "./ThemeProvider";
import { colourTheme, darkTheme, normalTheme, rainbowTheme } from "./themes";
import { useNavigate } from "react-router";
import { Team } from "./types";

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

const UserInfo = (user: User, teams: TeamState | undefined) => {
  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>gender: </b>
      </div>
      <div>{user?.gender?.toUpperCase() || "-"}</div>
      <div>
        <b>number: </b>
      </div>
      <div>{user?.number || "-"}</div>
      <div>
        <b>email: </b>
      </div>
      <div>{user?.email || "-"}</div>
      {teams && (
        <>
          <div>
            <b>teams: </b>
          </div>
          <ul
            style={{
              margin: 0,
              padding: 0,
              textAlign: "left",
            }}
          >
            {teams.teams.map((team, index) => (
              <li>
                {<b>{team.name}</b>} (
                {team.location || team.country || "location unknown"})
              </li>
            ))}
          </ul>
        </>
      )}
    </div>
  );
};

export default function Avatar() {
  const { user, teams, setTeams, onLogout } = useSession();
  const { theme, setTheme } = useTheme();
  const navigate = useNavigate();
  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: "change password", onClick: () => navigate("/changepassword") },
    {
      label: "change theme",
      onClick: () => {
        switch (theme) {
          case darkTheme:
            setTheme(colourTheme);
            break;
          case colourTheme:
            setTheme(rainbowTheme);
            break;
          case rainbowTheme:
            setTheme(normalTheme);
            break;
          case normalTheme:
            setTheme(darkTheme);
        }
      },
    },
    { 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() {
    if (user && teams) {
      dialogRef.current?.showModal();
      setDialog(UserInfo(user, teams));
    }
  }

  return (
    <>
      <div className="avatars" style={{ display: user ? "block" : "none" }}>
        <div
          className="avatar"
          onContextMenu={handleMenuClick}
          onClick={(event) => {
            if (contextMenu.open && event.target === avatarRef.current) {
              handleMenuClose();
            } else {
              handleMenuClick(event);
            }
          }}
          ref={avatarRef}
        >
          👤 {user?.username}
        </div>
        {teams && teams?.teams.length > 1 && (
          <select
            className="group-avatar"
            value={teams.activeTeam}
            onChange={(e) =>
              setTeams({ ...teams, activeTeam: Number(e.target.value) })
            }
          >
            {teams.teams.map((team) => (
              <option key={team.id} value={team.id}>
                👥 {team.name}
              </option>
            ))}
          </select>
        )}
      </div>

      {contextMenu.open && (
        <ul
          className="context-menu"
          ref={contextMenuRef}
          style={{
            top: contextMenu.mouseY,
            left: contextMenu.mouseX,
          }}
        >
          {contextMenuItems.map((item, index) => (
            <li
              key={index}
              onClick={() => {
                item.onClick();
                handleMenuClose();
              }}
            >
              {item.label}
            </li>
          ))}
        </ul>
      )}
      <dialog
        id="AvatarDialog"
        ref={dialogRef}
        onClick={(event) => {
          event.stopPropagation();
          event.currentTarget.close();
        }}
      >
        {dialog}
      </dialog>
    </>
  );
}
