import { getApiErrorMessage } from '../../clients/error-utils.js';
/**
 * Valid access-key scopes accepted by the Data API
 * `/users/{login}/access_key/{scope}` endpoints.
 */
export const ACCESS_KEY_SCOPES = ['WEBDAV_AND_STUDIO', 'AGENT_USER_AND_OCAPI', 'STOREFRONT'];
/**
 * Lists all users on a B2C Commerce instance.
 *
 * @param instance - B2C instance to query
 * @param options - Pagination options
 * @returns Users collection with pagination info
 */
export async function listBmUsers(instance, options = {}) {
    const { start, count, select } = options;
    const { data, error, response } = await instance.ocapi.GET('/users', {
        params: { query: { start, count, select: select ?? '(**)' } },
    });
    if (error) {
        throw new Error(`Failed to list users: ${getApiErrorMessage(error, response)}`, { cause: error });
    }
    return data;
}
/**
 * Gets a single user by login (email).
 *
 * @param instance - B2C instance
 * @param login - User login
 * @returns User details
 */
export async function getBmUser(instance, login) {
    const { data, error, response } = await instance.ocapi.GET('/users/{login}', {
        params: { path: { login } },
    });
    if (error) {
        throw new Error(`Failed to get user ${login}: ${getApiErrorMessage(error, response)}`, { cause: error });
    }
    return data;
}
/**
 * Returns details for the currently authenticated user (the user the OAuth token resolves to).
 *
 * Useful for verifying which BM identity is in use on an instance.
 *
 * @param instance - B2C instance
 * @returns Current user details (includes password expiration info)
 */
export async function whoamiBmUser(instance) {
    const { data, error, response } = await instance.ocapi.GET('/users/this');
    if (error) {
        throw new Error(`Failed to get current user: ${getApiErrorMessage(error, response)}`, { cause: error });
    }
    return data;
}
/**
 * Updates an existing user. The `locked` flag and the user `password` cannot be updated
 * with this resource.
 *
 * @param instance - B2C instance
 * @param login - User login
 * @param changes - Fields to update
 * @returns Updated user
 */
export async function updateBmUser(instance, login, changes) {
    const { data, error, response } = await instance.ocapi.PATCH('/users/{login}', {
        params: { path: { login } },
        body: changes,
    });
    if (error) {
        throw new Error(`Failed to update user ${login}: ${getApiErrorMessage(error, response)}`, { cause: error });
    }
    return data;
}
/**
 * Deletes a user from an instance.
 *
 * @param instance - B2C instance
 * @param login - User login
 */
export async function deleteBmUser(instance, login) {
    const { error, response } = await instance.ocapi.DELETE('/users/{login}', {
        params: { path: { login } },
    });
    if (error) {
        throw new Error(`Failed to delete user ${login}: ${getApiErrorMessage(error, response)}`, { cause: error });
    }
}
/**
 * Searches users on an instance.
 *
 * Supports either a fully-formed OCAPI query (`options.query`) or convenience flags
 * (`searchPhrase`, `login`, `email`, `locked`, `disabled`) which are combined into a
 * `bool_query`. If no criteria are provided a `match_all_query` is used.
 *
 * @param instance - B2C instance
 * @param options - Search options
 * @returns User search result
 */
export async function searchBmUsers(instance, options = {}) {
    const { query: providedQuery, searchPhrase, login, email, locked, disabled, sortBy, sortOrder, start, count, select, } = options;
    let query = providedQuery;
    if (!query) {
        const queries = [];
        if (searchPhrase) {
            queries.push({
                text_query: {
                    fields: ['login', 'email', 'first_name', 'last_name'],
                    search_phrase: searchPhrase,
                },
            });
        }
        if (login) {
            queries.push({ term_query: { fields: ['login'], operator: 'is', values: [login] } });
        }
        if (email) {
            queries.push({ term_query: { fields: ['email'], operator: 'is', values: [email] } });
        }
        if (locked !== undefined) {
            queries.push({ term_query: { fields: ['is_locked'], operator: 'is', values: [locked] } });
        }
        if (disabled !== undefined) {
            queries.push({ term_query: { fields: ['is_disabled'], operator: 'is', values: [disabled] } });
        }
        if (queries.length === 0) {
            query = { match_all_query: {} };
        }
        else if (queries.length === 1) {
            query = queries[0];
        }
        else {
            query = { bool_query: { must: queries } };
        }
    }
    const sorts = sortBy ? [{ field: sortBy, sort_order: sortOrder ?? 'asc' }] : undefined;
    const { data, error, response } = await instance.ocapi.POST('/user_search', {
        body: {
            query,
            start,
            count,
            sorts,
            select: select ?? '(**)',
        },
    });
    if (error) {
        throw new Error(`Failed to search users: ${getApiErrorMessage(error, response)}`, { cause: error });
    }
    return data;
}
/**
 * Gets a single access key for an externally-managed user.
 *
 * @param instance - B2C instance
 * @param login - User login
 * @param scope - Access key scope (one of {@link ACCESS_KEY_SCOPES})
 * @returns Access key details
 */
export async function getBmUserAccessKey(instance, login, scope) {
    const { data, error, response } = await instance.ocapi.GET('/users/{login}/access_key/{scope}', {
        params: { path: { login, scope } },
    });
    if (error) {
        throw new Error(`Failed to get access key (${scope}) for ${login}: ${getApiErrorMessage(error, response)}`, {
            cause: error,
        });
    }
    return data;
}
/**
 * Creates a single access key for an externally-managed user (replaces any existing key
 * for the same scope).
 *
 * The returned object includes the newly-generated `access_key` value — this is the only
 * time it is returned, so callers should record it.
 *
 * @param instance - B2C instance
 * @param login - User login
 * @param scope - Access key scope
 * @returns Access key details (including the secret `access_key` value)
 */
export async function createBmUserAccessKey(instance, login, scope) {
    const { data, error, response } = await instance.ocapi.PUT('/users/{login}/access_key/{scope}', {
        params: { path: { login, scope } },
    });
    if (error) {
        throw new Error(`Failed to create access key (${scope}) for ${login}: ${getApiErrorMessage(error, response)}`, {
            cause: error,
        });
    }
    return data;
}
/**
 * Enables or disables an existing access key for an externally-managed user.
 *
 * @param instance - B2C instance
 * @param login - User login
 * @param scope - Access key scope
 * @param enabled - Whether the access key should be enabled
 * @returns Updated access key details
 */
export async function setBmUserAccessKeyEnabled(instance, login, scope, enabled) {
    const { data, error, response } = await instance.ocapi.PATCH('/users/{login}/access_key/{scope}', {
        params: { path: { login, scope } },
        body: { enabled },
    });
    if (error) {
        throw new Error(`Failed to update access key (${scope}) for ${login}: ${getApiErrorMessage(error, response)}`, {
            cause: error,
        });
    }
    return data;
}
/**
 * Deletes a single access key for an externally-managed user.
 *
 * @param instance - B2C instance
 * @param login - User login
 * @param scope - Access key scope
 */
export async function deleteBmUserAccessKey(instance, login, scope) {
    const { error, response } = await instance.ocapi.DELETE('/users/{login}/access_key/{scope}', {
        params: { path: { login, scope } },
    });
    if (error) {
        throw new Error(`Failed to delete access key (${scope}) for ${login}: ${getApiErrorMessage(error, response)}`, {
            cause: error,
        });
    }
}
//# sourceMappingURL=users.js.map