import { EventSourcePolyfill } from "event-source-polyfill";
import { request } from "./api";
import { getEndpointByOptions, NOTIFICATIONS } from "./endpoints.const";
export class NotificationService {
    static async getNotifications(options) {
        return await request({
            method: "get",
            base: "notifications",
            stage: options.stage,
            endpoints: options.endpoints,
            camundaAuth: {
                token: options.userToken,
                refreshTokenMethod: options.getNewUserToken,
            },
            url: `notifications/orgs/${options.activeOrganizationId}`,
        });
    }
    static sendAnalyticsEvent(options, eventOptions) {
        request({
            method: "post",
            base: "notifications",
            stage: options.stage,
            endpoints: options.endpoints,
            camundaAuth: {
                token: options.userToken,
                refreshTokenMethod: options.getNewUserToken,
            },
            url: `analytics/${options.activeOrganizationId}/${eventOptions.event}`,
            body: {
                id: eventOptions.id,
            },
            type: "json",
            responseType: "text",
        });
    }
    static changeState(options, notificationId, operation) {
        request({
            method: "patch",
            base: "notifications",
            stage: options.stage,
            endpoints: options.endpoints,
            camundaAuth: {
                token: options.userToken,
                refreshTokenMethod: options.getNewUserToken,
            },
            url: `notifications/${notificationId}/${operation}`,
        });
    }
    static markManyAsRead(options, notificationIds) {
        if (notificationIds.length === 0) {
            return;
        }
        request({
            method: "patch",
            base: "notifications",
            stage: options.stage,
            endpoints: options.endpoints,
            camundaAuth: {
                token: options.userToken,
                refreshTokenMethod: options.getNewUserToken,
            },
            url: `notifications/batch/state/read`,
            body: {
                uuids: notificationIds,
            },
            type: "json",
        });
    }
    static dismissAll(options, orgId) {
        if (!orgId) {
            return;
        }
        request({
            method: "patch",
            base: "notifications",
            stage: options.stage,
            endpoints: options.endpoints,
            camundaAuth: {
                token: options.userToken,
                refreshTokenMethod: options.getNewUserToken,
            },
            url: `notifications/dismissAll?orgId=${orgId}`,
            type: "json",
        });
    }
    static notificationsStream(options, handler) {
        const baseUrl = getEndpointByOptions({
            ...options,
            endpoint: NOTIFICATIONS,
        });
        try {
            const source = new EventSourcePolyfill(`${baseUrl}/notifications/events`, {
                headers: {
                    authorization: `Bearer ${options.userToken}`,
                },
                heartbeatTimeout: 1000 * 60 * 60,
            });
            source.onmessage = function (event) {
                try {
                    const notification = JSON.parse(event.data);
                    if (!notification.keepAlive) {
                        handler(notification);
                    }
                }
                catch (error) {
                    if (options.enableLogs)
                        console.error(`Failed to handle SSE event`, { error });
                }
            };
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            source.onerror = function (_event) {
                // ignore
            };
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
        }
        catch (_error) {
            // ignore
        }
    }
    // updates <allNotifications> with <newNotification>
    // if <newNotification> is read or new, it will be added to <allNotifications>
    // if <newNotification> is dismissed, it will be removed from <allNotifications>
    static updateNotifications(allNotifications, newNotification) {
        const updatedNotifications = allNotifications
            .slice()
            .filter((currentNotification) => currentNotification.uuid !== newNotification.uuid);
        if (newNotification.state === "read" || newNotification.state === "new") {
            updatedNotifications.push(newNotification);
        }
        updatedNotifications.sort((a, b) => b.timestamp - a.timestamp);
        return updatedNotifications;
    }
    static updateNotificationState(allNotifications, notificationId, newState) {
        let updatedNotifications = allNotifications.slice();
        let foundNotification;
        switch (newState) {
            case "dismiss":
                updatedNotifications = updatedNotifications.filter((notification) => notification.uuid !== notificationId);
                break;
            case "read":
                foundNotification = updatedNotifications.find((currentNotification) => currentNotification.uuid === notificationId);
                if (foundNotification) {
                    foundNotification.state = newState;
                }
                break;
        }
        return updatedNotifications;
    }
    static updateNotificationStates(allNotifications, notificationIds, newState) {
        let updatedNotifications = allNotifications.slice();
        let foundNotifications = [];
        switch (newState) {
            case "dismiss":
                updatedNotifications = updatedNotifications.filter((notification) => !notificationIds.includes(notification.uuid));
                break;
            case "read":
                foundNotifications = updatedNotifications.filter((notification) => notificationIds.includes(notification.uuid));
                foundNotifications.forEach((foundNotification) => {
                    foundNotification.state = newState;
                });
                break;
        }
        return updatedNotifications;
    }
}
