"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const styles_1 = require("@mui/material/styles");
const Comment_1 = tslib_1.__importDefault(require("../Notification/Comment"));
const UserFollow_1 = tslib_1.__importDefault(require("../Notification/UserFollow"));
const UndeletedFor_1 = tslib_1.__importDefault(require("../Notification/UndeletedFor"));
const DeletedFor_1 = tslib_1.__importDefault(require("../Notification/DeletedFor"));
const UserConnection_1 = tslib_1.__importDefault(require("../Notification/UserConnection"));
const PrivateMessage_1 = tslib_1.__importDefault(require("../Notification/PrivateMessage"));
const UserBlocked_1 = tslib_1.__importDefault(require("../Notification/UserBlocked"));
const Mention_1 = tslib_1.__importDefault(require("../Notification/Mention"));
const CollapsedFor_1 = tslib_1.__importDefault(require("../Notification/CollapsedFor"));
const KindlyNoticeFor_1 = tslib_1.__importDefault(require("../Notification/KindlyNoticeFor"));
const KindlyNoticeFlag_1 = tslib_1.__importDefault(require("../Notification/KindlyNoticeFlag"));
const VoteUp_1 = tslib_1.__importDefault(require("../Notification/VoteUp"));
const Errors_1 = require("../../constants/Errors");
const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
const ContributionFollow_1 = tslib_1.__importDefault(require("../Notification/ContributionFollow"));
const material_1 = require("@mui/material");
const IncubatorApproved_1 = tslib_1.__importDefault(require("../Notification/IncubatorApproved"));
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
const types_1 = require("../../types");
const ScrollContainer_1 = tslib_1.__importDefault(require("../../shared/ScrollContainer"));
const react_intl_1 = require("react-intl");
const types_2 = require("@selfcommunity/types");
const api_services_1 = require("@selfcommunity/api-services");
const utils_1 = require("@selfcommunity/utils");
const react_core_1 = require("@selfcommunity/react-core");
const system_1 = require("@mui/system");
const Contribution_1 = tslib_1.__importDefault(require("../Notification/Contribution"));
const NotificationItem_1 = tslib_1.__importDefault(require("../../shared/NotificationItem"));
const constants_1 = require("./constants");
const Group_1 = tslib_1.__importDefault(require("../Notification/Group"));
const Event_1 = tslib_1.__importDefault(require("../Notification/Event/Event"));
const classes = {
    root: `${constants_1.PREFIX}-root`,
    notificationsWrap: `${constants_1.PREFIX}-notifications-wrap`,
    emptyBoxNotifications: `${constants_1.PREFIX}-empty-box-notifications`,
    list: `${constants_1.PREFIX}-list`,
    broadcastMessagesBanner: `${constants_1.PREFIX}-broadcast-messages-banner`,
    item: `${constants_1.PREFIX}-item`
};
const Root = (0, styles_1.styled)(material_1.Box, {
    name: constants_1.PREFIX,
    slot: 'Root'
})(() => ({}));
const PREFERENCES = [react_core_1.SCPreferences.LOGO_NAVBAR_LOGO_MOBILE, react_core_1.SCPreferences.TEXT_APPLICATION_NAME];
/**
 * > API documentation for the Community-JS SnippetNotifications component. Learn about the available props and the CSS API.
 *
 *
 * This component renders the notification list.
 * Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/SnippetNotifications)

 #### Import

 ```jsx
 import {SnippetNotifications} from '@selfcommunity/react-ui';
 ```

 #### Component Name

 The name `SCSnippetNotifications` can be used when providing style overrides in the theme.


 #### CSS

 |Rule Name|Global class|Description|
 |---|---|---|
 |root|.SCSnippetNotification-root|Styles applied to the root element.|
 |notificationsWrap|.SCSnippetNotification-notification-wrap|Styles applied to the notifications wrap.|
 |emptyBoxNotifications|.SCSnippetNotification-empty-box-notifications|Styles applied to the box indicating that there are no notifications.|
 |list|.SCSnippetNotification-list|Styles applied to the list of notifications.|
 |item|.SCSnippetNotification-item|Styles applied to the single notification.|
 |broadcastMessagesBanner|.SCSnippetNotification-broadcast-messages-banner|Styles applied to the broadcast message banner.|

 * @param inProps
 */
function SnippetNotifications(inProps) {
    // PROPS
    const props = (0, system_1.useThemeProps)({
        props: inProps,
        name: constants_1.PREFIX
    });
    const { id = `snippetNotifications`, className, showMax = 20, handleCustomNotification, handleNotification, ScrollContainerProps = {}, onNotificationClick, onFetchNotifications } = props, rest = tslib_1.__rest(props, ["id", "className", "showMax", "handleCustomNotification", "handleNotification", "ScrollContainerProps", "onNotificationClick", "onFetchNotifications"]);
    // CONTEXT
    const scUserContext = (0, react_core_1.useSCUser)();
    const scRoutingContext = (0, react_core_1.useSCRouting)();
    // STATE
    const [notifications, setNotifications] = (0, react_1.useState)([]);
    const [initialized, setInitialized] = (0, react_1.useState)(false);
    const [loading, setLoading] = (0, react_1.useState)(false);
    // REFS
    const notificationSubscription = (0, react_1.useRef)(null);
    // Compute preferences
    const scPreferences = (0, react_core_1.useSCPreferences)();
    const preferences = (0, react_1.useMemo)(() => {
        const _preferences = {};
        PREFERENCES.map((p) => (_preferences[p] = p in scPreferences.preferences ? scPreferences.preferences[p].value : null));
        return _preferences;
    }, [scPreferences.preferences]);
    // HOOKS
    const intl = (0, react_intl_1.useIntl)();
    /**
     * Perform vote
     */
    const performFetchNotifications = (0, react_1.useMemo)(() => () => {
        return api_services_1.http
            .request({
            url: api_services_1.Endpoints.UserNotificationList.url(),
            method: api_services_1.Endpoints.UserNotificationList.method
        })
            .then((res) => {
            if (res.status >= 300) {
                return Promise.reject(res);
            }
            return Promise.resolve(res.data);
        });
    }, []);
    /**
     * Handles vote
     * @param comment
     */
    const fetchNotifications = (0, react_1.useMemo)(() => () => {
        setInitialized(true);
        if (!loading) {
            setLoading(true);
            performFetchNotifications()
                .then((data) => {
                setNotifications(data.results);
                setLoading(false);
                scUserContext.refreshCounters();
                onFetchNotifications && onFetchNotifications(data.results);
            })
                .catch((error) => {
                utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
            });
        }
    }, [loading, notifications.length, onFetchNotifications, setInitialized]);
    /**
     * Fetch notifications
     */
    (0, react_1.useEffect)(() => {
        let _t;
        if (scUserContext.user && !initialized) {
            _t = setTimeout(fetchNotifications);
            return () => {
                _t && clearTimeout(_t);
            };
        }
    }, [scUserContext.user, initialized]);
    /**
     * Notification subscriber
     * @param msg
     * @param data
     */
    const notificationSubscriber = (msg, data) => {
        /**
         * Ignore notifications of type: notification_banner
         * (data.data.activity_type === SCNotificationTypologyType.NOTIFICATION_BANNER)
         */
        if (data &&
            data.type === types_2.SCNotificationTopicType.INTERACTION &&
            react_core_1.SCNotification.SCNotificationMapping[data.data.activity_type] &&
            !react_core_1.SCNotification.SCSilentSnippetNotifications.includes(data.data.activity_type)) {
            if (data.data.notification_obj) {
                setNotifications([...[{ is_new: true, sid: '', aggregated: [data.data.notification_obj] }], ...notifications]);
            }
        }
    };
    const handleSingleNotificationClick = (e, n) => {
        if (onNotificationClick) {
            onNotificationClick(e, n);
        }
    };
    /**
     * On mount, fetches first page of notifications
     * On mount, subscribe to receive notification updates
     */
    (0, react_1.useEffect)(() => {
        if (!loading) {
            notificationSubscription.current = pubsub_js_1.default.subscribe(types_2.SCNotificationTopicType.INTERACTION, notificationSubscriber);
        }
        return () => {
            notificationSubscription.current && pubsub_js_1.default.unsubscribe(notificationSubscription.current);
        };
    }, [loading]);
    /**
     * Render every single notification in aggregated group
     * @param n
     * @param i
     */
    const renderAggregatedItem = (n, i) => {
        const type = n.type;
        let content;
        if (type === types_2.SCNotificationTypologyType.COMMENT || type === types_2.SCNotificationTypologyType.NESTED_COMMENT) {
            content = (0, jsx_runtime_1.jsx)(Comment_1.default, { notificationObject: n, index: i, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.FOLLOW) {
            content = (0, jsx_runtime_1.jsx)(ContributionFollow_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.USER_FOLLOW) {
            content = (0, jsx_runtime_1.jsx)(UserFollow_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.CONNECTION_REQUEST || type === types_2.SCNotificationTypologyType.CONNECTION_ACCEPT) {
            content = (0, jsx_runtime_1.jsx)(UserConnection_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.VOTE_UP) {
            content = (0, jsx_runtime_1.jsx)(VoteUp_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_ADVERTISING ||
            type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_AGGRESSIVE ||
            type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_POOR ||
            type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_VULGAR ||
            type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_OFFTOPIC) {
            content = (0, jsx_runtime_1.jsx)(KindlyNoticeFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_FLAG) {
            content = (0, jsx_runtime_1.jsx)(KindlyNoticeFlag_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.DELETED_FOR_ADVERTISING ||
            type === types_2.SCNotificationTypologyType.DELETED_FOR_AGGRESSIVE ||
            type === types_2.SCNotificationTypologyType.DELETED_FOR_POOR ||
            type === types_2.SCNotificationTypologyType.DELETED_FOR_VULGAR ||
            type === types_2.SCNotificationTypologyType.DELETED_FOR_OFFTOPIC) {
            content = (0, jsx_runtime_1.jsx)(DeletedFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.UNDELETED_FOR) {
            content = (0, jsx_runtime_1.jsx)(UndeletedFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_ADVERTISING ||
            type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_AGGRESSIVE ||
            type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_POOR ||
            type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_VULGAR ||
            type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_OFFTOPIC) {
            content = (0, jsx_runtime_1.jsx)(CollapsedFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.PRIVATE_MESSAGE) {
            content = (0, jsx_runtime_1.jsx)(PrivateMessage_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.BLOCKED_USER || type === types_2.SCNotificationTypologyType.UNBLOCKED_USER) {
            content = (0, jsx_runtime_1.jsx)(UserBlocked_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.MENTION) {
            content = (0, jsx_runtime_1.jsx)(Mention_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.INCUBATOR_APPROVED) {
            content = (0, jsx_runtime_1.jsx)(IncubatorApproved_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (type === types_2.SCNotificationTypologyType.CUSTOM_NOTIFICATION && handleCustomNotification) {
            content = handleCustomNotification(n);
        }
        else if (type === types_2.SCNotificationTypologyType.CONTRIBUTION) {
            content = (0, jsx_runtime_1.jsx)(Contribution_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (n.type === types_2.SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
            n.type === types_2.SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
            n.type === types_2.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
            n.type === types_2.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP) {
            return (0, jsx_runtime_1.jsx)(Group_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        else if (n.type === types_2.SCNotificationTypologyType.USER_ADDED_TO_EVENT ||
            n.type === types_2.SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT ||
            n.type === types_2.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT ||
            n.type === types_2.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) {
            return (0, jsx_runtime_1.jsx)(Event_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
        }
        if (type && handleNotification) {
            /** Override content */
            content = handleNotification(type, n, content);
        }
        return content;
    };
    /**
     * Renders root object
     */
    return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest, { children: (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.notificationsWrap }, { children: !initialized || loading ? ((0, jsx_runtime_1.jsx)(Skeleton_1.default, { elevation: 0 })) : ((0, jsx_runtime_1.jsx)(ScrollContainer_1.default, Object.assign({}, ScrollContainerProps, { children: (0, jsx_runtime_1.jsxs)(material_1.MenuList, Object.assign({ className: classes.list, disabledItemsFocusable: true, disableListWrap: true }, { children: [scUserContext.user.unseen_notification_banners_counter ? ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ className: (0, classnames_1.default)(classes.item, classes.broadcastMessagesBanner), component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}) }, { children: (0, jsx_runtime_1.jsx)(NotificationItem_1.default, { template: types_1.SCNotificationObjectTemplateType.SNIPPET, isNew: true, disableTypography: true, image: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: preferences[react_core_1.SCPreferences.TEXT_APPLICATION_NAME], src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO_MOBILE] }), primary: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div' }, { children: intl.formatMessage({ id: 'ui.snippetNotifications.broadcastMessages', defaultMessage: 'ui.snippetNotifications.broadcastMessages' }, {
                                        count: scUserContext.user.unseen_notification_banners_counter,
                                        b: (...chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks }),
                                        link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}) }, { children: chunks }))
                                    }) })) }) }), "banner")) : null, notifications.length === 0 ? ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ className: classes.emptyBoxNotifications }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.snippetNotifications.noNotifications", defaultMessage: "ui.snippetNotifications.noNotifications" }) }))) : (notifications.slice(0, showMax).map((notificationObject, i) => notificationObject.aggregated.map((n, k) => ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ className: classes.item, onClick: (e) => handleSingleNotificationClick(e, n), disableRipple: true, disableTouchRipple: true }, { children: renderAggregatedItem(n, i) }), k)))))] })) }))) })) })));
}
exports.default = SnippetNotifications;
