// (C) 2023-2026 GoodData Corporation
import { useCallback, useEffect, useMemo, useState } from "react";
import cx from "classnames";
import { areObjRefsEqual, objRefToString, } from "@gooddata/sdk-model";
import { useBackendStrict, useCancelablePromise } from "@gooddata/sdk-ui";
import { useToastMessage } from "@gooddata/sdk-ui-kit";
import { messages, userDialogTabsMessages, userGroupDialogTabsMessages } from "./locales.js";
import { useTelemetry } from "./TelemetryContext.js";
import { extractUserGroupName, extractUserName, sortByName } from "./utils.js";
export const useUser = (userId, organizationId, isAdmin, onSuccess) => {
    const [user, setUser] = useState();
    const [isCurrentlyAdmin, setIsAdmin] = useState(isAdmin);
    const backend = useBackendStrict();
    const { error, status } = useCancelablePromise({
        promise: () => backend.organization(organizationId).users().getUser(userId),
        onSuccess: (user) => setUser(user),
    }, [backend, userId, organizationId]);
    const onUserDetailsChanged = (user, isAdmin) => {
        setUser(user);
        setIsAdmin(isAdmin);
        onSuccess();
    };
    return {
        user,
        onUserDetailsChanged,
        isCurrentlyAdmin,
        setIsAdmin,
        error,
        isLoading: status === "loading",
    };
};
export const useUserGroup = (userGroupId, organizationId, onSuccess) => {
    const [userGroup, setUserGroup] = useState();
    const backend = useBackendStrict();
    const { error, status } = useCancelablePromise({
        promise: () => backend.organization(organizationId).users().getUserGroup(userGroupId),
        onSuccess: (userGroup) => setUserGroup(userGroup),
    }, [backend, userGroupId, organizationId]);
    const onUserGroupDetailsChanged = (userGroup) => {
        setUserGroup(userGroup);
        onSuccess();
    };
    return {
        userGroup,
        onUserGroupDetailsChanged,
        error,
        isLoading: status === "loading",
    };
};
export const useDeleteUser = (userId, organizationId, onSuccess, onClose) => {
    const backend = useBackendStrict();
    const { addSuccess, addError } = useToastMessage();
    const [isProcessing, setIsProcessing] = useState(false);
    const trackEvent = useTelemetry();
    const deleteUser = useCallback(() => {
        setIsProcessing(true);
        backend
            .organization(organizationId)
            .users()
            .deleteUsers([userId])
            .then(() => {
            addSuccess(messages.userDeleteSuccess);
            trackEvent("user-deleted");
            onSuccess();
            onClose();
        })
            .catch((error) => {
            console.error("Delete of user failed", error);
            addError(messages.userDeletedFailure);
        })
            .finally(() => setIsProcessing(false));
    }, [backend, organizationId, userId, onSuccess, onClose, addSuccess, addError, trackEvent]);
    return {
        isDeleteUserProcessing: isProcessing,
        deleteUser,
    };
};
export const useDeleteUserGroup = (userGroupId, organizationId, onSuccess, onClose) => {
    const backend = useBackendStrict();
    const { addSuccess, addError } = useToastMessage();
    const [isProcessing, setIsProcessing] = useState(false);
    const trackEvent = useTelemetry();
    const deleteUserGroup = useCallback(() => {
        setIsProcessing(true);
        backend
            .organization(organizationId)
            .users()
            .deleteUserGroups([userGroupId])
            .then(() => {
            addSuccess(messages.userGroupDeleteSuccess);
            trackEvent("group-deleted");
            onSuccess();
            onClose();
        })
            .catch((error) => {
            console.error("Delete of user group failed", error);
            addError(messages.userGroupDeleteFailure);
        })
            .finally(() => setIsProcessing(false));
    }, [backend, organizationId, userGroupId, addError, addSuccess, onSuccess, onClose, trackEvent]);
    return {
        isDeleteUserGroupProcessing: isProcessing,
        deleteUserGroup,
    };
};
export const useDeleteDialog = () => {
    const [isConfirmDeleteOpened, setConfirmDeleteOpened] = useState(false);
    const dialogOverlayClassNames = cx("gd-user-management-dialog", {
        "gd-user-management-dialog-hidden": isConfirmDeleteOpened,
    });
    const dialogWrapperClassNames = cx("gd-user-management-dialog", {
        "gd-user-management-dialog-hidden": isConfirmDeleteOpened,
    });
    return {
        isConfirmDeleteOpened,
        onOpenDeleteDialog: () => setConfirmDeleteOpened(true),
        onCloseDeleteDialog: () => setConfirmDeleteOpened(false),
        dialogOverlayClassNames,
        dialogWrapperClassNames,
    };
};
export const useUserGroups = (userId, organizationId, bootstrapUserGroupId, onSuccess, setIsAdmin) => {
    const { addSuccess, addError } = useToastMessage();
    const backend = useBackendStrict();
    const [grantedUserGroups, setGrantedUserGroups] = useState(undefined);
    // load initial user groups
    useEffect(() => {
        void backend
            .organization(organizationId)
            .users()
            .getUserGroupsOfUser(userId)
            .then((userGroups) => {
            setGrantedUserGroups(userGroups.map((userGroup) => ({
                id: userGroup.id,
                title: extractUserGroupName(userGroup),
            })));
        });
    }, [backend, userId, organizationId]);
    const removeGrantedUserGroup = (grantedUserGroup) => {
        backend
            .organization(organizationId)
            .users()
            .removeUsersFromUserGroups([userId], [grantedUserGroup.id])
            .then(() => {
            addSuccess(messages.userGroupRemovedSuccess);
            setGrantedUserGroups(grantedUserGroups?.filter((item) => item.id !== grantedUserGroup.id));
            onSuccess();
        })
            .catch((error) => {
            console.error("Removal of user group failed", error);
            addError(messages.userGroupRemoveFailure);
        });
    };
    const hasBootstrapUserGroup = (userGroups) => userGroups?.some((group) => group.id === bootstrapUserGroupId);
    // removes admin group from the user if he is its member, update internal array of groups
    const removeAdminGroup = () => {
        if (hasBootstrapUserGroup(grantedUserGroups)) {
            void backend
                .organization(organizationId)
                .users()
                .removeUsersFromUserGroups([userId], [bootstrapUserGroupId])
                .then(() => setGrantedUserGroups(grantedUserGroups?.filter((item) => item.id !== bootstrapUserGroupId)));
        }
        else {
            void Promise.resolve();
        }
    };
    // update internal array with user groups after applied changed in groups edit mode
    const onUserGroupsChanged = (userGroups) => {
        const unchangedUserGroups = grantedUserGroups?.filter((item) => !userGroups.some((userGroup) => userGroup.id === item.id));
        const newUserGroups = [...(unchangedUserGroups ?? []), ...userGroups].sort(sortByName);
        setGrantedUserGroups(newUserGroups);
        if (hasBootstrapUserGroup(newUserGroups)) {
            setIsAdmin(true);
        }
        onSuccess();
    };
    return {
        grantedUserGroups,
        onUserGroupsChanged,
        removeGrantedUserGroup,
        removeAdminGroup,
    };
};
export const useUsers = (userGroupId, organizationId, onSuccess) => {
    const { addSuccess, addError } = useToastMessage();
    const backend = useBackendStrict();
    const [grantedUsers, setGrantedUsers] = useState([]);
    // load initial users
    useEffect(() => {
        void backend
            .organization(organizationId)
            .users()
            .getUsersOfUserGroup(userGroupId)
            .then((users) => {
            setGrantedUsers(users.map((user) => ({
                id: user.login,
                title: extractUserName(user),
                email: user.email,
            })));
        });
    }, [backend, userGroupId, organizationId]);
    const removeGrantedUsers = (grantedUser) => {
        backend
            .organization(organizationId)
            .users()
            .removeUsersFromUserGroups([grantedUser.id], [userGroupId])
            .then(() => {
            addSuccess(messages.usersRemovedSuccess);
            setGrantedUsers(grantedUsers.filter((item) => item.id !== grantedUser.id));
            onSuccess();
        })
            .catch((error) => {
            console.error("Removal of user failed", error);
            addError(messages.usersRemovedFailure);
        });
    };
    // update internal array with users after applied changed in user groups edit mode
    const onUsersChanged = (users) => {
        const unchangedUsers = grantedUsers.filter((item) => !users.some((g) => g.id === item.id));
        setGrantedUsers([...unchangedUsers, ...users].sort(sortByName));
        onSuccess();
    };
    return {
        grantedUsers,
        onUsersChanged,
        removeGrantedUsers,
    };
};
const getTabMessageKey = (tabId) => {
    switch (tabId) {
        case "WORKSPACES":
            return "workspaces";
        case "USER_GROUPS":
            return "userGroups";
        case "DATA_SOURCES":
            return "dataSources";
        default:
            return "details";
    }
};
export const useUserDialogTabs = (grantedWorkspaces, grantedUserGroups, grantedDataSources, isAdmin, selectedTab) => {
    const selectedTabLabel = selectedTab ? userDialogTabsMessages[getTabMessageKey(selectedTab)] : undefined;
    const [selectedTabId, setSelectedTabId] = useState(selectedTabLabel ?? (isAdmin ? userDialogTabsMessages.userGroups : userDialogTabsMessages.workspaces));
    const tabs = useMemo(() => {
        return [
            {
                id: userDialogTabsMessages.userGroups.id,
                values: { count: grantedUserGroups?.length },
            },
            isAdmin
                ? undefined
                : {
                    id: userDialogTabsMessages.workspaces.id,
                    values: { count: grantedWorkspaces?.length },
                },
            isAdmin
                ? undefined
                : {
                    id: userDialogTabsMessages.dataSources.id,
                    values: { count: grantedDataSources?.length },
                },
            userDialogTabsMessages.details,
        ].filter((tab) => !!tab);
    }, [isAdmin, grantedWorkspaces, grantedUserGroups, grantedDataSources]);
    return {
        tabs,
        selectedTabId,
        setSelectedTabId,
    };
};
export const useUserGroupDialogTabs = (grantedWorkspaces, grantedUsers, grantedDataSources, isAdmin) => {
    const [selectedTabId, setSelectedTabId] = useState(userGroupDialogTabsMessages.users);
    const tabs = useMemo(() => {
        return [
            {
                id: userGroupDialogTabsMessages.users.id,
                values: { count: grantedUsers?.length },
            },
            isAdmin
                ? undefined
                : {
                    id: userGroupDialogTabsMessages.workspaces.id,
                    values: { count: grantedWorkspaces?.length },
                },
            isAdmin
                ? undefined
                : {
                    id: userGroupDialogTabsMessages.dataSources.id,
                    values: { count: grantedDataSources?.length },
                },
            userGroupDialogTabsMessages.details,
        ].filter((tab) => !!tab);
    }, [isAdmin, grantedWorkspaces, grantedUsers, grantedDataSources]);
    return {
        tabs,
        selectedTabId,
        setSelectedTabId,
    };
};
export const useUserDialogMode = (initialView) => {
    const [dialogMode, setDialogMode] = useState(initialView);
    return {
        dialogMode,
        setDialogMode,
    };
};
export const useUserGroupDialogMode = (initialView) => {
    const [dialogMode, setDialogMode] = useState(initialView);
    return {
        dialogMode,
        setDialogMode,
    };
};
const useOrganization = (organizationId) => {
    const backend = useBackendStrict();
    const [organization, setOrganization] = useState();
    // initial load of organization details
    useEffect(() => {
        void backend
            .organization(organizationId)
            .getDescriptor(true)
            .then((organization) => {
            setOrganization(organization);
        });
    }, [backend, organizationId]);
    return {
        bootstrapUser: organization?.bootstrapUser,
        bootstrapUserGroup: organization?.bootstrapUserGroup,
    };
};
export const useOrganizationDetails = (organizationId) => {
    const { bootstrapUser, bootstrapUserGroup } = useOrganization(organizationId);
    return {
        isBootstrapUser: (user) => areObjRefsEqual(bootstrapUser, user?.ref),
        isBootstrapUserGroup: (userGroup) => areObjRefsEqual(bootstrapUserGroup, userGroup?.ref),
        bootstrapUserId: bootstrapUser ? objRefToString(bootstrapUser) : undefined,
        bootstrapUserGroupId: bootstrapUserGroup ? objRefToString(bootstrapUserGroup) : undefined,
    };
};
//# sourceMappingURL=dialogHooks.js.map