import { UMB_USER_GROUP_ENTITY_TYPE } from '../../entity.js';
import { UserGroupService } from '../../../../core/backend-api/index.js';
import { UmbId } from '../../../../core/id/index.js';
import { UmbManagementApiDataMapper } from '../../../../core/repository/index.js';
import { UmbControllerBase } from '../../../../../libs/class-api/index.js';
import { tryExecute } from '../../../../core/resources/index.js';
/**
 * A data source for the User Group that fetches data from the server
 * @class UmbUserGroupServerDataSource
 * @implements {RepositoryDetailDataSource}
 */
export class UmbUserGroupServerDataSource extends UmbControllerBase {
    #dataMapper = new UmbManagementApiDataMapper(this);
    /**
     * Creates a new User Group scaffold
     * @param {(string | null)} parentUnique
     * @returns { CreateUserGroupRequestModel }
     * @memberof UmbUserGroupServerDataSource
     */
    async createScaffold() {
        const data = {
            alias: '',
            aliasCanBeChanged: true,
            documentRootAccess: false,
            documentStartNode: null,
            entityType: UMB_USER_GROUP_ENTITY_TYPE,
            fallbackPermissions: [],
            hasAccessToAllLanguages: false,
            icon: 'icon-users',
            isDeletable: true,
            languages: [],
            mediaRootAccess: false,
            mediaStartNode: null,
            name: '',
            permissions: [],
            sections: [],
            unique: UmbId.new(),
            description: '',
        };
        return { data };
    }
    /**
     * Fetches a User Group with the given id from the server
     * @param {string} unique
     * @returns {*}
     * @memberof UmbUserGroupServerDataSource
     */
    async read(unique) {
        if (!unique)
            throw new Error('Unique is missing');
        const { data, error } = await tryExecute(this, UserGroupService.getUserGroupById({ path: { id: unique } }));
        if (error || !data) {
            return { error };
        }
        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);
        // TODO: make data mapper to prevent errors
        const userGroup = {
            alias: data.alias,
            documentRootAccess: data.documentRootAccess,
            documentStartNode: data.documentStartNode ? { unique: data.documentStartNode.id } : null,
            entityType: UMB_USER_GROUP_ENTITY_TYPE,
            fallbackPermissions: data.fallbackPermissions,
            hasAccessToAllLanguages: data.hasAccessToAllLanguages,
            icon: data.icon || null,
            isDeletable: data.isDeletable,
            aliasCanBeChanged: data.aliasCanBeChanged,
            languages: data.languages,
            mediaRootAccess: data.mediaRootAccess,
            mediaStartNode: data.mediaStartNode ? { unique: data.mediaStartNode.id } : null,
            name: data.name,
            permissions,
            sections: data.sections,
            unique: data.id,
            description: data.description ?? null,
        };
        return { data: userGroup };
    }
    /**
     * Inserts a new User Group on the server
     * @param {UmbUserGroupDetailModel} model
     * @returns {*}
     * @memberof UmbUserGroupServerDataSource
     */
    async create(model) {
        if (!model)
            throw new Error('User Group is missing');
        const permissionDataPromises = model.permissions.map(async (item) => {
            return this.#dataMapper.map({
                forDataModel: item.permissionType,
                data: item,
                fallback: async () => item,
            });
        });
        const permissions = await Promise.all(permissionDataPromises);
        // TODO: make data mapper to prevent errors
        const body = {
            alias: model.alias,
            documentRootAccess: model.documentRootAccess,
            documentStartNode: model.documentStartNode ? { id: model.documentStartNode.unique } : null,
            fallbackPermissions: model.fallbackPermissions,
            hasAccessToAllLanguages: model.hasAccessToAllLanguages,
            icon: model.icon,
            languages: model.languages,
            mediaRootAccess: model.mediaRootAccess,
            mediaStartNode: model.mediaStartNode ? { id: model.mediaStartNode.unique } : null,
            name: model.name,
            permissions,
            sections: model.sections,
            description: model.description,
        };
        const { data, error } = await tryExecute(this, UserGroupService.postUserGroup({
            body,
        }));
        if (data) {
            return this.read(data);
        }
        return { error };
    }
    /**
     * Updates a UserGroup on the server
     * @param {UmbUserGroupDetailModel} UserGroup
     * @param model
     * @returns {*}
     * @memberof UmbUserGroupServerDataSource
     */
    async update(model) {
        if (!model.unique)
            throw new Error('Unique is missing');
        const permissionDataPromises = model.permissions.map(async (item) => {
            return this.#dataMapper.map({
                forDataModel: item.userPermissionType,
                data: item,
                fallback: async () => item,
            });
        });
        const permissions = await Promise.all(permissionDataPromises);
        // TODO: make data mapper to prevent errors
        const body = {
            alias: model.alias,
            documentRootAccess: model.documentRootAccess,
            documentStartNode: model.documentStartNode ? { id: model.documentStartNode.unique } : null,
            fallbackPermissions: model.fallbackPermissions,
            hasAccessToAllLanguages: model.hasAccessToAllLanguages,
            icon: model.icon,
            languages: model.languages,
            mediaRootAccess: model.mediaRootAccess,
            mediaStartNode: model.mediaStartNode ? { id: model.mediaStartNode.unique } : null,
            name: model.name,
            permissions,
            sections: model.sections,
            description: model.description,
        };
        const { error } = await tryExecute(this, UserGroupService.putUserGroupById({
            path: { id: model.unique },
            body,
        }));
        if (!error) {
            return this.read(model.unique);
        }
        return { error };
    }
    /**
     * Deletes a User Group on the server
     * @param {string} unique
     * @returns {*}
     * @memberof UmbUserGroupServerDataSource
     */
    async delete(unique) {
        if (!unique)
            throw new Error('Unique is missing');
        return tryExecute(this, UserGroupService.deleteUserGroupById({
            path: { id: unique },
        }));
    }
}
