// (C) 2021-2026 GoodData Corporation
import { differenceWith, partition } from "lodash-es";
import { areObjRefsEqual, idRef, objRefToString, uriRef, } from "@gooddata/sdk-model";
import { simplifyText } from "@gooddata/util";
import { isGranteeGroup, isGranteeGroupAll, isGranteeRules, isGranularGranteeGroup, } from "./types.js";
/**
 * @internal
 */
export const ADD_GRANTEE_ID = "add-grantee-id";
/**
 * @internal
 */
export const ADD_GRANTEE_SELECT_ID = "add-grantee-select-id";
/**
 * @internal
 */
export const ALL_WORKSPACE_USERS = "allWorkspaceUsers";
/**
 * @internal
 */
export const SHARE_LINK_HELPER_TEXT_ID = "share-link-helper-text";
/**
 * @internal
 */
export const SHARE_LINK_HEADLINE_ID = "share-link-headline";
/**
 * @internal
 */
export const GranteeRules = {
    type: ALL_WORKSPACE_USERS,
    id: {
        identifier: ALL_WORKSPACE_USERS,
    },
    permissions: ["VIEW"],
    inheritedPermissions: [],
};
/**
 * @internal
 */
export const GROUP_ALL_ID = "groupAll";
/**
 * @internal
 */
export const GranteeGroupAll = {
    id: uriRef(GROUP_ALL_ID),
    type: "groupAll",
};
/**
 * @internal
 */
export const INACTIVE_OWNER_ID = "inactive_owner";
/**
 * @internal
 */
export const InactiveOwner = {
    id: uriRef(INACTIVE_OWNER_ID),
    type: "inactive_owner",
};
/**
 * @internal
 */
const exhaustiveCheck = (_param) => {
    throw new Error("unknown grantee type");
};
/**
 * @internal
 */
export const getGranteeLabel = (grantee, intl) => {
    if (grantee.type === "user" || grantee.type === "granularUser") {
        if (grantee.isCurrentUser) {
            return intl.formatMessage({ id: "shareDialog.share.grantee.item.you" }, { userName: grantee.name });
        }
        return grantee.name;
    }
    else if (grantee.type === "group" || grantee.type === "granularGroup") {
        return grantee.name;
    }
    else if (grantee.type === "groupAll" || grantee.type === "allWorkspaceUsers") {
        return intl.formatMessage({ id: "shareDialog.share.grantee.item.user.all" });
    }
    else if (grantee.type === "inactive_owner") {
        return intl.formatMessage({ id: "shareDialog.share.grantee.item.user.inactive" });
    }
    else {
        exhaustiveCheck(grantee);
    }
    return "";
};
/**
 * @internal
 */
export const sortGranteesByName = (intl) => (granteeA, granteeB) => {
    const textA = getGranteeLabel(granteeA, intl).toUpperCase();
    const textB = getGranteeLabel(granteeB, intl).toUpperCase();
    return textA < textB ? -1 : textA > textB ? 1 : 0;
};
export const sortGranteeList = (grantees, intl) => {
    const granteeSort = sortGranteesByName(intl);
    const hasAllGroup = hasGroupAll(grantees);
    const granteeRules = grantees.find((g) => isGranteeRules(g));
    const granteesWithNoAllGroup = grantees.filter((g) => !(isGranteeGroupAll(g) || isGranteeRules(g)));
    const [groups, users] = partition(granteesWithNoAllGroup, (grantee) => isGranteeGroup(grantee) || isGranularGranteeGroup(grantee));
    const sorted = [...groups.sort(granteeSort), ...users.sort(granteeSort)];
    if (hasAllGroup) {
        return [GranteeGroupAll, ...sorted];
    }
    if (granteeRules) {
        return [granteeRules, ...sorted];
    }
    return sorted;
};
/**
 * @internal
 */
export const notInArrayFilter = (array, notInArray) => {
    return differenceWith(array, notInArray, (g, g1) => areObjRefsEqual(g.id, g1.id));
};
/**
 * @internal
 */
export const hasGroupAll = (array) => {
    return array.some((g) => areObjRefsEqual(g.id, GranteeGroupAll.id));
};
/**
 * @internal
 */
export const hasGranteeRules = (array) => {
    return array.some((g) => isGranteeRules(g));
};
/**
 * @internal
 */
export const getAppliedGrantees = (grantees, granteesToAdd, granteesToDelete) => {
    const omitDeleted = notInArrayFilter(grantees, granteesToDelete);
    return [...omitDeleted, ...granteesToAdd];
};
/**
 * @internal
 */
export const getGranteeItemTestId = (grantee, prefix) => {
    const prefixValue = prefix ? `${prefix}-` : "";
    const id = objRefToString(grantee.id).split("/").pop() ?? "";
    return `s-gd-grantee-item-id-${prefixValue}${simplifyText(id)}`;
};
/**
 * @internal
 */
export const getGranularGranteeClassNameId = (grantee) => {
    const id = objRefToString(grantee.id).split("/").pop() ?? "";
    return `gd-granular-grantee-item-id-${simplifyText(id)}`;
};
/**
 * @internal
 */
export const getGranularPermissionFromUserPermissions = (userPermissions) => {
    if (userPermissions.canEditAffectedObject || userPermissions.canEditLockedAffectedObject) {
        return "EDIT";
    }
    else if (userPermissions.canShareAffectedObject || userPermissions.canShareLockedAffectedObject) {
        return "SHARE";
    }
    else if (userPermissions.canViewAffectedObject) {
        return "VIEW";
    }
    else {
        return undefined;
    }
};
/**
 * Decide whether specific grantee is the currently logged in user.
 *
 * In some cases, current user might have uriRef instead of idRef or vice versa. This would result in
 * a false negative match. Method conveniently checks also user login to avoid such mismatch.
 *
 * @internal
 */
export const getIsGranteeCurrentUser = (granteeRef, currentUser) => {
    return (areObjRefsEqual(granteeRef, currentUser.ref) || areObjRefsEqual(granteeRef, idRef(currentUser.login)));
};
