"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NotificationsClient = void 0;
const ta_json_1 = require("ta-json");
const constants_1 = require("../constants");
const guard_1 = __importDefault(require("../guard"));
const notification_mapper_1 = require("../mappers/notification-mapper");
const distribute_notification_resource_1 = require("../models/notifications/distribute-notification-resource");
const type_guards_1 = require("../type-guards");
const response_handler_1 = require("./response-handler");
class NotificationsClient {
    constructor(client) {
        guard_1.default.notNullOrUndefined(client);
        this._client = client;
    }
    //! Not necessary for now, can be added later (lots of boilerplate)
    // // public async getMailTemplateAsync(name: string, loadConfiguration: Nullable<IEntityLoadConfiguration> = null)
    sendConfirmationEmailAsync(users) {
        return __awaiter(this, void 0, void 0, function* () {
            let userIds = [];
            if (type_guards_1.TypeGuards.isStringArray(users)) {
                userIds = (yield this._client.users.getUserIdsAsync(users));
            }
            else {
                userIds = users;
            }
            guard_1.default.validIds(userIds);
            for (const userId of userIds) {
                const link = yield this._client.linkHelper.sendConfirmationMailToLinkAsync(userId);
                const response = yield this._client.raw.postAsync(link.href, ta_json_1.TaJson.serialize(userId));
                response_handler_1.ResponseHandler.handleErrors(response);
            }
        });
    }
    sendEmailNotificationAsync(mailRequest) {
        return __awaiter(this, void 0, void 0, function* () {
            guard_1.default.notNullOrUndefined(mailRequest);
            mailRequest.validate();
            if ("recipients" in mailRequest) {
                if (type_guards_1.TypeGuards.isStringArray(mailRequest.recipients)) {
                    // Usernames
                    const mailUsernames = mailRequest;
                    const ids = yield this._client.users.getUserIdsAsync(mailUsernames.recipients);
                    if (ids !== null) {
                        yield this.sendPrivateEmailNotificationAsync(mailUsernames, ids);
                    }
                }
                else {
                    // Ids
                    const mailIds = mailRequest;
                    yield this.sendPrivateEmailNotificationAsync(mailIds, mailIds.recipients);
                }
            }
            else {
                // Broadcast
                yield this.sendPrivateEmailNotificationAsync(mailRequest, null);
            }
        });
    }
    sendRealTimeNotificationAsync(realtimeRequest) {
        return __awaiter(this, void 0, void 0, function* () {
            guard_1.default.notNull(realtimeRequest);
            realtimeRequest.validate();
            if ("recipients" in realtimeRequest) {
                if (type_guards_1.TypeGuards.isStringArray(realtimeRequest.recipients)) {
                    // Usernames
                    const realtimeUsers = realtimeRequest;
                    const ids = yield this._client.users.getUserIdsAsync(realtimeUsers.recipients);
                    if (ids !== null) {
                        yield this.sendPrivateRealTimeNotificationAsync(realtimeRequest, ids);
                    }
                }
                else {
                    // Ids
                    const realtimeIds = realtimeRequest;
                    yield this.sendPrivateRealTimeNotificationAsync(realtimeIds, realtimeIds.recipients);
                }
            }
            else {
                // Broadcast
                yield this.sendPrivateRealTimeNotificationAsync(realtimeRequest, null);
            }
        });
    }
    //#region Private functions
    sendPrivateEmailNotificationAsync(mailRequest, recipients) {
        return __awaiter(this, void 0, void 0, function* () {
            return this.sendNotificationAsync(mailRequest.mailTemplateName, recipients, "EmailNotification", mailRequest.variables);
        });
    }
    sendPrivateRealTimeNotificationAsync(realtimeRequest, recipients) {
        return __awaiter(this, void 0, void 0, function* () {
            const parameters = notification_mapper_1.NotificationMapper.mapParameters(realtimeRequest);
            return this.sendNotificationAsync(constants_1.NOTIFICATIONS.REALTIME.raw, recipients, "RealTimeNotification", parameters);
        });
    }
    sendNotificationAsync(notificationName, recipients, channel, parameters) {
        return __awaiter(this, void 0, void 0, function* () {
            const link = yield this._client.linkHelper.sendNotificationToLinkAsync(notificationName);
            // Get user links.
            let userLinks = null;
            const linkPromises = recipients === null || recipients === void 0 ? void 0 : recipients.map(id => this._client.linkHelper.entityToLinkAsync(id));
            if (linkPromises != null) {
                userLinks = yield Promise.all(linkPromises);
            }
            // Create the resource.
            const resource = new distribute_notification_resource_1.DistributeNotificationResource();
            resource.recipients = userLinks;
            resource.channels = [channel];
            resource.parameters = parameters;
            const response = yield this._client.raw.postAsync(link.href, ta_json_1.TaJson.serialize(resource));
            response_handler_1.ResponseHandler.handleErrors(response);
        });
    }
}
exports.NotificationsClient = NotificationsClient;
//# sourceMappingURL=notifications-client.js.map