import React, { useContext, useState, useEffect } from "react";
import { format, differenceInMilliseconds, parseISO, addSeconds } from "date-fns";
// Context
import { NotificationsContext } from "../../../notificationsContext";
// Components
import NoNotifications from "../../NoNotifications";
import ContextMenuToggle from "../../../../common/ContextMenu";
import { getDefaultContextMenuActions } from "../../shared/notificationCard/NotificationCardHeaderControls";
import { CheckButton } from "../../shared/CheckButton";
// Utils
import { getActiveFilter, getMostRecentAction, isNewNotification, isReNotification, searchNotifications, } from "../../../utils";
import { NotificationCardHeaderLogo } from "../../shared/notificationCard/NotificationCardHeaderLogo";
// Constants
import { SelectionMode } from "../../../constants";
import { ErrorBoundary } from "../../../../common/ErrorBoundary";
import { FEAGlobals } from "../../../../../../common";
import { getNotificationsPreferences } from "../../../../userPreferences/components/content/notificationViews/notificationViewsUtils";
const ListHeaderComponent = () => (React.createElement("div", { className: "list-header__container" },
    React.createElement("div", { className: "list-header_cell" }, "Received"),
    React.createElement("div", { className: "list-header_cell" }, "App"),
    React.createElement("div", { className: "list-header_cell" }, "Content"),
    React.createElement("div", { className: "list-header_cell" }, "")));
export const NotificationListRowShell = ({ notification, newNotificationHaloPeriodSeconds, children, }) => {
    const notificationsContext = useContext(NotificationsContext);
    const { setSelectedNotification, muteFilters, selectionMode } = notificationsContext;
    const [isNew, setIsNew] = useState(isNewNotification(notification, newNotificationHaloPeriodSeconds));
    const [wokeFromSnooze, setWokeFromSnooze] = useState(isReNotification(notification, newNotificationHaloPeriodSeconds));
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const [isMuteFilterApplied, setIsMuteFilterApplied] = useState(muteFilters
        ? muteFilters.some((filter) => filter.source === notification.source && filter.type === notification.type)
        : false);
    // effect needed as the newNotificationHaloPeriodSeconds is fecthed asynchronously in the parent component
    // and sometimes at the first render, this value is still 0
    useEffect(() => {
        setIsNew(isNewNotification(notification, newNotificationHaloPeriodSeconds));
    }, [newNotificationHaloPeriodSeconds]);
    useEffect(() => {
        let isNewTimerId;
        if (isNew) {
            if (notification.isRead) {
                setIsNew(false);
                clearTimeout(isNewTimerId);
            }
            else {
                isNewTimerId = setTimeout(() => {
                    setIsNew(false);
                }, differenceInMilliseconds(addSeconds(parseISO(notification.issuedAt), newNotificationHaloPeriodSeconds), Date.now()));
            }
        }
        return () => {
            clearTimeout(isNewTimerId);
        };
    }, [isNew, notification]);
    useEffect(() => {
        let isRenotificationTimerId;
        if (isReNotification(notification, newNotificationHaloPeriodSeconds)) {
            const mostRecentAction = getMostRecentAction(notification);
            if (mostRecentAction) {
                const { datePerformed } = mostRecentAction;
                setWokeFromSnooze(true);
                isRenotificationTimerId = setTimeout(() => {
                    setWokeFromSnooze(false);
                }, differenceInMilliseconds(addSeconds(parseISO(datePerformed), newNotificationHaloPeriodSeconds), Date.now()));
            }
        }
        else {
            setWokeFromSnooze(false);
            clearTimeout(isRenotificationTimerId);
        }
        return () => {
            clearTimeout(isRenotificationTimerId);
        };
    }, [newNotificationHaloPeriodSeconds, notification]);
    const overFlowActions = getDefaultContextMenuActions();
    overFlowActions.DETAILS.action = (detailNotification) => {
        setSelectedNotification(detailNotification);
    };
    delete overFlowActions.DISMISS;
    // Don't display read if notification is read
    if (overFlowActions.MARK_AS_READ)
        overFlowActions.MARK_AS_READ.display = !notification.isRead;
    // Don't display unread if notification is unread
    if (overFlowActions.MARK_AS_UNREAD)
        overFlowActions.MARK_AS_UNREAD.display = !!notification.isRead;
    useEffect(() => {
        function listenMuteStateChanged(error, response) {
            if (error) {
                console.error("FinsembleNotificationsMuteStateChannel: ", error);
                FEAGlobals.FSBL.Clients.Logger.system.error("FinsembleNotificationsMuteStateChannel: ", error);
            }
            else {
                const { data } = response;
                if (notification.source === data.source && notification.type === data.type) {
                    setIsMuteFilterApplied(data.isMuted);
                }
            }
        }
        FEAGlobals.FSBL.Clients.RouterClient.addListener("FinsembleNotificationsMuteStateChannel", listenMuteStateChanged);
        return () => {
            FEAGlobals.FSBL.Clients.RouterClient.removeListener("FinsembleNotificationsMuteStateChannel", listenMuteStateChanged);
        };
    }, []);
    return (React.createElement("div", { className: `list-row__container notification-item ${notification.isRead ? "is-read" : ""} ${isNew || wokeFromSnooze ? "new" : ""}
				${notification.cssClassName ? notification.cssClassName : ""}` },
        children ? (React.createElement(React.Fragment, null,
            selectionMode === SelectionMode.SELECTION ? (React.createElement("div", { className: "list-row__cell" },
                React.createElement(CheckButton, { notification: notification }))) : (React.createElement(React.Fragment, null)),
            children)) : (React.createElement(React.Fragment, null,
            React.createElement("div", { className: "list-row__cell" }, format(Date.parse(notification.issuedAt), "dd-MM-yyyy HH:mm")),
            React.createElement("div", { className: "list-row__cell" }, selectionMode === SelectionMode.SELECTION ? (React.createElement("span", null,
                React.createElement(CheckButton, { notification: notification }))) : (React.createElement(NotificationCardHeaderLogo, { headerLogo: notification.headerLogo }))),
            React.createElement("div", { className: "list-row__cell" }, `${notification.title} - ${notification.details}`))),
        React.createElement("div", { className: "list-row__cell" },
            React.createElement("span", null,
                React.createElement(ContextMenuToggle, { menuActions: overFlowActions, message: notification, isMuteFilterApplied: false })))));
};
const ListView = ({ notificationHeaderRow, notificationListRow, notifications }) => {
    var _a;
    const notificationsContext = useContext(NotificationsContext);
    // The context will be used to filter the notifications
    const { drawerControlProps, searchString, filteredNotifications, setFilteredNotifications } = notificationsContext;
    const activeFilter = getActiveFilter(drawerControlProps);
    const [newNotificationHaloPeriodSeconds, setNotificationHaloPeriodSeconds] = useState(0);
    const NotificationHeaderRow = notificationHeaderRow || ListHeaderComponent;
    const NotificationListRow = notificationListRow || NotificationListRowShell;
    // Sets the current default preference
    useEffect(() => {
        getNotificationsPreferences().then((preferences) => {
            setNotificationHaloPeriodSeconds(preferences.newNotificationHaloPeriodSeconds);
        });
    }, []);
    useEffect(() => {
        if (searchString === "") {
            setFilteredNotifications(notifications);
        }
        else {
            setFilteredNotifications(searchNotifications(notifications, searchString));
        }
    }, [searchString, notifications]);
    let controlFilteredNotifications = activeFilter ? (_a = activeFilter.run) === null || _a === void 0 ? void 0 : _a.call(activeFilter, filteredNotifications) : [];
    controlFilteredNotifications.sort((a, b) => Date.parse(b.issuedAt) - Date.parse(a.issuedAt));
    controlFilteredNotifications = controlFilteredNotifications.filter((notification) => activeFilter.action === "snoozed" ? notification.isSnoozed : !notification.isSnoozed);
    return controlFilteredNotifications.length === 0 ? (React.createElement(NoNotifications, null)) : (React.createElement(React.Fragment, null,
        React.createElement(NotificationHeaderRow, null),
        controlFilteredNotifications.map((notification, index) => {
            const key = `${index}_${notification.id ? notification.id : notification.issuedAt}`;
            return (React.createElement(ErrorBoundary, { key: key },
                React.createElement(NotificationListRow, { key: key, notification: notification, newNotificationHaloPeriodSeconds: newNotificationHaloPeriodSeconds })));
        })));
};
export default ListView;
//# sourceMappingURL=ListView.js.map