"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateGroupCore = exports.updateGroup = void 0;
const tslib_1 = require("tslib");
const axios_1 = require("axios");
const helpers_1 = require("../helpers");
const constants_1 = require("../constants");
const helpers_2 = require("./helpers");
const CryptoJS = require("crypto-js");
const getGroup_1 = require("./getGroup");
const AES = require("../chat/helpers/aes");
const getGroupMemberStatus_1 = require("./getGroupMemberStatus");
/**
 * Update Group information
 */
const updateGroup = (options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    return yield (0, exports.updateGroupCore)(options, helpers_2.PGPHelper);
});
exports.updateGroup = updateGroup;
const updateGroupCore = (options, pgpHelper) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    const { chatId, groupName, groupImage, groupDescription, members, admins, account = null, signer = null, env = constants_1.default.ENV.PROD, pgpPrivateKey = null, scheduleAt, scheduleEnd, status, meta, rules, } = options || {};
    try {
        if (account == null && signer == null) {
            throw new Error(`At least one from account or signer is necessary!`);
        }
        const wallet = (0, helpers_2.getWallet)({ account, signer });
        const address = yield (0, helpers_2.getAccountAddress)(wallet);
        (0, helpers_2.updateGroupRequestValidator)(chatId, groupName, members, admins, address, groupDescription);
        const connectedUser = yield (0, helpers_2.getConnectedUserV2Core)(wallet, pgpPrivateKey, env, pgpHelper);
        const convertedMembersPromise = members.map((each) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
            return (0, helpers_2.getUserDID)(each, env);
        }));
        const convertedAdminsPromise = admins.map((each) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
            return (0, helpers_2.getUserDID)(each, env);
        }));
        const convertedMembers = yield Promise.all(convertedMembersPromise);
        const convertedAdmins = yield Promise.all(convertedAdminsPromise);
        const groupChat = yield (0, getGroup_1.getGroup)({ chatId, env });
        // Compare members array with updateGroup.members array. If they have all the same elements then return true
        const updatedParticipants = new Set(convertedMembers.map((participant) => participant.toLowerCase()));
        const participantStatus = yield (0, getGroupMemberStatus_1.getGroupMemberStatus)({
            chatId,
            did: connectedUser.did,
            env,
        });
        let sameMembers = true;
        groupChat.members.map((element) => {
            if (!updatedParticipants.has(element.wallet.toLowerCase())) {
                sameMembers = false;
            }
        });
        let encryptedSecret = null;
        if ((!sameMembers || !participantStatus.isMember) && !groupChat.isPublic) {
            const secretKey = AES.generateRandomSecret(15);
            const publicKeys = [];
            // This will now only take keys of non-removed members
            groupChat.members.map((element) => {
                if (updatedParticipants.has(element.wallet.toLowerCase())) {
                    publicKeys.push(element.publicKey);
                }
            });
            // This is autoJoin Case
            if (!participantStatus.isMember) {
                publicKeys.push(connectedUser.publicKey);
            }
            // Encrypt secret key with group members public keys
            encryptedSecret = yield pgpHelper.pgpEncrypt({
                plainText: secretKey,
                keys: publicKeys,
            });
        }
        const bodyToBeHashed = {
            groupName: groupName,
            groupDescription: groupDescription == undefined ? null : groupDescription,
            groupImage: groupImage == undefined ? null : groupImage,
            members: convertedMembers,
            admins: convertedAdmins,
            chatId: chatId,
        };
        const hash = CryptoJS.SHA256(JSON.stringify(bodyToBeHashed)).toString();
        const signature = yield pgpHelper.sign({
            message: hash,
            signingKey: connectedUser.privateKey,
        });
        const sigType = 'pgp';
        const verificationProof = sigType + ':' + signature + ':' + account;
        const API_BASE_URL = (0, helpers_1.getAPIBaseUrls)(env);
        const apiEndpoint = `${API_BASE_URL}/v1/chat/groups/${chatId}`;
        const body = (0, helpers_2.updateGroupPayload)(groupName, convertedMembers, convertedAdmins, connectedUser.did, verificationProof, encryptedSecret, groupDescription, groupImage, scheduleAt, scheduleEnd, status, meta, rules);
        return axios_1.default
            .put(apiEndpoint, body)
            .then((response) => {
            return response.data;
        })
            .catch((err) => {
            var _a;
            if ((_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data)
                throw new Error(JSON.stringify(err.response.data));
            throw new Error(err);
        });
    }
    catch (err) {
        console.error(`[Push SDK] - API  - Error - API ${exports.updateGroup.name} -:  `, err);
        throw Error(`[Push SDK] - API  - Error - API ${exports.updateGroup.name} -: ${err}`);
    }
});
exports.updateGroupCore = updateGroupCore;
//# sourceMappingURL=updateGroup.js.map