import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useContext, useReducer, useMemo } from 'react';
import { createUID, windowIsAvailable } from '../../utils';
import { useI18n } from '../../hooks';
import { StyledLog } from './LiveLog.styles';
import { LiveLogContext } from './Context';
const reducer = (state, action) => {
    const type = action.type;
    switch (type) {
        case 'announce': {
            const message = action.payload.message;
            const messageType = action.payload.type;
            const announceMessage = ['alert', 'error', 'exception'].includes(messageType) ||
                !state.suppressedTypes.includes(messageType);
            if (announceMessage) {
                const id = createUID();
                if (action.payload.level === 'assertive') {
                    return {
                        ...state,
                        assertiveMessages: [...state.assertiveMessages, { message, id }]
                    };
                }
                return {
                    ...state,
                    politeMessages: [...state.politeMessages, { message, id }]
                };
            }
            return state;
        }
        case 'setMaxLength': {
            return {
                ...state,
                maxLength: action.payload > 0 ? action.payload : 15
            };
        }
        case 'trimLength': {
            const trimPolite = state.politeMessages.length > state.maxLength;
            const trimAssertive = state.assertiveMessages.length > state.maxLength;
            return {
                ...state,
                politeMessages: trimPolite
                    ? [...state.politeMessages.slice(-state.maxLength)]
                    : state.politeMessages,
                assertiveMessages: trimAssertive
                    ? [...state.assertiveMessages.slice(-state.maxLength)]
                    : state.assertiveMessages
            };
        }
        default:
            return state;
    }
};
const LiveLog = ({ children, maxLength = 15 }) => {
    const t = useI18n();
    const [state, dispatch] = useReducer(reducer, {
        maxLength,
        politeMessages: [],
        assertiveMessages: [],
        suppressedTypes: [] // initialize via a11y settings once available.
    });
    // Manage log length.
    useEffect(() => {
        const timeout = setTimeout(() => {
            dispatch({ type: 'trimLength' });
        }, 1000);
        return () => {
            clearTimeout(timeout);
        };
    }, [state.assertiveMessages, state.politeMessages, state.maxLength]);
    // Update max length
    useEffect(() => {
        dispatch({ type: 'setMaxLength', payload: maxLength });
    }, [maxLength]);
    const providerValue = useMemo(() => ({
        announce: ({ message, type = 'info', assertive = false }) => {
            dispatch({
                type: 'announce',
                payload: { message, type, level: assertive ? 'assertive' : 'polite' }
            });
        },
        announcePolite: ({ message, type = 'info' }) => {
            dispatch({ type: 'announce', payload: { message, type, level: 'polite' } });
        },
        announceAssertive: ({ message, type = 'info' }) => {
            dispatch({ type: 'announce', payload: { message, type, level: 'assertive' } });
        },
        initialized: true
    }), []);
    // Don't create additional LiveLogContext.Providers.
    const context = windowIsAvailable
        ? window.cosmos.liveLogContext ?? LiveLogContext
        : LiveLogContext;
    const priorCtx = useContext(context);
    if (priorCtx.initialized) {
        return _jsx(context.Provider, { value: priorCtx, children: children });
    }
    return (_jsxs(context.Provider, { value: providerValue, children: [children, _jsxs(StyledLog, { role: 'log', "aria-relevant": 'additions', children: [_jsx("h6", { children: t('polite_announcements') }), state.politeMessages.map(({ message, id }) => (_jsx("p", { children: message }, id)))] }), _jsxs(StyledLog, { role: 'log', "aria-live": 'assertive', "aria-relevant": 'additions', children: [_jsx("h6", { children: t('assertive_announcements') }), state.assertiveMessages.map(({ message, id }) => (_jsx("p", { children: message }, id)))] })] }));
};
export default LiveLog;
//# sourceMappingURL=LiveLog.js.map