import { useState, FC } from "react";
import { observer } from "mobx-react-lite";
import Link from "next/link";
import { useRouter } from "next/router";
// lucide icons
import { ChevronDown, Dot, XCircle } from "lucide-react";
// ui
import { CustomSelect, Tooltip, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ConfirmWorkspaceMemberRemove } from "components/workspace";
// helpers
import { getUserRole } from "helpers/user.helper";
// constants
import { WM_ROLE_CHANGED, WORKSPACE_MEMBER_REMOVED, WORKSPACE_MEMBER_LEFT } from "constants/event-tracker";
import { EUserWorkspaceRoles, ROLE } from "constants/workspace";
// hooks
import { useEventTracker, useMember, useUser } from "hooks/store";
import { usePlatformOS } from "hooks/use-platform-os";

type Props = {
  memberId: string;
};

export const WorkspaceMembersListItem: FC<Props> = observer((props) => {
  const { memberId } = props;
  // states
  const [removeMemberModal, setRemoveMemberModal] = useState(false);
  // router
  const router = useRouter();
  const { workspaceSlug } = router.query;
  // store hooks
  const {
    currentUser,
    currentUserSettings,
    membership: { currentWorkspaceRole, leaveWorkspace },
  } = useUser();
  const {
    workspace: { updateMember, removeMemberFromWorkspace, getWorkspaceMemberDetails },
  } = useMember();
  const { captureEvent } = useEventTracker();
  const { isMobile } = usePlatformOS();
  // derived values
  const memberDetails = getWorkspaceMemberDetails(memberId);

  const handleLeaveWorkspace = async () => {
    if (!workspaceSlug || !currentUserSettings) return;

    await leaveWorkspace(workspaceSlug.toString())
      .then(() => {
        captureEvent(WORKSPACE_MEMBER_LEFT, {
          member_id: currentUser?.id,
          role: currentWorkspaceRole ? getUserRole(currentWorkspaceRole as number) : undefined,
          state: "SUCCESS",
          element: "Workspace settings members page",
        });
        router.push("/profile");
      })
      .catch((err) =>
        setToast({
          type: TOAST_TYPE.ERROR,
          title: "Error",
          message: err?.error || "Something went wrong. Please try again.",
        })
      );
  };

  const handleRemoveMember = async () => {
    if (!workspaceSlug || !memberDetails) return;

    await removeMemberFromWorkspace(workspaceSlug.toString(), memberDetails.member.id)
      .then(() =>
        captureEvent(WORKSPACE_MEMBER_REMOVED, {
          member_id: memberDetails.member.id,
          removed_by_role: currentWorkspaceRole ? getUserRole(currentWorkspaceRole as number) : undefined,
          role: memberDetails.role ? getUserRole(memberDetails.role as number) : undefined,
          state: "SUCCESS",
          element: "Workspace settings members page",
        })
      )
      .catch((err) =>
        setToast({
          type: TOAST_TYPE.ERROR,
          title: "Error",
          message: err?.error || "Something went wrong. Please try again.",
        })
      );
  };

  const handleRemove = async () => {
    if (memberDetails?.member.id === currentUser?.id) await handleLeaveWorkspace();
    else await handleRemoveMember();
  };

  if (!memberDetails) return null;

  // is the member current logged in user
  const isCurrentUser = memberDetails?.member.id === currentUser?.id;
  // is the current logged in user admin
  const isAdmin = currentWorkspaceRole === EUserWorkspaceRoles.ADMIN;
  // role change access-
  // 1. user cannot change their own role
  // 2. only admin or member can change role
  // 3. user cannot change role of higher role
  const hasRoleChangeAccess =
    currentWorkspaceRole &&
    !isCurrentUser &&
    [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER].includes(currentWorkspaceRole) &&
    memberDetails.role <= currentWorkspaceRole;

  return (
    <>
      <ConfirmWorkspaceMemberRemove
        isOpen={removeMemberModal}
        onClose={() => setRemoveMemberModal(false)}
        userDetails={{
          id: memberDetails.member.id,
          display_name: `${memberDetails.member.display_name}`,
        }}
        onSubmit={handleRemove}
      />
      <div className="group flex items-center justify-between px-3 py-4 hover:bg-custom-background-90">
        <div className="flex items-center gap-x-4 gap-y-2">
          {memberDetails.member.avatar && memberDetails.member.avatar.trim() !== "" ? (
            <Link href={`/${workspaceSlug}/profile/${memberDetails.member.id}`}>
              <span className="relative flex h-10 w-10 items-center justify-center rounded p-4 capitalize text-white">
                <img
                  src={memberDetails.member.avatar}
                  className="absolute left-0 top-0 h-full w-full rounded object-cover"
                  alt={memberDetails.member.display_name || memberDetails.member.email}
                />
              </span>
            </Link>
          ) : (
            <Link href={`/${workspaceSlug}/profile/${memberDetails.member.id}`}>
              <span className="relative flex h-10 w-10 items-center justify-center rounded bg-gray-700 p-4 capitalize text-white">
                {(memberDetails.member.email ?? memberDetails.member.display_name ?? "?")[0]}
              </span>
            </Link>
          )}
          <div>
            <Link href={`/${workspaceSlug}/profile/${memberDetails.member.id}`}>
              <span className="text-sm font-medium">
                {memberDetails.member.first_name} {memberDetails.member.last_name}
              </span>
            </Link>
            <div className="flex items-center">
              <p className="text-xs text-custom-text-300">{memberDetails.member.display_name}</p>
              {isAdmin && (
                <>
                  <Dot height={16} width={16} className="text-custom-text-300" />
                  <p className="text-xs text-custom-text-300">{memberDetails.member.email}</p>
                </>
              )}
            </div>
          </div>
        </div>
        <div className="flex items-center gap-2 text-xs">
          <CustomSelect
            customButton={
              <div className="item-center flex gap-1 rounded px-2 py-0.5">
                <span
                  className={`flex items-center rounded text-xs font-medium ${
                    hasRoleChangeAccess ? "" : "text-custom-sidebar-text-400"
                  }`}
                >
                  {ROLE[memberDetails.role]}
                </span>
                {hasRoleChangeAccess && (
                  <span className="grid place-items-center">
                    <ChevronDown className="h-3 w-3" />
                  </span>
                )}
              </div>
            }
            value={memberDetails.role}
            onChange={(value: EUserWorkspaceRoles) => {
              if (!workspaceSlug || !value) return;

              updateMember(workspaceSlug.toString(), memberDetails.member.id, {
                role: value,
              })
                .then(() =>
                  captureEvent(WM_ROLE_CHANGED, {
                    member_id: memberDetails.member.id,
                    changed_role: value ? getUserRole(value as number) : undefined,
                    state: "SUCCESS",
                    element: "Workspace settings members page",
                  })
                )
                .catch(() => {
                  setToast({
                    type: TOAST_TYPE.ERROR,
                    title: "Error!",
                    message: "An error occurred while updating member role. Please try again.",
                  });
                });
            }}
            disabled={!hasRoleChangeAccess}
            placement="bottom-end"
          >
            {Object.keys(ROLE).map((key) => {
              if (currentWorkspaceRole && currentWorkspaceRole !== 20 && currentWorkspaceRole < parseInt(key))
                return null;

              return (
                <CustomSelect.Option key={key} value={parseInt(key, 10)}>
                  <>{ROLE[parseInt(key) as keyof typeof ROLE]}</>
                </CustomSelect.Option>
              );
            })}
          </CustomSelect>
          <Tooltip
            isMobile={isMobile}
            tooltipContent={isCurrentUser ? "Leave workspace" : "Remove member"}
            disabled={!isAdmin && !isCurrentUser}
          >
            <button
              type="button"
              onClick={() => setRemoveMemberModal(true)}
              className={
                isAdmin || isCurrentUser
                  ? "pointer-events-none opacity-0 group-hover:pointer-events-auto group-hover:opacity-100"
                  : "pointer-events-none opacity-0"
              }
            >
              <XCircle className="h-3.5 w-3.5 text-red-500" strokeWidth={2} />
            </button>
          </Tooltip>
        </div>
      </div>
    </>
  );
});
