"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Chat = void 0;
const tslib_1 = require("tslib");
const constants_1 = require("../constants");
const pushAPITypes_1 = require("./pushAPITypes");
const PUSH_USER = require("../user");
const PUSH_CHAT = require("../chat");
const helpers_1 = require("../chat/helpers");
const helpers_2 = require("../helpers");
const updateGroupProfile_1 = require("../chat/updateGroupProfile");
const user_1 = require("./user");
const updateGroupConfig_1 = require("../chat/updateGroupConfig");
const PushAPI_1 = require("./PushAPI");
class Chat {
    constructor(account, env, alpha, decryptedPgpPvtKey, signer, progressHook) {
        this.account = account;
        this.env = env;
        this.alpha = alpha;
        this.decryptedPgpPvtKey = decryptedPgpPvtKey;
        this.signer = signer;
        this.progressHook = progressHook;
        this.group = {
            create: (name, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                var _a, _b, _c;
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                const groupParams = {
                    account: this.account,
                    signer: this.signer,
                    pgpPrivateKey: this.decryptedPgpPvtKey,
                    env: this.env,
                    groupName: name,
                    groupDescription: (_a = options === null || options === void 0 ? void 0 : options.description) !== null && _a !== void 0 ? _a : null,
                    groupImage: (_b = options === null || options === void 0 ? void 0 : options.image) !== null && _b !== void 0 ? _b : null,
                    rules: (_c = options === null || options === void 0 ? void 0 : options.rules) !== null && _c !== void 0 ? _c : {},
                    isPublic: !(options === null || options === void 0 ? void 0 : options.private),
                    groupType: 'default',
                    config: {
                        meta: null,
                        scheduleAt: null,
                        scheduleEnd: null,
                        status: null,
                    },
                    members: (options === null || options === void 0 ? void 0 : options.members) ? options.members : [],
                    admins: (options === null || options === void 0 ? void 0 : options.admins) ? options.admins : [],
                };
                const response = yield PUSH_CHAT.createGroupV2(groupParams);
                if (this.scalabilityV2Feature) {
                    return response;
                }
                else {
                    return yield PUSH_CHAT.getGroup({
                        chatId: response.chatId,
                        env: this.env,
                    });
                }
            }),
            participants: {
                list: (chatId, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                    const { page = 1, limit = 20, filter = { pending: undefined, role: undefined }, } = options !== null && options !== void 0 ? options : {};
                    const getGroupMembersOptions = {
                        chatId,
                        page,
                        limit,
                        pending: filter.pending,
                        role: filter.role,
                        env: this.env,
                    };
                    const members = yield PUSH_CHAT.getGroupMembers(getGroupMembersOptions);
                    return { members };
                }),
                count: (chatId) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                    const count = yield PUSH_CHAT.getGroupMemberCount({
                        chatId,
                        env: this.env,
                    });
                    return {
                        participants: count.overallCount - count.pendingCount,
                        pending: count.pendingCount,
                    };
                }),
                status: (chatId, accountId) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                    const status = yield PUSH_CHAT.getGroupMemberStatus({
                        chatId: chatId,
                        did: accountId,
                        env: this.env,
                    });
                    return {
                        pending: status.isPending,
                        role: status.isAdmin ? 'admin' : 'member',
                        participant: status.isMember,
                    };
                }),
            },
            permissions: (chatId) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                const getGroupAccessOptions = {
                    chatId,
                    did: this.account,
                    env: this.env,
                };
                return yield PUSH_CHAT.getGroupAccess(getGroupAccessOptions);
            }),
            info: (chatId) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                return this.scalabilityV2Feature
                    ? yield PUSH_CHAT.getGroupInfo({
                        chatId: chatId,
                        env: this.env,
                    })
                    : yield PUSH_CHAT.getGroup({
                        chatId: chatId,
                        env: this.env,
                    });
            }),
            update: (chatId, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                const group = yield PUSH_CHAT.getGroupInfo({
                    chatId: chatId,
                    env: this.env,
                });
                if (!group) {
                    throw new Error('Group not found');
                }
                const updateGroupProfileOptions = {
                    chatId: chatId,
                    groupName: options.name ? options.name : group.groupName,
                    groupDescription: options.description
                        ? options.description
                        : group.groupDescription,
                    groupImage: options.image ? options.image : group.groupImage,
                    rules: options.rules ? options.rules : group.rules,
                    account: this.account,
                    pgpPrivateKey: this.decryptedPgpPvtKey,
                    env: this.env,
                };
                const updateGroupConfigOptions = {
                    chatId: chatId,
                    meta: options.meta ? options.meta : group.meta,
                    scheduleAt: options.scheduleAt ? options.scheduleAt : group.scheduleAt,
                    scheduleEnd: options.scheduleEnd
                        ? options.scheduleEnd
                        : group.scheduleEnd,
                    status: options.status ? options.status : group.status,
                    account: this.account,
                    pgpPrivateKey: this.decryptedPgpPvtKey,
                    env: this.env,
                };
                yield (0, updateGroupProfile_1.updateGroupProfile)(updateGroupProfileOptions);
                const response = yield (0, updateGroupConfig_1.updateGroupConfig)(updateGroupConfigOptions);
                if (this.scalabilityV2Feature) {
                    return response;
                }
                else {
                    return yield PUSH_CHAT.getGroup({
                        chatId: response.chatId,
                        env: this.env,
                    });
                }
            }),
            add: (chatId, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                const { role, accounts } = options;
                const validRoles = ['ADMIN', 'MEMBER'];
                if (!validRoles.includes(role)) {
                    throw new Error('Invalid role provided.');
                }
                if (!accounts || accounts.length === 0) {
                    throw new Error('accounts array cannot be empty!');
                }
                accounts.forEach((account) => {
                    if (!(0, helpers_2.isValidETHAddress)(account)) {
                        throw new Error(`Invalid account address: ${account}`);
                    }
                });
                let response;
                if (role === 'ADMIN') {
                    response = yield PUSH_CHAT.addAdmins({
                        chatId: chatId,
                        admins: accounts,
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                else {
                    response = yield PUSH_CHAT.addMembers({
                        chatId: chatId,
                        members: accounts,
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                if (this.scalabilityV2Feature) {
                    return response;
                }
                else {
                    return yield PUSH_CHAT.getGroup({
                        chatId: response.chatId,
                        env: this.env,
                    });
                }
            }),
            remove: (chatId, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                const { accounts } = options;
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                if (!accounts || accounts.length === 0) {
                    throw new Error('Accounts array cannot be empty!');
                }
                accounts.forEach((account) => {
                    if (!(0, helpers_2.isValidETHAddress)(account)) {
                        throw new Error(`Invalid account address: ${account}`);
                    }
                });
                const adminsToRemove = [];
                const membersToRemove = [];
                for (const account of accounts) {
                    const status = yield PUSH_CHAT.getGroupMemberStatus({
                        chatId: chatId,
                        did: account,
                        env: this.env,
                    });
                    if (status.isAdmin) {
                        adminsToRemove.push(account);
                    }
                    else if (status.isMember) {
                        membersToRemove.push(account);
                    }
                }
                if (adminsToRemove.length > 0) {
                    yield PUSH_CHAT.removeAdmins({
                        chatId: chatId,
                        admins: adminsToRemove,
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                if (membersToRemove.length > 0) {
                    yield PUSH_CHAT.removeMembers({
                        chatId: chatId,
                        members: membersToRemove,
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                return yield this.group.info(chatId);
            }),
            modify: (chatId, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                const { role, accounts } = options;
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                const validRoles = ['ADMIN', 'MEMBER'];
                if (!validRoles.includes(role)) {
                    throw new Error('Invalid role provided.');
                }
                if (!accounts || accounts.length === 0) {
                    throw new Error('accounts array cannot be empty!');
                }
                accounts.forEach((account) => {
                    if (!(0, helpers_2.isValidETHAddress)(account)) {
                        throw new Error(`Invalid account address: ${account}`);
                    }
                });
                return yield PUSH_CHAT.modifyRoles({
                    chatId: chatId,
                    newRole: role,
                    members: accounts,
                    env: this.env,
                    account: this.account,
                    signer: this.signer,
                    pgpPrivateKey: this.decryptedPgpPvtKey,
                    overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                });
            }),
            join: (target) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                const status = yield PUSH_CHAT.getGroupMemberStatus({
                    chatId: target,
                    did: this.account,
                    env: this.env,
                });
                if (status.isPending) {
                    yield PUSH_CHAT.approve({
                        senderAddress: target,
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                else if (!status.isMember) {
                    yield PUSH_CHAT.addMembers({
                        chatId: target,
                        members: [this.account],
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                return yield this.group.info(target);
            }),
            leave: (target) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                const status = yield PUSH_CHAT.getGroupMemberStatus({
                    chatId: target,
                    did: this.account,
                    env: this.env,
                });
                let response;
                if (status.isAdmin) {
                    response = yield PUSH_CHAT.removeAdmins({
                        chatId: target,
                        admins: [this.account],
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                else {
                    response = yield PUSH_CHAT.removeMembers({
                        chatId: target,
                        members: [this.account],
                        env: this.env,
                        account: this.account,
                        signer: this.signer,
                        pgpPrivateKey: this.decryptedPgpPvtKey,
                        overrideSecretKeyGeneration: !this.scalabilityV2Feature,
                    });
                }
                if (this.scalabilityV2Feature) {
                    return response;
                }
                else {
                    return yield PUSH_CHAT.getGroup({
                        chatId: response.chatId,
                        env: this.env,
                    });
                }
            }),
            reject: (target) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                if (!this.signer) {
                    throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
                }
                yield PUSH_CHAT.reject({
                    senderAddress: target,
                    env: this.env,
                    account: this.account,
                    signer: this.signer,
                    pgpPrivateKey: this.decryptedPgpPvtKey,
                });
            }),
        };
        this.userInstance = new user_1.User(this.account, this.env);
        this.scalabilityV2Feature = this.alpha.feature.includes(constants_1.ALPHA_FEATURES.SCALABILITY_V2);
    }
    list(type, options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const accountToUse = (options === null || options === void 0 ? void 0 : options.overrideAccount) || this.account;
            const listParams = {
                account: accountToUse,
                pgpPrivateKey: this.decryptedPgpPvtKey,
                page: options === null || options === void 0 ? void 0 : options.page,
                limit: options === null || options === void 0 ? void 0 : options.limit,
                env: this.env,
                toDecrypt: !!this.signer, // Set to false if signer is undefined or null,
            };
            switch (type) {
                case pushAPITypes_1.ChatListType.CHATS:
                    return yield PUSH_CHAT.chats(listParams);
                case pushAPITypes_1.ChatListType.REQUESTS:
                    return yield PUSH_CHAT.requests(listParams);
                default:
                    throw new Error('Invalid Chat List Type');
            }
        });
    }
    latest(target) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { threadHash } = yield PUSH_CHAT.conversationHash({
                conversationId: target,
                account: this.account,
                env: this.env,
            });
            if (!threadHash)
                return {};
            return yield PUSH_CHAT.latest({
                threadhash: threadHash,
                toDecrypt: !!this.signer,
                pgpPrivateKey: this.decryptedPgpPvtKey,
                account: this.account,
                env: this.env,
            });
        });
    }
    history(target, options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let reference;
            if (!(options === null || options === void 0 ? void 0 : options.reference)) {
                const { threadHash } = yield PUSH_CHAT.conversationHash({
                    conversationId: target,
                    account: this.account,
                    env: this.env,
                });
                reference = threadHash;
            }
            else {
                reference = options.reference;
            }
            if (!reference)
                return [];
            return yield PUSH_CHAT.history({
                account: this.account,
                env: this.env,
                threadhash: reference,
                pgpPrivateKey: this.decryptedPgpPvtKey,
                toDecrypt: !!this.signer,
                limit: options === null || options === void 0 ? void 0 : options.limit,
            });
        });
    }
    send(recipient, options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.signer) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            if (!options.type) {
                options.type = constants_1.MessageType.TEXT;
            }
            const sendParams = {
                message: options,
                to: recipient,
                account: this.account,
                signer: this.signer,
                pgpPrivateKey: this.decryptedPgpPvtKey,
                env: this.env,
            };
            return yield PUSH_CHAT.send(sendParams);
        });
    }
    decrypt(messagePayloads) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.signer) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            return yield PUSH_CHAT.decryptConversation({
                pgpPrivateKey: this.decryptedPgpPvtKey,
                env: this.env,
                messages: messagePayloads,
                connectedUser: yield this.userInstance.info(),
            });
        });
    }
    accept(target) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.signer) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            return yield PUSH_CHAT.approve({
                senderAddress: target,
                env: this.env,
                account: this.account,
                signer: this.signer,
                pgpPrivateKey: this.decryptedPgpPvtKey,
                overrideSecretKeyGeneration: !this.scalabilityV2Feature,
            });
        });
    }
    reject(target) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.signer) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            yield PUSH_CHAT.reject({
                senderAddress: target,
                env: this.env,
                account: this.account,
                signer: this.signer,
                pgpPrivateKey: this.decryptedPgpPvtKey,
            });
        });
    }
    block(users) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.signer || !this.decryptedPgpPvtKey) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            const user = yield PUSH_USER.get({
                account: this.account,
                env: this.env,
            });
            for (const element of users) {
                if (!(0, helpers_2.isValidETHAddress)(element)) {
                    throw new Error('Invalid address in the users: ' + element);
                }
            }
            if (!user.profile.blockedUsersList) {
                user.profile.blockedUsersList = [];
            }
            user.profile.blockedUsersList = [
                ...new Set([...user.profile.blockedUsersList, ...users]),
            ];
            if (!this.decryptedPgpPvtKey) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            return yield PUSH_USER.profile.update({
                pgpPrivateKey: this.decryptedPgpPvtKey,
                account: this.account,
                profile: {
                    name: user.profile.name,
                    desc: user.profile.desc,
                    picture: user.profile.picture,
                    blockedUsersList: user.profile.blockedUsersList,
                },
                env: this.env,
                progressHook: this.progressHook,
            });
        });
    }
    unblock(users) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.signer || !this.decryptedPgpPvtKey) {
                throw new Error(PushAPI_1.PushAPI.ensureSignerMessage());
            }
            const user = yield PUSH_USER.get({
                account: this.account,
                env: this.env,
            });
            for (const element of users) {
                if (!(0, helpers_2.isValidETHAddress)(element)) {
                    throw new Error('Invalid address in the users: ' + element);
                }
            }
            if (!user.profile.blockedUsersList) {
                return user;
            }
            const userDIDsPromises = users.map((user) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                return (yield (0, helpers_1.getUserDID)(user, this.env)).toLowerCase();
            }));
            const userDIDs = yield Promise.all(userDIDsPromises);
            user.profile.blockedUsersList = user.profile.blockedUsersList.filter((blockedUser) => {
                !userDIDs.includes(blockedUser.toLowerCase());
            });
            return yield PUSH_USER.profile.update({
                pgpPrivateKey: this.decryptedPgpPvtKey,
                account: this.account,
                profile: {
                    name: user.profile.name,
                    desc: user.profile.desc,
                    picture: user.profile.picture,
                    blockedUsersList: user.profile.blockedUsersList,
                },
                env: this.env,
                progressHook: this.progressHook,
            });
        });
    }
}
exports.Chat = Chat;
//# sourceMappingURL=chat.js.map