import { LogError, LogStatus, Metadata, RunView } from "@memberjunction/core";
import { UserCache } from "@memberjunction/sqlserver-dataprovider";
import { configInfo } from "../config.js";
export class NewUserBase {
    async createNewUser(firstName, lastName, email, linkedRecordType = 'None', linkedEntityId, linkedEntityRecordId) {
        try {
            let contextUser = null;
            const contextUserForNewUserCreation = configInfo?.userHandling?.contextUserForNewUserCreation;
            if (contextUserForNewUserCreation) {
                contextUser = UserCache.Instance.UserByName(contextUserForNewUserCreation);
            }
            if (!contextUser) {
                LogError(`Failed to load context user ${configInfo?.userHandling?.contextUserForNewUserCreation}, using an existing user with the Owner role instead`);
                contextUser = UserCache.Users.find(user => user.Type.trim().toLowerCase() === 'owner');
                if (!contextUser) {
                    LogError(`No existing users found in the database with the Owner role, cannot create a new user`);
                    return null;
                }
            }
            const md = new Metadata();
            const user = await md.GetEntityObject('Users', contextUser);
            user.NewRecord();
            user.Name = email;
            user.IsActive = true;
            user.FirstName = firstName;
            user.LastName = lastName;
            user.Email = email;
            user.Type = 'User';
            user.LinkedRecordType = linkedRecordType;
            if (linkedEntityId) {
                user.LinkedEntityID = linkedEntityId;
            }
            if (linkedEntityRecordId) {
                user.LinkedEntityRecordID = linkedEntityRecordId;
            }
            const saveResult = await user.Save();
            if (!saveResult) {
                LogError(`Failed to create new user ${firstName} ${lastName} ${email}:`, undefined, user.LatestResult);
                return null;
            }
            if (configInfo.userHandling && configInfo.userHandling.newUserRoles) {
                LogStatus(`User ${user.Email} created, assigning roles`);
                for (const role of configInfo.userHandling.newUserRoles) {
                    const userRoleEntity = await md.GetEntityObject('User Roles', contextUser);
                    userRoleEntity.NewRecord();
                    userRoleEntity.UserID = user.ID;
                    const userRole = md.Roles.find(r => r.Name === role);
                    if (!userRole) {
                        LogError(`Role ${role} not found in the database, cannot assign to new user ${user.Name}`);
                        continue;
                    }
                    userRoleEntity.RoleID = userRole.ID;
                    const roleSaveResult = await userRoleEntity.Save();
                    if (roleSaveResult) {
                        LogStatus(`Assigned role ${role} to new user ${user.Name}`);
                    }
                    else {
                        LogError(`Failed to assign role ${role} to new user ${user.Name}:`, undefined, userRoleEntity.LatestResult);
                    }
                }
            }
            if (configInfo.userHandling && configInfo.userHandling.CreateUserApplicationRecords) {
                LogStatus("Creating User Applications for new user: " + user.Name);
                let applicationsToCreate = [];
                if (configInfo.userHandling.UserApplications && configInfo.userHandling.UserApplications.length > 0) {
                    for (const appName of configInfo.userHandling.UserApplications) {
                        const toLowerCase = appName.trim().toLocaleLowerCase();
                        const application = md.Applications.find(a => a.Name.trim().toLocaleLowerCase() === toLowerCase);
                        if (application) {
                            applicationsToCreate.push(application);
                        }
                        else {
                            LogError(`Application ${appName} not found in the Metadata, cannot assign to new user ${user.Name}`);
                        }
                    }
                }
                else {
                    LogStatus(`No UserApplications configured, using DefaultForNewUser applications for new user ${user.Name}`);
                    applicationsToCreate = md.Applications.filter(a => a.DefaultForNewUser);
                    LogStatus(`Found ${applicationsToCreate.length} applications with DefaultForNewUser=true`);
                }
                for (const [appIndex, application] of applicationsToCreate.entries()) {
                    const userApplication = await md.GetEntityObject('User Applications', contextUser);
                    userApplication.NewRecord();
                    userApplication.UserID = user.ID;
                    userApplication.ApplicationID = application.ID;
                    userApplication.Sequence = appIndex;
                    userApplication.IsActive = true;
                    const userApplicationSaveResult = await userApplication.Save();
                    if (userApplicationSaveResult) {
                        LogStatus(`Created User Application ${application.Name} for new user ${user.Name}`);
                        const rv = new RunView();
                        const rvResult = await rv.RunView({
                            EntityName: 'Application Entities',
                            ExtraFilter: `ApplicationID = '${application.ID}' and DefaultForNewUser = 1`,
                        }, contextUser);
                        if (!rvResult.Success) {
                            LogError(`Failed to load Application Entities for Application ${application.Name} for new user ${user.Name}:`, undefined, rvResult.ErrorMessage);
                            continue;
                        }
                        LogStatus(`Creating ${rvResult.Results.length} User Application Entities for User Application ${application.Name} for new user ${user.Name}`);
                        for (const [index, appEntity] of rvResult.Results.entries()) {
                            const userAppEntity = await md.GetEntityObject('User Application Entities', contextUser);
                            userAppEntity.NewRecord();
                            userAppEntity.UserApplicationID = userApplication.ID;
                            userAppEntity.EntityID = appEntity.EntityID;
                            userAppEntity.Sequence = index;
                            const userAppEntitySaveResult = await userAppEntity.Save();
                            if (userAppEntitySaveResult) {
                                LogStatus(`Created User Application Entity ${appEntity.Entity} for new user ${user.Name}`);
                            }
                            else {
                                LogError(`Failed to create User Application Entity for new user ${user.Name}:`, undefined, userAppEntity.LatestResult);
                            }
                        }
                    }
                    else {
                        LogError(`Failed to create User Application ${application.Name} for new user ${user.Name}:`, undefined, userApplication.LatestResult);
                    }
                }
            }
            return user;
        }
        catch (e) {
            LogError(e);
            return undefined;
        }
    }
}
//# sourceMappingURL=newUsers.js.map