// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useMemo, useRef, useState } from 'react';
import { useMergeRefs } from '@cloudscape-design/component-toolkit/internal';
import { useInternalI18n } from '../../../i18n/context';
import FeaturePrompt from '../../../internal/do-not-use/feature-prompt';
import { persistFeatureNotifications, retrieveFeatureNotifications } from '../../../internal/persistence';
import { useMountRefPromise } from '../../../internal/utils/promises';
import RuntimeFeaturesNotificationDrawer, { RuntimeContentPart } from '../drawer/feature-notifications-drawer-content';
const DEFAULT_PERSISTENCE_CONFIG = {
    uniqueKey: 'awsui-feature-notifications',
};
const FEATURE_NOTIFICATIONS_RETENTION_DAYS = 180;
const DEFAULT_FEATURE_FILTER_DAYS = 90;
function subtractDaysFromDate(currentDate, daysToSubtract = 0) {
    const pastDate = new Date(currentDate);
    pastDate.setDate(pastDate.getDate() - daysToSubtract);
    return pastDate;
}
function filterOutdatedFeatures(features) {
    const cutoffDate = subtractDaysFromDate(new Date(), FEATURE_NOTIFICATIONS_RETENTION_DAYS);
    return Object.keys(features).reduce((acc, key) => {
        const featureDate = new Date(features[key]);
        if (featureDate && featureDate >= cutoffDate) {
            return {
                ...acc,
                [key]: features[key],
            };
        }
        return acc;
    }, {});
}
export function useFeatureNotifications() {
    const i18n = useInternalI18n('features-notification-drawer');
    const [featurePromptDismissed, setFeaturePromptDismissed] = useState(false);
    const [featureNotificationsData, setFeatureNotificationsData] = useState(null);
    const [seenFeatures, setSeenFeatures] = useState({});
    const featurePromptRef = useRef(null);
    const { ref: featurePromptMountRef, promise: featurePromptMountPromise } = useMountRefPromise();
    const featurePromptMergedRef = useMergeRefs(featurePromptRef, featurePromptMountRef);
    const allNotificationsSeen = useMemo(() => {
        return featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.features.every(feature => !!seenFeatures[feature.id]);
    }, [featureNotificationsData, seenFeatures]);
    const defaultFeaturesFilter = (feature) => {
        return feature.releaseDate >= subtractDaysFromDate(new Date(), DEFAULT_FEATURE_FILTER_DAYS);
    };
    const getFeaturesToDisplay = (payload) => {
        return payload.features
            .slice()
            .filter(payload.filterFeatures ? payload.filterFeatures : defaultFeaturesFilter)
            .sort((a, b) => b.releaseDate.getTime() - a.releaseDate.getTime());
    };
    const mapPayloadToDrawer = (payload) => {
        var _a, _b, _c, _d, _e;
        return {
            id: payload.id,
            content: (React.createElement(RuntimeFeaturesNotificationDrawer, { features: payload.features, featuresPageLink: payload.featuresPageLink, mountItem: payload.mountItem, i18nStrings: payload.i18nStrings })),
            trigger: {
                iconSvg: (React.createElement("svg", { viewBox: "0 0 16 16", xmlns: "http://www.w3.org/2000/svg", focusable: "false", "aria-hidden": "true" },
                    React.createElement("path", { d: "M7 4L14.3244 1.25334C14.6513 1.13076 15 1.3724 15 1.7215V13.2785C15 13.6276 14.6513 13.8692 14.3244 13.7467L7 11" }),
                    React.createElement("path", { d: "M1 6C1 4.89543 1.89543 4 3 4H7V11H3C1.89543 11 1 10.1046 1 9V6Z" }),
                    React.createElement("path", { d: "M9.93649 12.1466C9.66614 13.4393 8.51989 14.4102 7.14687 14.4102C5.57286 14.4102 4.29688 13.1342 4.29688 11.5602C4.29688 11.3685 4.31579 11.1813 4.35187 11.0002" }))),
            },
            ariaLabels: {
                closeButton: i18n('ariaLabels.closeButton', (_a = payload.i18nStrings) === null || _a === void 0 ? void 0 : _a.closeButtonAriaLabel),
                drawerName: (_c = i18n('ariaLabels.content', (_b = payload.i18nStrings) === null || _b === void 0 ? void 0 : _b.contentAriaLabel)) !== null && _c !== void 0 ? _c : '',
                triggerButton: i18n('ariaLabels.triggerButton', (_d = payload.i18nStrings) === null || _d === void 0 ? void 0 : _d.triggerButtonAriaLabel),
                resizeHandle: i18n('ariaLabels.resizeHandle', (_e = payload.i18nStrings) === null || _e === void 0 ? void 0 : _e.resizeHandleAriaLabel),
            },
            resizable: true,
            defaultSize: 320,
            badge: payload.badge,
        };
    };
    function featureNotificationsMessageHandler(event) {
        var _a, _b;
        if (event.type === 'registerFeatureNotifications') {
            const { payload } = event;
            const features = getFeaturesToDisplay(payload);
            if (features.length === 0) {
                return;
            }
            setFeatureNotificationsData({ ...payload, features });
            const persistenceConfig = (_a = payload.persistenceConfig) !== null && _a !== void 0 ? _a : DEFAULT_PERSISTENCE_CONFIG;
            // Retrieve previously seen feature notifications from persistence to determine
            // which features the user has already viewed
            ((payload === null || payload === void 0 ? void 0 : payload.__retrieveFeatureNotifications) || retrieveFeatureNotifications)(persistenceConfig).then(seenFeatureNotifications => {
                var _a;
                setSeenFeatures(seenFeatureNotifications);
                const hasUnseenFeatures = features.some(feature => !seenFeatureNotifications[feature.id]);
                if (hasUnseenFeatures) {
                    const latestFeature = (_a = features.find(feature => !seenFeatureNotifications[feature.id])) !== null && _a !== void 0 ? _a : null;
                    if (!payload.suppressFeaturePrompt &&
                        !featurePromptDismissed &&
                        !seenFeatureNotifications[getFeaturePromptPersistenceId(latestFeature)]) {
                        featurePromptMountPromise.then(() => {
                            var _a;
                            (_a = featurePromptRef.current) === null || _a === void 0 ? void 0 : _a.show();
                        });
                    }
                    setFeatureNotificationsData(data => (data ? { ...data, badge: true } : data));
                }
            });
            return;
        }
        if (event.type === 'showFeaturePromptIfPossible' && !allNotificationsSeen) {
            (_b = featurePromptRef.current) === null || _b === void 0 ? void 0 : _b.show();
            return;
        }
        if (event.type === 'clearFeatureNotifications') {
            setFeatureNotificationsData(null);
            return;
        }
    }
    function getLatestUnseenFeature() {
        var _a;
        return (_a = featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.features.find(feature => !seenFeatures[feature.id])) !== null && _a !== void 0 ? _a : null;
    }
    function renderLatestFeaturePrompt({ triggerRef }) {
        const latestFeature = getLatestUnseenFeature();
        if (!triggerRef.current || !latestFeature) {
            return null;
        }
        return (React.createElement(FeaturePrompt, { ref: featurePromptMergedRef, onShow: () => {
                triggerRef.current.dataset.awsuiSuppressTooltip = 'true';
            }, onDismiss: event => {
                var _a;
                if (((_a = event.detail) === null || _a === void 0 ? void 0 : _a.method) !== 'blur') {
                    triggerRef === null || triggerRef === void 0 ? void 0 : triggerRef.current.focus();
                }
                setFeaturePromptDismissed(true);
                Promise.resolve().then(() => {
                    var _a;
                    if ((_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.dataset) {
                        triggerRef.current.dataset.awsuiSuppressTooltip = 'false';
                    }
                });
                persistFeaturePromptDismiss(latestFeature);
            }, header: React.createElement(RuntimeContentPart, { mountContent: featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.mountItem, content: latestFeature.header }), content: React.createElement(RuntimeContentPart, { mountContent: featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.mountItem, content: latestFeature.content }), trackKey: latestFeature.id, position: "left", getTrack: () => triggerRef.current }));
    }
    const setFeaturesToSeenAndPersist = () => {
        var _a, _b;
        const persistenceConfig = (_a = featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.persistenceConfig) !== null && _a !== void 0 ? _a : DEFAULT_PERSISTENCE_CONFIG;
        const featuresMap = featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.features.reduce((acc, feature) => {
            return {
                ...acc,
                [feature.id]: feature.releaseDate,
            };
        }, {});
        const filteredSeenFeaturesMap = filterOutdatedFeatures(seenFeatures);
        const allFeaturesMap = { ...featuresMap, ...filteredSeenFeaturesMap };
        ((_b = featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.__persistFeatureNotifications) !== null && _b !== void 0 ? _b : persistFeatureNotifications)(persistenceConfig, allFeaturesMap).then(() => {
            setSeenFeatures(allFeaturesMap);
            setFeatureNotificationsData(data => (data ? { ...data, badge: false } : data));
        });
    };
    const getFeaturePromptPersistenceId = (feature) => `${feature === null || feature === void 0 ? void 0 : feature.id}_feature-prompt`;
    const persistFeaturePromptDismiss = (feature) => {
        var _a, _b, _c;
        const persistenceConfig = (_a = featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.persistenceConfig) !== null && _a !== void 0 ? _a : DEFAULT_PERSISTENCE_CONFIG;
        const featuresMap = { [getFeaturePromptPersistenceId(feature)]: (_b = feature.releaseDate) === null || _b === void 0 ? void 0 : _b.toString() };
        const filteredSeenFeaturesMap = filterOutdatedFeatures(seenFeatures);
        const allFeaturesMap = { ...featuresMap, ...filteredSeenFeaturesMap };
        ((_c = featureNotificationsData === null || featureNotificationsData === void 0 ? void 0 : featureNotificationsData.__persistFeatureNotifications) !== null && _c !== void 0 ? _c : persistFeatureNotifications)(persistenceConfig, allFeaturesMap).then(() => {
            setSeenFeatures(allFeaturesMap);
        });
    };
    const onOpenFeatureNotificationsDrawer = () => {
        if (!featureNotificationsData || allNotificationsSeen) {
            return;
        }
        setFeaturesToSeenAndPersist();
    };
    const featureNotificationsProps = {
        renderLatestFeaturePrompt,
        drawer: featureNotificationsData && mapPayloadToDrawer(featureNotificationsData),
    };
    return {
        featureNotificationsProps,
        onOpenFeatureNotificationsDrawer,
        featureNotificationsMessageHandler,
    };
}
//# sourceMappingURL=use-feature-notifications.js.map