import { __rest } from "tslib";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useState } from 'react';
import { styled } from '@mui/material/styles';
import CardContent from '@mui/material/CardContent';
import CommentNotification from './Comment';
import UserFollowNotification from './UserFollow';
import UndeletedForNotification from './UndeletedFor';
import DeletedForNotification from './DeletedFor';
import UserConnectionNotification from './UserConnection';
import PrivateMessageNotification from './PrivateMessage';
import UserBlockedNotification from './UserBlocked';
import MentionNotification from './Mention';
import CollapsedForNotification from './CollapsedFor';
import KindlyNoticeForNotification from './KindlyNoticeFor';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import KindlyNoticeFlagNotification from './KindlyNoticeFlag';
import VoteUpNotification from './VoteUp';
import Icon from '@mui/material/Icon';
import { SCOPE_SC_UI } from '../../constants/Errors';
import { getContribution, getContributionRouteName, getContributionSnippet, getRouteData } from '../../utils/contribution';
import ContributionFollowNotification from './ContributionFollow';
import { Avatar, CardHeader, Collapse, ListItemButton, ListItemText, Tooltip } from '@mui/material';
import IncubatorApprovedNotification from './IncubatorApproved';
import { Endpoints, http } from '@selfcommunity/api-services';
import { Link, SCRoutes, useSCRouting } from '@selfcommunity/react-core';
import ContributionNotification from './Contribution';
import classNames from 'classnames';
import LoadingButton from '@mui/lab/LoadingButton';
import Widget from '../Widget';
import { useThemeProps } from '@mui/system';
import { Logger } from '@selfcommunity/utils';
import { SCNotificationTypologyType } from '@selfcommunity/types';
import UserDeletedSnackBar from '../../shared/UserDeletedSnackBar';
import UserAvatar from '../../shared/UserAvatar';
import { PREFIX } from './constants';
import GroupNotification from './Group';
import EventNotification from './Event/Event';
const messages = defineMessages({
    receivePrivateMessage: {
        id: 'ui.notification.receivePrivateMessage',
        defaultMessage: 'ui.notification.receivePrivateMessage'
    }
});
const classes = {
    root: `${PREFIX}-root`,
    header: `${PREFIX}-header`,
    avatar: `${PREFIX}-avatar`,
    title: `${PREFIX}-title`,
    image: `${PREFIX}-image`,
    username: `${PREFIX}-username`,
    content: `${PREFIX}-content`,
    unCollapsed: `${PREFIX}-uncollapsed`,
    collapsed: `${PREFIX}-collapsed`,
    stopButton: `${PREFIX}-stop-button`,
    showOtherAggregated: `${PREFIX}-show-other-aggregated`
};
const Root = styled(Widget, {
    name: PREFIX,
    slot: 'Root'
})(() => ({}));
/**
 *
 > API documentation for the Community-JS UserNotification component. Learn about the available props and the CSS API.

 #### Import

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

 #### Component Name

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


 #### CSS

 |Rule Name|Global class|Description|
 |---|---|---|
 |root|.SCNotification-root|Styles applied to the root element.|
 |content|.SCNotification-notification-wrap|Styles applied to the element wrap.|
 |header|.SCNotification-notification-wrap|Styles applied to the notification header.|
 |title|.SCNotification-title|Styles applied to the title element in the notification header.|
 |image|.SCNotification-image|Styles applied to the image element in the notification header.|
 |username|.SCNotification-username|Styles applied to the user element in the notification header.|
 |content|.SCNotification-notification-content|Styles applied to the notification content.|
 |unCollapsed|.SCNotification-notification-wrap|Styles applied to the uncollapsed elements.|
 |collapsed|.SCNotification-notification-wrap|Styles applied to the collapsed elements.|
 |stopButton|.SCNotification-stop-notification-button|Styles applied to the stop notification button.|
 |showOtherAggregated|.SCNotification-show-other-aggregated|Styles applied to the show other aggregated element.|

 * @param inProps
 */
export default function UserNotification(inProps) {
    // PROPS
    const props = useThemeProps({
        props: inProps,
        name: PREFIX
    });
    const { id = `notification_${props.notificationObject.sid}`, className, notificationObject, handleCustomNotification, showMaxAggregated = 2, collapsedOtherAggregated = true, onStateChange, onHeightChange } = props, rest = __rest(props, ["id", "className", "notificationObject", "handleCustomNotification", "showMaxAggregated", "collapsedOtherAggregated", "onStateChange", "onHeightChange"]);
    // ROUTING
    const scRoutingContext = useSCRouting();
    // STATE
    const [obj, setObj] = useState(notificationObject);
    const [loadingSuspendNotification, setLoadingSuspendNotification] = useState(false);
    const [openOtherAggregated, setOpenOtherAggregated] = useState(!collapsedOtherAggregated);
    const [openAlert, setOpenAlert] = useState(false);
    //INTL
    const intl = useIntl();
    /**
     * Notify changes to Feed if the FeedObject is contained in the feed
     */
    const notifyFeedChanges = useMemo(() => (state) => {
        if (onStateChange && state) {
            onStateChange(state);
        }
        onHeightChange && onHeightChange();
    }, [onStateChange, onHeightChange]);
    /**
     * Performs  notification suspension
     */
    const performSuspendNotification = useMemo(() => (obj) => {
        return http
            .request({
            url: Endpoints.UserSuspendContributionNotification.url({ type: obj.type, id: obj.id }),
            method: Endpoints.UserSuspendContributionNotification.method
        })
            .then((res) => {
            if (res.status >= 300) {
                return Promise.reject(res);
            }
            return Promise.resolve(res.data);
        });
    }, [obj]);
    /**
     * Handles stop notification for contribution
     * @param contribution
     */
    function handleStopContentNotification(contribution) {
        setLoadingSuspendNotification(true);
        performSuspendNotification(contribution)
            .then((data) => {
            const newObj = obj;
            newObj[contribution.type].suspended = !newObj[contribution.type].suspended;
            setObj(newObj);
            setLoadingSuspendNotification(false);
        })
            .catch((error) => {
            Logger.error(SCOPE_SC_UI, error);
        });
    }
    /**
     * Handles vote
     * @param index
     */
    const handleVote = (index) => {
        return (contribution) => {
            const newObj = Object.assign({}, notificationObject);
            const _notification = Object.assign({}, newObj.aggregated[index]);
            _notification[contribution.type] = contribution;
            newObj.aggregated[index] = _notification;
            setObj(newObj);
        };
    };
    /**
     * Open/close other aggregated activities
     * The layout change -> call onStateChange
     */
    function setStateAggregated() {
        const _openOtherAggregated = !openOtherAggregated;
        notifyFeedChanges({ collapsedOtherAggregated: _openOtherAggregated });
        setOpenOtherAggregated(_openOtherAggregated);
    }
    /**
     * Render:
     * - discussion/post/status summary if notification include contribute
     * - user header for private message
     */
    function renderNotificationHeader() {
        /**
         * Private messages header
         */
        if (notificationObject.aggregated && notificationObject.aggregated[0].type === SCNotificationTypologyType.PRIVATE_MESSAGE) {
            let messageNotification = notificationObject.aggregated[0];
            return (_jsx(CardHeader, { className: classes.header, avatar: _jsx(Link, Object.assign({}, (!messageNotification.message.sender.deleted && {
                    to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, messageNotification.message.sender)
                }), { onClick: messageNotification.message.sender.deleted ? () => setOpenAlert(true) : null }, { children: _jsx(UserAvatar, Object.assign({ hide: !messageNotification.message.sender.community_badge, smaller: true }, { children: _jsx(Avatar, { className: classes.avatar, alt: messageNotification.message.sender.username, variant: "circular", src: messageNotification.message.sender.avatar }) })) })), titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: _jsxs(_Fragment, { children: [_jsx(Link, Object.assign({}, (!messageNotification.message.sender.deleted && {
                            to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, messageNotification.message.sender)
                        }), { onClick: messageNotification.message.sender.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: messageNotification.message.sender.username })), ' ', intl.formatMessage(messages.receivePrivateMessage, {
                            total: notificationObject.aggregated.length,
                            b: (...chunks) => _jsx("strong", { children: chunks })
                        })] }) }));
        }
        /**
         * Group notifications header
         */
        if (notificationObject.aggregated &&
            (notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP)) {
            let groupNotification = notificationObject.aggregated[0];
            return (_jsx(CardHeader, { className: classes.header, avatar: _jsx(Link, Object.assign({}, (!groupNotification.user.deleted && {
                    to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
                }), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null }, { children: _jsx(UserAvatar, Object.assign({ hide: !groupNotification.user.community_badge, smaller: true }, { children: _jsx(Avatar, { className: classes.avatar, alt: groupNotification.user.username, variant: "circular", src: groupNotification.user.avatar }) })) })), titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: _jsxs(_Fragment, { children: [_jsx(Link, Object.assign({}, (!groupNotification.user.deleted && {
                            to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
                        }), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: groupNotification.user.username })), ' ', _jsx(FormattedMessage, { id: `ui.notification.${notificationObject.aggregated[0].type}`, defaultMessage: `ui.notification.${notificationObject.aggregated[0].type}`, values: {
                                group: groupNotification.group.name,
                                link: (...chunks) => (_jsx(Link, Object.assign({ to: notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP ||
                                        notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP
                                        ? scRoutingContext.url(SCRoutes.GROUP_MEMBERS_ROUTE_NAME, groupNotification.group)
                                        : scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, groupNotification.group) }, { children: chunks })))
                            } })] }) }));
        }
        /**
         * Comment, NestedComment, Follow Contribution header
         */
        if (notificationObject.aggregated &&
            (notificationObject.aggregated[0].type === SCNotificationTypologyType.COMMENT ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.NESTED_COMMENT ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.FOLLOW ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.MENTION ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.VOTE_UP ||
                notificationObject.aggregated[0].type === SCNotificationTypologyType.CONTRIBUTION)) {
            const contribution = getContribution(notificationObject);
            return (_jsx(CardHeader, { className: classes.header, titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: _jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(contribution), getRouteData(notificationObject[contribution.type])) }, { children: getContributionSnippet(contribution) })), action: contribution && (_jsx(Tooltip, Object.assign({ title: contribution.suspended ? (_jsx(FormattedMessage, { id: 'ui.notification.notificationSuspended', defaultMessage: 'ui.notification.notificationSuspended' })) : (_jsx(FormattedMessage, { id: 'ui.notification.notificationSuspend', defaultMessage: 'ui.notification.notificationSuspend' })) }, { children: _jsx(LoadingButton, Object.assign({ variant: "text", size: "small", loading: loadingSuspendNotification, color: 'inherit', classes: { root: classes.stopButton }, onClick: () => handleStopContentNotification(contribution) }, { children: contribution.suspended ? _jsx(Icon, Object.assign({ color: 'primary' }, { children: "notifications_off" })) : _jsx(Icon, Object.assign({ color: 'inherit' }, { children: "notifications" })) })) }))) }));
        }
        return null;
    }
    /**
     * Render every single notification in aggregated group
     * @param n
     * @param i
     */
    function renderAggregatedItem(n, i) {
        if (n.type === SCNotificationTypologyType.COMMENT || n.type === SCNotificationTypologyType.NESTED_COMMENT) {
            return _jsx(CommentNotification, { notificationObject: n, onVote: handleVote(i) }, i);
        }
        else if (n.type === SCNotificationTypologyType.FOLLOW) {
            return _jsx(ContributionFollowNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.USER_FOLLOW) {
            return _jsx(UserFollowNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.CONNECTION_REQUEST || n.type === SCNotificationTypologyType.CONNECTION_ACCEPT) {
            return _jsx(UserConnectionNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.VOTE_UP) {
            return _jsx(VoteUpNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.KINDLY_NOTICE_ADVERTISING ||
            n.type === SCNotificationTypologyType.KINDLY_NOTICE_AGGRESSIVE ||
            n.type === SCNotificationTypologyType.KINDLY_NOTICE_POOR ||
            n.type === SCNotificationTypologyType.KINDLY_NOTICE_VULGAR ||
            n.type === SCNotificationTypologyType.KINDLY_NOTICE_OFFTOPIC) {
            return _jsx(KindlyNoticeForNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.KINDLY_NOTICE_FLAG) {
            return _jsx(KindlyNoticeFlagNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.DELETED_FOR_ADVERTISING ||
            n.type === SCNotificationTypologyType.DELETED_FOR_AGGRESSIVE ||
            n.type === SCNotificationTypologyType.DELETED_FOR_POOR ||
            n.type === SCNotificationTypologyType.DELETED_FOR_VULGAR ||
            n.type === SCNotificationTypologyType.DELETED_FOR_OFFTOPIC) {
            return _jsx(DeletedForNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.UNDELETED_FOR) {
            return _jsx(UndeletedForNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.COLLAPSED_FOR_ADVERTISING ||
            n.type === SCNotificationTypologyType.COLLAPSED_FOR_AGGRESSIVE ||
            n.type === SCNotificationTypologyType.COLLAPSED_FOR_POOR ||
            n.type === SCNotificationTypologyType.COLLAPSED_FOR_VULGAR ||
            n.type === SCNotificationTypologyType.COLLAPSED_FOR_OFFTOPIC) {
            return _jsx(CollapsedForNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.PRIVATE_MESSAGE) {
            return _jsx(PrivateMessageNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.BLOCKED_USER || n.type === SCNotificationTypologyType.UNBLOCKED_USER) {
            return _jsx(UserBlockedNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.MENTION) {
            return _jsx(MentionNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.INCUBATOR_APPROVED) {
            return _jsx(IncubatorApprovedNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.CUSTOM_NOTIFICATION) {
            handleCustomNotification && handleCustomNotification(n);
        }
        else if (n.type === SCNotificationTypologyType.CONTRIBUTION) {
            return _jsx(ContributionNotification, { notificationObject: n, onVote: handleVote(i) }, i);
        }
        else if (n.type === SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
            n.type === SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
            n.type === SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
            n.type === SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP) {
            return _jsx(GroupNotification, { notificationObject: n }, i);
        }
        else if (n.type === SCNotificationTypologyType.USER_ADDED_TO_EVENT ||
            n.type === SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT ||
            n.type === SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT ||
            n.type === SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) {
            return _jsx(EventNotification, { notificationObject: n }, i);
        }
        return null;
    }
    /**
     * Renders root object
     */
    return (_jsxs(_Fragment, { children: [_jsxs(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest, { children: [renderNotificationHeader(), _jsxs(CardContent, Object.assign({ className: classes.content }, { children: [_jsx("div", Object.assign({ className: classes.unCollapsed }, { children: notificationObject.aggregated.slice(0, showMaxAggregated).map((n, i) => renderAggregatedItem(n, i)) })), notificationObject.aggregated.length > showMaxAggregated && (_jsxs(_Fragment, { children: [_jsxs(ListItemButton, Object.assign({ onClick: setStateAggregated, classes: { root: classes.showOtherAggregated } }, { children: [_jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: 'ui.notification.showOthers', defaultMessage: 'ui.notification.showOthers' }) }), openOtherAggregated ? _jsx(Icon, { children: "expand_less" }) : _jsx(Icon, { children: "expand_more" })] })), _jsx(Collapse, Object.assign({ in: openOtherAggregated, timeout: "auto", unmountOnExit: true, classes: { root: classes.collapsed } }, { children: notificationObject.aggregated.slice(showMaxAggregated).map((n, i) => renderAggregatedItem(n, i)) }))] }))] }))] })), openAlert && _jsx(UserDeletedSnackBar, { open: openAlert, handleClose: () => setOpenAlert(false) })] }));
}
