// https://docs.authing.co/v2/reference/sdk-for-node/management/UsersManagementClient.html
const { ManagementClient } = require('authing-node-sdk')
const managementClient  = new ManagementClient({
    accessKeyId: '669b25e1731d50c59f5494d1',
    accessKeySecret: "4cfc095a72a67e22065c97e90054315c",
    host: 'https://textbook.u2-dev.hep.com.cn', // 应用的认证地址
})


/**
 * 用户创建前，创建用户至Authing
 * @desc 仅同步注册信息及密码，资料在afterSave中同步
 * @example
 * 注册：
 curl -X POST -H "Content-Type: application/json" -H "X-Parse-Application-Id: edu-textbook" -d '{
  "username": "333",
  "password": "333"
 }' http://127.0.0.1:61337/parse/users
 * 删除：
 */
export function defineUserBeforeSave(){
    Parse.Cloud.beforeSave("_User", async (request) => {
        // console.log("UserBeforeSave")
        request.object = appendUserACL(request.object)
        let user = request.object;
        // 仅首次注册/创建用户/修改密码有password属性，同步Authing账号
        let password = user?.get("password");
        // console.log(password)
        if(password){
            let mobile = user?.get("mobile");
            let email = user?.get("email");
            let username = user?.get("username");
            let externalId = user?.id;
            let authingUserExists = await findUserByMobileEmailUserName(user)
            // console.log(authingUserExists)
            if(authingUserExists?.statusCode==404){ // 创建用户
                let newuser = {
                    status:"Activated",
                    password:password,
                }
                if(mobile){newuser.phone = mobile}
                if(email){newuser.email = email}
                if(username){newuser.username = username}
                if(externalId){newuser.externalId = externalId}
                // console.log(newuser)
                result = await managementClient.createUser(newuser)
            }
            if(authingUserExists?.statusCode==200){
                let existsUser = authingUserExists?.data;
                try{
                    let updateRes = await managementClient.updateUser({
                        userId:existsUser?.userId,
                        password:password,
                    })
                    // console.log(result)
                }catch(err){console.log(err)}
            }
        }
    });
}
function appendUserACL(user){
    let acl = user?.getACL();
    if(!acl) acl = new Parse.ACL();

    // 添加superadmin用户的可读可写权限
    acl.setRoleWriteAccess("superadmin", true);
    acl.setRoleReadAccess("superadmin", true);

    // 添加admin用户的可读可写权限
    acl.setRoleWriteAccess("admin", true);
    acl.setRoleReadAccess("admin", true);

    // 添加manager用户的可读可写权限
    acl.setRoleWriteAccess("manager", true);
    acl.setRoleReadAccess("manager", true);
    
    // 添加公共可读权限
    acl.setPublicReadAccess(true);

    user.setACL(acl);
    return user
}
/**
 * 用户删除前，删除用户从Authing
 */
 export function defineUserAfterDelete(){
    Parse.Cloud.afterDelete("_User", async (request) => {
        let user = request.object;
        // console.log(user.toJSON());
        // console.log(user?.get("password"))
            try{
                let authingUserExists = await findUserByMobileEmailUserName(user)
                if(authingUserExists?.statusCode==200){
                    let existsUser = authingUserExists?.data;
                        let deleteRes = await managementClient.deleteUsersBatch({
                            // 替换用户 ID 数组
                            userIds: [existsUser.userId],
                            options: {
                                userIdType: "user_id"
                            }
                        });
                }
            }catch(deleteErr){}

        // 直接给予删除权限
        // if(request?.master){
        //     return await object.destroy({useMasterKey:true})
        // }
        // let requestUser = request.user;
        // if(!requestUser?.id){
        //     throw new Parse.Error(206,"Insufficient auth.")
        // }
        // let query = new Parse.Query("_Role");
        // query.equalTo("users",requestUser)
        // let roles = await query.find({useMasterKey:true});

        // let acl = request.object.getACL();
        // if(!acl){
        //     throw new Parse.Error(206,"Object has no ACL.")
        // }
        // if(acl.getWriteAccess(requestUser)){
        //     return await request.object.destroy({useMasterKey:true})
        // }else{

        //     let hasPermission = roles.some(role=>acl.getRoleWriteAccess(role.getName()))
        //     if(hasPermission) {
        //         return await request.object.destroy({useMasterKey:true})
        //     }
        //     throw new Parse.Error(206,"Insufficient auth.")
        // }
    });
}
/**
 * 用户保存后同步数据至Authing
 */
export function defineUserAfterSave(){
    Parse.Cloud.afterSave("_User", async (request) => {
        // console.log("save _User",request?.object?.id)
        let query = new Parse.Query("Profile");
        query.equalTo("user",request?.object?.id)
        let profile = await query.first();
       syncUserProfileToAuthing(request?.object,profile)
    });

    Parse.Cloud.afterSave("Profile", async (request) => {
        // console.log("save Profile",request?.object?.id)
        let query = new Parse.Query("Profile");
        let userPointer = request?.object?.get("user")
        query.include("user");
        console.log(userPointer)
        profile = await query.get(request?.object?.id,{useMasterKey:true});
        syncUserProfileToAuthing(profile.get("user"),profile)

        appandUserToRole(profile.get("user")?.toPointer() || userPointer,profile?.get("identity"))
    });
}

// 同步Profile角色身份
var roleNameMap = {
    "国家级管理员":"superadmin",
    "工作联系人":"admin",
    "高校联系人":"manager",
}
async function appandUserToRole(user,roleName) {
    console.log(user,roleName)
    roleName = roleNameMap[roleName] || roleName
    let id = user?.id || user?.objectId
    if(!id || !roleName) return
    let userObj = new Parse.User();
    userObj.id = id;
    let query = new Parse.Query(Parse.Role);
    query.equalTo("name", roleName);
    try{
        let role = await query.first({ useMasterKey: true });
        console.log(role?.toJSON())
        if (role?.toJSON()?.name) {
            let usersRelation = role.relation("users");
            usersRelation.add(userObj);
            await role.save(null, { useMasterKey: true });
            let users = await usersRelation.query().find({ useMasterKey: true });
            console.log('Users in role after addition:', users.map(u => u.toJSON()));
        } 
    }catch(err){
        console.error(err)
    }
}

/**
 * 查询用户
 * @param {*} user 
 * @returns 
 * 不存在：
 *  {
        statusCode: 404,
        apiCode: 2004,
        message: '用户不存在',
        requestId: 'e59cb407-f2d9-4bd8-ac93-d2dbc8d6ab72'
    }

    {
        statusCode: 200,
        message: '',
        data: {
            userId: '669676e5a3a9ac870bfff2a3',
            createdAt: '2024-07-16T13:34:29.789Z',
            updatedAt: '2024-07-16T13:34:29.789Z',
            status: 'Activated'
        }
    }
 */
async function findUserByMobileEmailUserName(user){
    let mobile = user?.get("mobile");
    let email = user?.get("email");
    let username = user?.get("username");
    let externalId = user?.id;
    let result;
    if(email){
        try{
            result = await managementClient.getUser({userIdType:`email`,userId:email})
            // console.log(email,result)
        }catch(err){}
    } 
    if(mobile&&(!result || result?.statusCode==404)){
        try{
            result = await managementClient.getUser({userIdType:`phone`,userId:mobile})
            // console.log(mobile,result)
        }catch(err){}
    }
    if(username&&(!result || result?.statusCode==404)){
        try{
            result = await managementClient.getUser({userIdType:`username`,userId:username})
            // console.log("username",username,result)
        }catch(err){}
    }
    if(externalId&&(!result || result?.statusCode==404)){
        try{
            result = await managementClient.getUser({userIdType:`external_id`,userId:externalId})
            // console.log(externalId,result)
        }catch(err){}
    }
    return result
}

async function syncUserProfileToAuthing(user,profile){
    if(!user?.id) return
    let userInfo = user.toJSON();
    userInfo = fixJsonFileds(userInfo)
    if(profile?.id){
        let pjson = profile.toJSON();
        delete pjson.objectId;
        pjson= fixJsonFileds(pjson)
        Object.keys(pjson).forEach(key=>{
            userInfo[key] = pjson[key]
        })
    }
    // 映射对应字段
    userInfo.company = userInfo.companyName
    delete userInfo.companyName
    userInfo.userType = userInfo.identity
    delete userInfo.identity
    userInfo.userId = userInfo.objectId
    let authingUserExists = await findUserByMobileEmailUserName(user)
    if(authingUserExists?.statusCode==200){
        let existsUser = authingUserExists?.data;
        userInfo.userId = existsUser.userId
    }
    delete userInfo.objectId
    userInfo.identifyStatus = userInfo.accountState
    // 自定义数据全量同步
    userInfo.customData = JSON.parse(JSON.stringify(userInfo))
    // {
    //     identifyStatus : userInfo.accountState
    // }

    // console.log(userInfo)
    // 同步数据至Authing用户池
    let result
    try{
        result = await managementClient.updateUser(userInfo)
        // console.log(result)
    }catch(err){console.log(err)}

}

function fixJsonFileds(json){
    // Parse独有关系数据
    delete json.ACL
    delete json.className
    delete json.sessionToken
    delete json.company
    delete json.user
    delete json.createdAt
    delete json.updatedAt
    // 来自Authing的数据
    delete json?.loginsCount
    delete json?.lastIP
    delete json?.lastLogin
    return json
}