// (C) 2024-2025 GoodData Corporation
import { useCallback, useMemo, useState } from "react";
import { isAlertNotification } from "@gooddata/sdk-model";
import { UnexpectedSdkError, useWorkspace } from "@gooddata/sdk-ui";
import { useFetchNotifications } from "./useFetchNotifications.js";
import { useOrganization } from "../@staging/OrganizationContext/OrganizationContext.js";
function assertOrganizationReady(status, action) {
    if (status === "error") {
        throw new UnexpectedSdkError(`Cannot call ${action} - organization load failed.`);
    }
    if (status === "pending" || status === "loading") {
        throw new UnexpectedSdkError(`Cannot call ${action} - organization is not initialized.`);
    }
}
function assertNotificationsReady(status, action) {
    if (status === "error") {
        throw new UnexpectedSdkError(`Cannot call ${action} - notifications load failed.`);
    }
    if (status === "pending" || status === "loading") {
        throw new UnexpectedSdkError(`Cannot call ${action} - notifications are not initialized.`);
    }
}
function filterNotificationsByType(notifications, enableScheduleNotifications) {
    return enableScheduleNotifications ? notifications : notifications.filter(isAlertNotification);
}
function applyReadStatus(notifications, markedAsReadIds) {
    return notifications.map((notification) => {
        if (markedAsReadIds.includes(notification.id)) {
            return { ...notification, isRead: true };
        }
        return notification;
    });
}
/**
 * @internal
 */
export function useNotifications({ workspace, refreshInterval, itemsPerPage, enableScheduleNotifications, }) {
    const effectiveWorkspace = useWorkspace(workspace);
    const { notifications, error: notificationsError, status: notificationsStatus, hasNextPage: notificationsHasNextPage, loadNextPage: notificationsLoadNextPage, reset: notificationsReset, } = useFetchNotifications({
        workspace: effectiveWorkspace,
        refreshInterval,
        itemsPerPage,
    });
    const { notifications: unreadNotifications, error: unreadNotificationsError, status: unreadNotificationsStatus, hasNextPage: unreadNotificationsHasNextPage, loadNextPage: unreadNotificationsLoadNextPage, totalNotificationsCount: unreadNotificationsCount, reset: unreadNotificationsReset, } = useFetchNotifications({
        workspace: effectiveWorkspace,
        readStatus: "unread",
        refreshInterval,
        itemsPerPage,
    });
    const { result: organizationService, status: organizationStatus } = useOrganization();
    const [markedAsReadNotifications, setMarkedAsReadNotifications] = useState([]);
    const markNotificationAsRead = useCallback(async (notificationId) => {
        assertOrganizationReady(organizationStatus, "markAsRead");
        await organizationService.notifications().markNotificationAsRead(notificationId);
        setMarkedAsReadNotifications((prev) => [...prev, notificationId]);
    }, [organizationStatus, organizationService, setMarkedAsReadNotifications]);
    const markAllNotificationsAsRead = useCallback(async () => {
        assertOrganizationReady(organizationStatus, "markAllAsRead");
        assertNotificationsReady(notificationsStatus, "markAllAsRead");
        await organizationService.notifications().markAllNotificationsAsRead();
        notificationsReset();
        unreadNotificationsReset();
    }, [
        organizationService,
        organizationStatus,
        notificationsStatus,
        notificationsReset,
        unreadNotificationsReset,
    ]);
    const effectiveNotifications = useMemo(() => {
        if (!notifications) {
            return notifications;
        }
        const filteredNotifications = filterNotificationsByType(notifications, enableScheduleNotifications);
        return applyReadStatus(filteredNotifications, markedAsReadNotifications);
    }, [notifications, markedAsReadNotifications, enableScheduleNotifications]);
    const effectiveUnreadNotifications = useMemo(() => {
        if (!unreadNotifications) {
            return unreadNotifications;
        }
        const filteredUnreadNotifications = filterNotificationsByType(unreadNotifications, enableScheduleNotifications);
        const withReadStatus = applyReadStatus(filteredUnreadNotifications, markedAsReadNotifications);
        return withReadStatus.filter((x) => !x.isRead);
    }, [unreadNotifications, markedAsReadNotifications, enableScheduleNotifications]);
    /**
     * Generally, we filter out notifications that are not of type alert and here we prepare
     * the correction of the total count of unread notifications retrieved from the server.
     */
    const numberOfInvalidUnreadNotifications = useMemo(() => {
        return enableScheduleNotifications
            ? unreadNotifications.length
            : unreadNotifications.filter((notification) => !isAlertNotification(notification)).length;
    }, [unreadNotifications, enableScheduleNotifications]);
    return {
        notifications: effectiveNotifications,
        notificationsStatus,
        notificationsError,
        notificationsHasNextPage,
        notificationsLoadNextPage,
        notificationsReset,
        unreadNotifications: effectiveUnreadNotifications,
        unreadNotificationsStatus: unreadNotificationsStatus,
        unreadNotificationsError: unreadNotificationsError,
        unreadNotificationsHasNextPage: unreadNotificationsHasNextPage,
        unreadNotificationsLoadNextPage: unreadNotificationsLoadNextPage,
        unreadNotificationsReset,
        unreadNotificationsCount: Math.max(0, unreadNotificationsCount -
            markedAsReadNotifications.length -
            (enableScheduleNotifications ? 0 : numberOfInvalidUnreadNotifications)),
        markNotificationAsRead,
        markAllNotificationsAsRead,
    };
}
//# sourceMappingURL=useNotifications.js.map