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


// const pgp = require('pg-promise')();
// const pgClient = () => {return pgp("postgresql://textbook:Edu2024textbask@oss-cn-beijing-internal.aliyuncs.com:5432/textbook");}

import { pgClient } from '../../db/pg-instance'
export function defineAuthingDepartSync(){
    Parse.Cloud.define("authingDepartSync", async (request) => {
        let result = await syncOrganizationsFromAuthing()
        return result
    });
}
  

/**
 * 同步全部组织架构 From Authing
 * @desc
 * https://docs.authing.cn/v3/reference/sdk/node/management/管理组织机构/list-organizations.html
 * @param {*} token 
 * @returns 
 */
async function syncOrganizationsFromAuthing(){
    // 通过用户的 id_token 初始化之后获取用户信息
    
    let orgList = []
    try{

        let result = await managementClient.listOrganizations({
            page: 1,
            limit: 50,
            withPost: true,
            withCustomData: true
        });
        if(result?.data?.list?.length){
            orgList = orgList.concat(result?.data?.list)
            let departList = await getAllChildDepartments(orgList[0])
            // console.log(departList)
            console.log(departList?.length)
            // return
            let insertRes = await InsertAllDepartment(departList);
            console.log(insertRes)
            // 将所有不存在的部门，设置为isDeleted删除状态
            try{
                let deleteRes = await UpdateAllDeleteDepartment(departList);
            }catch(err){}
            return {code:200,count:departList?.length,message:`成功导入${departList?.length}条`}
        }
        
    }catch(err){
        console.error(err)
    }
    return
    // console.log(user)

}
module.exports.syncOrganizationsFromAuthing = syncOrganizationsFromAuthing


async function UpdateAllDeleteDepartment(departList){
    let existsIdList = departList.map(depart=>depart?.departmentId)
    existsIdList = existsIdList.filter(item=>item)
    let sql = `
    UPDATE "Department" SET "isDeleted" = true
    WHERE "objectId" <> ALL ($1);
    `
    let result = await pgClient().any(sql,[existsIdList]);
    return result
}
async function InsertAllDepartment(departList){
    // {
        //     departmentId: '66868df17adf199d1c77875d',
    //     organizationCode: '1000000',
    //     name: '河北人民出版社有限责任公司',
    //     description: '',
    //     code: '30000095',
    //     hasChildren: false,
    //     isVirtualNode: false,
    //     i18n: { name: [Object] },
    //     customData: {},
    //     status: true
    //     createdAt: '2024-07-04T11:56:33.813Z',
    //     updatedAt: '2024-07-04T11:56:33.813Z',
    //   },
    let rowData = []
    departList.forEach(depart=>{
        let objectId = depart?.departmentId
        if(!depart?.hasChildren){ // 最后一级，类型为单位
            depart.type = "单位"
        }
        let parentId = depart?.parent?.departmentId // 指针是正常的
        let branchName = depart?.branch?.name // 分值为当前单位最上级分支（表示应用下，分支最高级名称）

        rowData.push([
            // 1-5
            objectId, depart?.organizationCode, depart?.name, depart?.description, branchName,
            // 6-10
            parentId, depart?.code, depart?.createdAt || new Date(), depart?.updatedAt || new Date(), depart?.status,
            // 11
            depart?.type,depart?.hasChildren
        ])
    })
    let flattenedParams = rowData.flat();

    let syncDepartSQL = `
    INSERT INTO "Department" ("objectId", "organizationCode", "name", "description","branch","parent","code","createdAt","updatedAt","status","type","hasChildren")
    VALUES
        ${rowData.map((_, i) => `($${i * 12 + 1}, $${i * 12 + 2}, $${i * 12 + 3}, $${i * 12 + 4}, $${i * 12 + 5}, $${i * 12 + 6}, $${i * 12 + 7}, $${i * 12 + 8}, $${i * 12 + 9}, $${i * 12 + 10}, $${i * 12 + 11}, $${i * 12 + 12})`).join(',\n')}    
    ON CONFLICT ("objectId") DO UPDATE
    SET 
        "organizationCode" = EXCLUDED."organizationCode",
        "name" = EXCLUDED."name",
        "description" = EXCLUDED."description",
        "branch" = EXCLUDED."branch",
        "parent" = EXCLUDED."parent",
        "code" = EXCLUDED."code",
        "status" = EXCLUDED."status",
        "createdAt" = EXCLUDED."createdAt",
        "updatedAt" = EXCLUDED."updatedAt",
        "type" = EXCLUDED."type",
        "hasChildren" = EXCLUDED."hasChildren";
    `
    let result = await pgClient().any(syncDepartSQL,flattenedParams);
    return result
}

async function getAllChildDepartments(organization,depart,parentMap,level){
    // if(level>3) return []
    let newParentMap = JSON.parse(JSON.stringify(parentMap||{}))
    level = level || 1
    let currentDepart = depart || organization
    if(level==1) newParentMap["1"] = newParentMap["1"] || depart
    if(level==2) newParentMap["2"] = newParentMap["2"] || depart
    if(level==3) newParentMap["3"] = newParentMap["3"] || depart
    if(level==4) newParentMap["4"] = newParentMap["4"] || depart
    if(!currentDepart?.hasChildren) return []
    let departmentList = []
    
    let childDepartList
    // if(organization){
    try{
        childDepartList = await getDepartmentOfOrg(currentDepart?.organizationCode,currentDepart?.departmentId,currentDepart,newParentMap)
        // childDepartList?.forEach(item=>item.parent = currentDepart)
    }catch(err){console.error(err)}
        // }
    departmentList = departmentList.concat(childDepartList)
    // console.log("childDepartList",childDepartList)
    let pList = childDepartList?.map(item=>getAllChildDepartments(null,item,newParentMap,level+1))
    let resList = await Promise.all(pList);
    resList.forEach((list,index)=>{
        list = list?.map(item=>{
            return item
        })
        if(list?.length) departmentList = departmentList.concat(list)
    })
    return departmentList
}

async function getDepartmentOfOrg(organizationCode,departmentId,parent,parentMap){
    let newParent = JSON.parse(JSON.stringify(parent))
    let newParentMap = JSON.parse(JSON.stringify(parentMap))
    let result
    try{
        result = await managementClient.listChildrenDepartments({
            // 替换组织 Code 和部门 ID
            organizationCode: organizationCode,
            departmentId: departmentId,
            departmentIdType: 'department_id',
            withCustomData: true
        });
    }catch(err){}
      if(result?.data?.list?.length) {
        let list = result?.data?.list;
        list.forEach(item=>{
            item.branch = newParentMap?.["2"]
            item.parent = newParent
        })
        return result?.data?.list
      }
      return []
}

// const crypto = require('crypto');
// function generateObjectId(inputString) {
//     const hash = crypto.createHash('sha256').update(inputString).digest('hex');
//     const objectId = hash;
//     return objectId;
// }