import { UmbCurrentUserServerDataSource } from './current-user.server.data-source.js';
import { UMB_CURRENT_USER_STORE_CONTEXT } from './current-user.store.token.js';
import { UmbRepositoryBase } from '../../../core/repository/index.js';
import { UMB_NOTIFICATION_CONTEXT } from '../../../core/notification/index.js';
/**
 * A repository for the current user
 * @class UmbCurrentUserRepository
 * @augments {UmbRepositoryBase}
 */
export class UmbCurrentUserRepository extends UmbRepositoryBase {
    #currentUserSource = new UmbCurrentUserServerDataSource(this._host);
    #currentUserStore;
    #init;
    constructor(host) {
        super(host);
        this.#init = Promise.all([
            this.consumeContext(UMB_CURRENT_USER_STORE_CONTEXT, (instance) => {
                if (instance) {
                    this.#currentUserStore = instance;
                }
            })
                .asPromise({ preventTimeout: true })
                // Ignore the error, we can assume that the flow was stopped (asPromise failed), but it does not mean that the consumption was not successful.
                .catch(() => undefined),
            this.consumeContext(UMB_NOTIFICATION_CONTEXT, (instance) => {
                this.notificationContext = instance;
            })
                .asPromise({ preventTimeout: true })
                .catch(() => undefined),
        ]);
    }
    /**
     * Request the current user
     * @returns {*}
     * @memberof UmbCurrentUserRepository
     */
    async requestCurrentUser() {
        await this.#init;
        const { data, error } = await this.#currentUserSource.getCurrentUser();
        if (data) {
            this.#currentUserStore?.set(data);
        }
        return { data, error, asObservable: () => this.#currentUserStore.data };
    }
    /**
     * Request the current user's external login providers
     * @memberof UmbCurrentUserRepository
     */
    async requestExternalLoginProviders() {
        await this.#init;
        const { data, error } = await this.#currentUserSource.getExternalLoginProviders();
        if (data) {
            this.#currentUserStore?.setExternalLoginProviders(data);
        }
        return { data, error, asObservable: () => this.#currentUserStore.externalLoginProviders };
    }
    /**
     * Request the current user's available MFA login providers
     * @memberof UmbCurrentUserRepository
     */
    async requestMfaLoginProviders() {
        await this.#init;
        const { data, error } = await this.#currentUserSource.getMfaLoginProviders();
        if (data) {
            this.#currentUserStore?.setMfaProviders(data);
        }
        return { data, error, asObservable: () => this.#currentUserStore.mfaProviders };
    }
    /**
     * Enable an MFA provider
     * @param provider The provider to enable
     * @param providerName
     * @param code The activation code of the provider to enable
     * @param secret
     * @memberof UmbCurrentUserRepository
     */
    async enableMfaProvider(providerName, code, secret) {
        const { error } = await this.#currentUserSource.enableMfaProvider(providerName, code, secret);
        if (error) {
            return { error };
        }
        this.#currentUserStore?.updateMfaProvider({ providerName, isEnabledOnUser: true });
        return {};
    }
    /**
     * Disable an MFA provider
     * @param provider The provider to disable
     * @param providerName
     * @param code The activation code of the provider to disable
     * @memberof UmbCurrentUserRepository
     */
    async disableMfaProvider(providerName, code) {
        const { error } = await this.#currentUserSource.disableMfaProvider(providerName, code);
        if (error) {
            return { error };
        }
        this.#currentUserStore?.updateMfaProvider({ providerName, isEnabledOnUser: false });
        return {};
    }
    /**
     * Change password for current user
     * @param userId
     * @param newPassword
     * @param oldPassword
     * @param isCurrentUser
     * @returns
     */
    async changePassword(newPassword, oldPassword) {
        if (!newPassword)
            throw new Error('New password is missing');
        if (!oldPassword)
            throw new Error('Old password is missing');
        const { data, error } = await this.#currentUserSource.changePassword(newPassword, oldPassword);
        if (!error) {
            const notification = { data: { message: `Password changed` } };
            this.notificationContext?.peek('positive', notification);
        }
        else {
            const notification = { data: { message: error.message ?? 'Unknown failure' } };
            this.notificationContext?.peek('danger', notification);
        }
        return { data, error };
    }
}
export default UmbCurrentUserRepository;
