import { UserService } from '../../../core/backend-api/index.js';
import { UmbControllerBase } from '../../../../libs/class-api/index.js';
import { UmbManagementApiDataMapper } from '../../../core/repository/index.js';
import { tryExecute } from '../../../core/resources/index.js';
/**
 * A data source for the current user that fetches data from the server
 * @class UmbCurrentUserServerDataSource
 */
export class UmbCurrentUserServerDataSource extends UmbControllerBase {
    #dataMapper = new UmbManagementApiDataMapper(this);
    /**
     * Get the current user
     * @returns {*}
     * @memberof UmbCurrentUserServerDataSource
     */
    async getCurrentUser() {
        const { data, error } = await tryExecute(this, UserService.getUserCurrent());
        if (data) {
            const permissionDataPromises = data.permissions.map(async (item) => {
                return this.#dataMapper.map({
                    forDataModel: item.$type,
                    data: item,
                    fallback: async () => {
                        return {
                            ...item,
                            permissionType: 'unknown',
                        };
                    },
                });
            });
            const permissions = await Promise.all(permissionDataPromises);
            const user = {
                allowedSections: data.allowedSections,
                avatarUrls: data.avatarUrls,
                documentStartNodeUniques: data.documentStartNodeIds.map((node) => {
                    return {
                        unique: node.id,
                    };
                }),
                email: data.email,
                fallbackPermissions: data.fallbackPermissions,
                hasAccessToAllLanguages: data.hasAccessToAllLanguages,
                hasAccessToSensitiveData: data.hasAccessToSensitiveData,
                hasDocumentRootAccess: data.hasDocumentRootAccess,
                hasMediaRootAccess: data.hasMediaRootAccess,
                isAdmin: data.isAdmin,
                languageIsoCode: data.languageIsoCode || 'en-us', // TODO: make global variable
                languages: data.languages,
                mediaStartNodeUniques: data.mediaStartNodeIds.map((node) => {
                    return {
                        unique: node.id,
                    };
                }),
                name: data.name,
                permissions,
                unique: data.id,
                userName: data.userName,
                userGroupUniques: data.userGroupIds.map((group) => group.id),
            };
            return { data: user };
        }
        return { error };
    }
    /**
     * Get the current user's external login providers
     * @memberof UmbCurrentUserServerDataSource
     */
    async getExternalLoginProviders() {
        return tryExecute(this, UserService.getUserCurrentLoginProviders());
    }
    /**
     * Get the current user's available MFA login providers
     * @memberof UmbCurrentUserServerDataSource
     */
    async getMfaLoginProviders() {
        const { data, error } = await tryExecute(this, UserService.getUserCurrent2Fa());
        if (data) {
            return { data };
        }
        return { error };
    }
    /**
     * Enable an MFA provider
     * @param providerName
     * @param code
     * @param secret
     */
    async enableMfaProvider(providerName, code, secret) {
        const { error } = await tryExecute(this, UserService.postUserCurrent2FaByProviderName({ path: { providerName }, body: { code, secret } }));
        if (error) {
            return { error };
        }
        return {};
    }
    /**
     * Disable an MFA provider
     * @param providerName
     * @param code
     */
    async disableMfaProvider(providerName, code) {
        const { error } = await tryExecute(this, UserService.deleteUserCurrent2FaByProviderName({ path: { providerName }, query: { code } }));
        if (error) {
            return { error };
        }
        return {};
    }
    /**
     * Change the password for current user
     * @param id
     * @param newPassword
     * @param oldPassword
     * @param isCurrentUser
     * @returns
     */
    async changePassword(newPassword, oldPassword) {
        return tryExecute(this, UserService.postUserCurrentChangePassword({
            body: {
                newPassword,
                oldPassword,
            },
        }), { disableNotifications: true });
    }
}
