import { useState } from "react";
import { observer } from "mobx-react-lite";
import Link from "next/link";
import { useRouter } from "next/router";
// icons
import { ChevronDown, Dot, XCircle } from "lucide-react";
// ui
import { CustomSelect, Tooltip, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ConfirmProjectMemberRemove } from "components/project";
// constants
import { PM_ROLE_CHANGED, PROJECT_MEMBER_LEFT, PROJECT_MEMBER_REMOVED } from "constants/event-tracker";
import { EUserProjectRoles } from "constants/project";
import { ROLE } from "constants/workspace";
// hooks
import { useEventTracker, useMember, useProject, useUser } from "hooks/store";
// helpers
import { getUserRole } from "helpers/user.helper";

type Props = {
  userId: string;
};

export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
  const { userId } = props;
  // states
  const [removeMemberModal, setRemoveMemberModal] = useState(false);
  // router
  const router = useRouter();
  const { workspaceSlug, projectId } = router.query;
  // store hooks
  const {
    currentUser,
    membership: { currentProjectRole, leaveProject },
  } = useUser();
  const { fetchProjects } = useProject();
  const {
    project: { removeMemberFromProject, getProjectMemberDetails, updateMember },
  } = useMember();
  const { captureEvent } = useEventTracker();

  // derived values
  const isAdmin = currentProjectRole === EUserProjectRoles.ADMIN;
  const userDetails = getProjectMemberDetails(userId);

  const handleRemove = async () => {
    if (!workspaceSlug || !projectId || !userDetails) return;

    if (userDetails.member?.id === currentUser?.id) {
      await leaveProject(workspaceSlug.toString(), projectId.toString())
        .then(async () => {
          captureEvent(PROJECT_MEMBER_LEFT, {
            state: "SUCCESS",
            element: "Project settings members page",
          });
          await fetchProjects(workspaceSlug.toString());
          router.push(`/${workspaceSlug}/projects`);
        })
        .catch((err) =>
          setToast({
            type: TOAST_TYPE.ERROR,
            title: "Error",
            message: err?.error || "Something went wrong. Please try again.",
          })
        );
    } else
      await removeMemberFromProject(workspaceSlug.toString(), projectId.toString(), userDetails.member.id)
        .then(() => {
          captureEvent(PROJECT_MEMBER_REMOVED, {
            member_id: userDetails.member.id,
            role: getUserRole(userDetails.role as number),
            removed_by_role: currentProjectRole ? getUserRole(currentProjectRole as number) : undefined,
            state: "SUCCESS",
            element: "Project settings members page",
          });
        })
        .catch((err) =>
          setToast({
            type: TOAST_TYPE.ERROR,
            title: "Error",
            message: err?.error || "Something went wrong. Please try again.",
          })
        );
  };

  if (!userDetails) return null;

  return (
    <>
      <ConfirmProjectMemberRemove
        isOpen={removeMemberModal}
        onClose={() => setRemoveMemberModal(false)}
        data={userDetails.member}
        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">
          {userDetails.member?.avatar && userDetails.member?.avatar !== "" ? (
            <Link href={`/${workspaceSlug}/profile/${userDetails.member?.id}`}>
              <span className="relative flex h-10 w-10 items-center justify-center rounded p-4 capitalize text-white">
                <img
                  src={userDetails.member?.avatar}
                  alt={userDetails.member?.display_name || userDetails.member?.email}
                  className="absolute left-0 top-0 h-full w-full rounded object-cover"
                />
              </span>
            </Link>
          ) : (
            <Link href={`/${workspaceSlug}/profile/${userDetails.id}`}>
              <span className="relative flex h-10 w-10 items-center justify-center rounded bg-gray-700 p-4 capitalize text-white">
                {(userDetails.member?.display_name ?? userDetails.member?.email ?? "?")[0]}
              </span>
            </Link>
          )}

          <div>
            <Link href={`/${workspaceSlug}/profile/${userDetails.member?.id}`}>
              <span className="text-sm font-medium">
                {userDetails.member?.first_name} {userDetails.member?.last_name}
              </span>
            </Link>
            <div className="flex items-center">
              <p className="text-xs text-custom-text-300">{userDetails.member?.display_name}</p>
              {isAdmin && (
                <>
                  <Dot height={16} width={16} className="text-custom-text-300" />
                  <p className="text-xs text-custom-text-300">{userDetails.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 ${
                    userDetails.member?.id !== currentUser?.id ? "" : "text-custom-text-400"
                  }`}
                >
                  {ROLE[userDetails.role]}
                </span>
                {userDetails.member?.id !== currentUser?.id && (
                  <span className="grid place-items-center">
                    <ChevronDown className="h-3 w-3" />
                  </span>
                )}
              </div>
            }
            value={userDetails.role}
            onChange={(value: EUserProjectRoles) => {
              if (!workspaceSlug || !projectId) return;

              updateMember(workspaceSlug.toString(), projectId.toString(), userDetails.member?.id, {
                role: value,
              })
                .then(() => {
                  captureEvent(PM_ROLE_CHANGED, {
                    member_id: userDetails.member.id,
                    changed_role: getUserRole(value as number),
                    state: "SUCCESS",
                    element: "Project settings members page",
                  });
                })
                .catch((err) => {
                  const error = err.error;
                  const errorString = Array.isArray(error) ? error[0] : error;

                  setToast({
                    type: TOAST_TYPE.ERROR,
                    title: "Error!",
                    message: errorString ?? "An error occurred while updating member role. Please try again.",
                  });
                });
            }}
            disabled={
              userDetails.member?.id === currentUser?.id || !currentProjectRole || currentProjectRole < userDetails.role
            }
            placement="bottom-end"
          >
            {Object.keys(ROLE).map((key) => {
              if (currentProjectRole && !isAdmin && currentProjectRole < parseInt(key)) return null;

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