import React__default, { useMemo, useCallback } from 'react';
import { deepEqual } from '../../utils/deepEqual.mjs';
import { Autocomplete } from '../components/Autocomplete.mjs';
import { Button } from '../components/Button.mjs';
import { FlexBox } from '../shared/components/FlexBox.mjs';
import { Input } from '../components/Input.mjs';
import { RolesList } from '../components/RolesList.mjs';
import { SettingsContainer, useSettingsContainer } from '../components/SettingsContainer.mjs';
import { SettingsSection } from '../components/SettingsSection.mjs';
import { Table } from '../components/Table.mjs';
import { Typography } from '../components/Typography.mjs';
import { getSsoConnectionRoleAssignments, getSsoGroupRoleAssignments } from '../utils/getSsoRoleAssignments.mjs';
import { useFormState } from '../utils/useFormState.mjs';
import { useMutateSsoConnection } from '../utils/useMutateSsoConnection.mjs';
import { useRbac } from '../utils/useRbac.mjs';
import { useRoleAutocomplete } from '../utils/useRoleAutocomplete.mjs';
import { getIdpInfo } from './IdpInfo.mjs';
import { useSsoRouterController } from './SSORouter.mjs';
import Add from '../../../../../node_modules/@mui/icons-material/esm/Add.mjs';

const RoleAssignmentsSectionBody = ({ connection, localState, setLocalState, remoteState })=>{
    const { editing } = useSettingsContainer();
    const { data: canGetOrgCustomRoles } = useRbac('stytch.custom-org-roles', 'get');
    const { connectionRoleIds, groupedRoles } = editing ? localState : remoteState;
    const connectionNeedsGroupAttributeMapping = connection.connectionType === 'saml' && !connection.attribute_mapping.groups;
    const roleAutocompleteProps = useRoleAutocomplete({
        includeOrgRoles: canGetOrgCustomRoles ?? false
    });
    const handleAddGroupRole = useCallback(()=>{
        setLocalState((state)=>({
                ...state,
                groupedRoles: [
                    ...state.groupedRoles,
                    {
                        group: '',
                        roleIds: []
                    }
                ]
            }));
    }, [
        setLocalState
    ]);
    const handleConnectionRolesChange = useCallback((value)=>{
        return setLocalState((state)=>({
                ...state,
                connectionRoleIds: value
            }));
    }, [
        setLocalState
    ]);
    const idpInfo = connection.connectionType === 'saml' ? getIdpInfo(connection.identity_provider, 'saml') : undefined;
    const implicitRoleAssignments = connection.connectionType === 'saml' ? connection.saml_connection_implicit_role_assignments : connection.external_connection_implicit_role_assignments;
    return /*#__PURE__*/ React__default.createElement(FlexBox, {
        flexDirection: "column",
        gap: 2
    }, /*#__PURE__*/ React__default.createElement(SettingsSection, {
        title: "Connection Roles",
        tooltipText: "Connection Roles are automatically assigned to all Members who authenticate via this SSO connection."
    }, editing ? /*#__PURE__*/ React__default.createElement(Autocomplete, {
        ...roleAutocompleteProps,
        value: connectionRoleIds,
        onChange: handleConnectionRolesChange
    }) : implicitRoleAssignments.length > 0 ? /*#__PURE__*/ React__default.createElement(RolesList, {
        roles: implicitRoleAssignments
    }) : /*#__PURE__*/ React__default.createElement(Typography, {
        variant: "body2"
    }, "No roles assigned.")), /*#__PURE__*/ React__default.createElement(SettingsSection, {
        title: "Group Roles",
        tooltipText: "If a Member is part of a group, they will be assigned both the Connection Role and their Group Role."
    }, connection.connectionType === 'external' && /*#__PURE__*/ React__default.createElement(Typography, {
        variant: "body2"
    }, 'Ensure a "groups" key exists in the external connection Attribute Mapping first to assign group roles.'), !connectionNeedsGroupAttributeMapping ? editing ? /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, groupedRoles.map(({ group, roleIds }, i)=>/*#__PURE__*/ React__default.createElement(FlexBox, {
            key: i,
            alignItems: "stretch",
            justifyContent: "space-between"
        }, /*#__PURE__*/ React__default.createElement(Input, {
            label: "Group name",
            fullWidth: true,
            value: group,
            onChange: (value)=>{
                setLocalState((state)=>({
                        ...state,
                        groupedRoles: state.groupedRoles.map((item, index)=>index === i ? {
                                ...item,
                                group: value
                            } : item)
                    }));
            }
        }), /*#__PURE__*/ React__default.createElement(Autocomplete, {
            ...roleAutocompleteProps,
            label: "Group Role",
            value: roleIds,
            fullWidth: true,
            onChange: (values)=>{
                setLocalState((state)=>({
                        ...state,
                        groupedRoles: state.groupedRoles.map((item, index)=>index === i ? {
                                ...item,
                                roleIds: values
                            } : item)
                    }));
            }
        }))), /*#__PURE__*/ React__default.createElement(Button, {
        variant: "text",
        startIcon: /*#__PURE__*/ React__default.createElement(Add, null),
        onClick: handleAddGroupRole
    }, "Add group roles")) : groupedRoles.length > 0 ? /*#__PURE__*/ React__default.createElement(Table, {
        items: groupedRoles,
        rowKeyExtractor: roleAssignmentKeyExtractor,
        itemRenderer: roleAssignmentItemRenderer
    }) : /*#__PURE__*/ React__default.createElement(Typography, {
        variant: "body2"
    }, "No roles assigned.") : idpInfo && /*#__PURE__*/ React__default.createElement(Typography, {
        variant: "body2"
    }, 'Add a "groups" key in the ', idpInfo.idp.attributeMappingLabel, " first to assign group roles.")));
};
const roleAssignmentKeyExtractor = ({ group })=>group;
const roleAssignmentItemRenderer = [
    {
        title: 'Group',
        getValue: ({ group })=>/*#__PURE__*/ React__default.createElement(Typography, {
                variant: "body2",
                color: "secondary"
            }, group)
    },
    {
        title: 'Role',
        getValue: ({ roleIds })=>/*#__PURE__*/ React__default.createElement(RolesList, {
                roles: roleIds
            })
    }
];
const RoleAssignmentsSection = ({ canUpdateConnection, connection })=>{
    const implicitRoleAssignments = getSsoConnectionRoleAssignments(connection);
    const implicitGroupAssignments = getSsoGroupRoleAssignments(connection);
    const connectionRoleIds = useMemo(()=>implicitRoleAssignments.map(({ role_id })=>role_id), [
        implicitRoleAssignments
    ]);
    const groupedRoles = useMemo(()=>{
        return Object.values(implicitGroupAssignments.reduce((acc, { group, role_id })=>{
            if (!acc[group]) {
                acc[group] = {
                    group,
                    roleIds: []
                };
            }
            acc[group].roleIds.push(role_id);
            return acc;
        }, {}));
    }, [
        implicitGroupAssignments
    ]);
    const remoteState = useMemo(()=>({
            connectionRoleIds,
            groupedRoles
        }), [
        connectionRoleIds,
        groupedRoles
    ]);
    const { localState, setLocalState, editing, handleSetEditing } = useFormState({
        remoteState
    });
    const { mutate } = useMutateSsoConnection(connection.connectionType);
    const handleSave = useCallback(async ()=>{
        const baseOptions = {
            connection_id: connection.connection_id
        };
        const implicitRoleAssignments = !deepEqual(remoteState.connectionRoleIds, localState.connectionRoleIds) ? localState.connectionRoleIds.map((role_id)=>({
                role_id
            })) : undefined;
        const filteredGroupRoles = localState.groupedRoles.filter(({ group, roleIds })=>group && roleIds.length > 0);
        const implicitGroupAssignments = !deepEqual(remoteState.groupedRoles, filteredGroupRoles) ? filteredGroupRoles.flatMap(({ group, roleIds })=>roleIds.map((role_id)=>({
                    group,
                    role_id
                }))) : undefined;
        if (connection.connectionType === 'saml') {
            const mutatedProperties = {
                ...implicitRoleAssignments && {
                    saml_connection_implicit_role_assignments: implicitRoleAssignments
                },
                ...implicitGroupAssignments && {
                    saml_group_implicit_role_assignments: implicitGroupAssignments
                }
            };
            if (Object.keys(mutatedProperties).length > 0) {
                return mutate({
                    ...baseOptions,
                    ...mutatedProperties
                }, {
                    errorMessage: 'Failed to update role assignments.'
                });
            }
        } else {
            const mutatedProperties = {
                ...implicitRoleAssignments && {
                    external_connection_implicit_role_assignments: implicitRoleAssignments
                },
                ...implicitGroupAssignments && {
                    external_group_implicit_role_assignments: implicitGroupAssignments
                }
            };
            if (Object.keys(mutatedProperties).length > 0) {
                return mutate({
                    ...baseOptions,
                    ...mutatedProperties
                }, {
                    errorMessage: 'Failed to update role assignments.'
                });
            }
        }
        return Promise.resolve();
    }, [
        connection.connectionType,
        connection.connection_id,
        localState.connectionRoleIds,
        localState.groupedRoles,
        mutate,
        remoteState.connectionRoleIds,
        remoteState.groupedRoles
    ]);
    const { useBlockNavigation } = useSsoRouterController();
    return /*#__PURE__*/ React__default.createElement(SettingsContainer, {
        title: "Role assignments",
        hasCTA: canUpdateConnection,
        onSave: handleSave,
        useBlockNavigation: useBlockNavigation,
        editing: editing,
        setEditing: handleSetEditing
    }, /*#__PURE__*/ React__default.createElement(RoleAssignmentsSectionBody, {
        connection: connection,
        localState: localState,
        remoteState: remoteState,
        setLocalState: setLocalState
    }));
};

export { RoleAssignmentsSection };
//# sourceMappingURL=RoleAssignmentsSection.mjs.map
