import { UmbCurrentUserRepository } from './repository/current-user.repository.js';
import { UMB_CURRENT_USER_CONTEXT } from './current-user.context.token.js';
import { UmbContextBase } from '../../../libs/class-api/index.js';
import { filter, firstValueFrom } from '../../../external/rxjs/index.js';
import { UMB_AUTH_CONTEXT } from '../../core/auth/index.js';
import { UmbObjectState } from '../../../libs/observable-api/index.js';
import { umbLocalizationRegistry } from '../../core/localization/index.js';
export class UmbCurrentUserContext extends UmbContextBase {
    #currentUser;
    #authContext;
    #currentUserRepository;
    constructor(host) {
        super(host, UMB_CURRENT_USER_CONTEXT);
        this.#currentUser = new UmbObjectState(undefined);
        this.currentUser = this.#currentUser.asObservable().pipe(filter((user) => !!user));
        this.allowedSections = this.#currentUser.asObservablePart((user) => user?.allowedSections);
        this.avatarUrls = this.#currentUser.asObservablePart((user) => user?.avatarUrls);
        this.documentStartNodeUniques = this.#currentUser.asObservablePart((user) => user?.documentStartNodeUniques);
        this.email = this.#currentUser.asObservablePart((user) => user?.email);
        this.fallbackPermissions = this.#currentUser.asObservablePart((user) => user?.fallbackPermissions);
        this.hasAccessToAllLanguages = this.#currentUser.asObservablePart((user) => user?.hasAccessToAllLanguages);
        this.hasAccessToSensitiveData = this.#currentUser.asObservablePart((user) => user?.hasAccessToSensitiveData);
        this.hasDocumentRootAccess = this.#currentUser.asObservablePart((user) => user?.hasDocumentRootAccess);
        this.hasMediaRootAccess = this.#currentUser.asObservablePart((user) => user?.hasMediaRootAccess);
        this.isAdmin = this.#currentUser.asObservablePart((user) => user?.isAdmin);
        this.languageIsoCode = this.#currentUser.asObservablePart((user) => user?.languageIsoCode);
        this.languages = this.#currentUser.asObservablePart((user) => user?.languages);
        this.mediaStartNodeUniques = this.#currentUser.asObservablePart((user) => user?.mediaStartNodeUniques);
        this.name = this.#currentUser.asObservablePart((user) => user?.name);
        this.permissions = this.#currentUser.asObservablePart((user) => user?.permissions);
        this.unique = this.#currentUser.asObservablePart((user) => user?.unique);
        this.userName = this.#currentUser.asObservablePart((user) => user?.userName);
        this.#currentUserRepository = new UmbCurrentUserRepository(this);
        this.consumeContext(UMB_AUTH_CONTEXT, (instance) => {
            this.#authContext = instance;
            this.#observeIsAuthorized();
        });
        this.observe(this.languageIsoCode, (currentLanguageIsoCode) => {
            if (!currentLanguageIsoCode)
                return;
            umbLocalizationRegistry.loadLanguage(currentLanguageIsoCode);
        });
    }
    /**
     * Loads the current user
     */
    async load() {
        const { asObservable } = await this.#currentUserRepository.requestCurrentUser();
        if (asObservable) {
            await this.observe(asObservable(), (currentUser) => {
                this.#currentUser?.setValue(currentUser);
            })
                .asPromise()
                // 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);
        }
    }
    /**
     * Checks if a user is the current user.
     * @param userUnique The user id to check
     * @returns True if the user is the current user, otherwise false
     */
    async isUserCurrentUser(userUnique) {
        const currentUser = await firstValueFrom(this.currentUser);
        return currentUser?.unique === userUnique;
    }
    /**
     * Checks if the current user is an admin.
     * @returns True if the current user is an admin, otherwise false
     */
    async isCurrentUserAdmin() {
        const currentUser = await firstValueFrom(this.currentUser);
        return currentUser?.isAdmin ?? false;
    }
    /**
     * Get the allowed sections for the current user
     * @returns {Array<string> | undefined} The allowed sections for the current user
     */
    getAllowedSection() {
        return this.#currentUser.getValue()?.allowedSections;
    }
    /**
     * Get the avatar urls for the current user
     * @returns {Array<string> | undefined} The avatar urls for the current user
     */
    getAvatarUrls() {
        return this.#currentUser.getValue()?.avatarUrls;
    }
    /**
     * Get the document start node uniques for the current user
     * @returns {Array<UmbReferenceByUnique> | undefined} The document start node uniques for the current user
     */
    getDocumentStartNodeUniques() {
        return this.#currentUser.getValue()?.documentStartNodeUniques;
    }
    /**
     * Get the email for the current user
     * @returns {string | undefined} The email for the current user
     */
    getEmail() {
        return this.#currentUser.getValue()?.email;
    }
    /**
     * Get the fallback permissions for the current user
     * @returns {Array<string> | undefined} The fallback permissions for the current user
     */
    getFallbackPermissions() {
        return this.#currentUser.getValue()?.fallbackPermissions;
    }
    /**
     * Get if the current user has access to all languages
     * @returns {boolean | undefined} True if the current user has access to all languages, otherwise false
     */
    getHasAccessToAllLanguages() {
        return this.#currentUser.getValue()?.hasAccessToAllLanguages;
    }
    /**
     * Get if the current user has access to sensitive data
     * @returns {boolean | undefined} True if the current user has access to sensitive data, otherwise false
     */
    getHasAccessToSensitiveData() {
        return this.#currentUser.getValue()?.hasAccessToSensitiveData;
    }
    /**
     * Get if the current user has document root access
     * @returns {boolean | undefined} True if the current user has document root access, otherwise false
     */
    getHasDocumentRootAccess() {
        return this.#currentUser.getValue()?.hasDocumentRootAccess;
    }
    /**
     * Get if the current user has media root access
     * @returns {boolean | undefined} True if the current user has media root access, otherwise false
     */
    getHasMediaRootAccess() {
        return this.#currentUser.getValue()?.hasMediaRootAccess;
    }
    /**
     * Get if the current user is an admin
     * @returns {boolean | undefined} True if the current user is an admin, otherwise false
     */
    getIsAdmin() {
        return this.#currentUser.getValue()?.isAdmin;
    }
    /**
     * Get the language iso code for the current user
     * @returns {string | undefined} The language iso code for the current user
     */
    getLanguageIsoCode() {
        return this.#currentUser.getValue()?.languageIsoCode;
    }
    /**
     * Get the languages for the current user
     * @returns {Array<string> | undefined} The languages for the current user
     */
    getLanguages() {
        return this.#currentUser.getValue()?.languages;
    }
    /**
     * Get the media start node uniques for the current user
     * @returns {Array<UmbReferenceByUnique> | undefined} The media start node uniques for the current user
     */
    getMediaStartNodeUniques() {
        return this.#currentUser.getValue()?.mediaStartNodeUniques;
    }
    /**
     * Get the name for the current user
     * @returns {string | undefined} The name for the current user
     */
    getName() {
        return this.#currentUser.getValue()?.name;
    }
    /**
     * Get the permissions for the current user
     * @returns {unknown[] | undefined} The permissions for the current user
     */
    getPermissions() {
        return this.#currentUser.getValue()?.permissions;
    }
    /**
     * Get the unique for the current user
     * @returns {string | undefined} The unique for the current user
     */
    getUnique() {
        return this.#currentUser.getValue()?.unique;
    }
    /**
     * Get the user name for the current user
     * @returns {string | undefined} The user name for the current user
     */
    getUserName() {
        return this.#currentUser.getValue()?.userName;
    }
    #observeIsAuthorized() {
        if (!this.#authContext)
            return;
        this.observe(this.#authContext.isAuthorized, (isAuthorized) => {
            if (isAuthorized) {
                this.load();
            }
        });
    }
}
export default UmbCurrentUserContext;
