'use client';
import React, { createContext, useCallback, useContext, useMemo, useReducer } from 'react';
import { DEFAULT_DURATION, DEFAULT_DURATION_WITH_ACTION, DEFAULT_TOAST_KEY_PREFIX } from './constants';
import { toasterReducer } from './reducers';
import { ToasterContainer } from './styled-components';
import { Toast } from './Toast';
import { CustomToast, ErrorToast, LoadingToast, SuccessToast } from './variants';
// This default value isn't used in practice, since we set it in the context
// provider. We still have to provide a default value that matches the correct
// signature though, so we provide a stub that does nothing
export const ToasterContext = createContext({
    closeAll: () => {
        // Do nothing
    },
    error: () => ({
        close: () => {
            // Do nothing
        },
    }),
    loading: () => ({
        close: () => {
            // Do nothing
        },
    }),
    success: () => ({
        close: () => {
            // Do nothing
        },
    }),
    custom: () => ({
        close: () => {
            // Do nothing
        },
    }),
});
let currentId = 0;
export const Toaster = ({ children }) => {
    const [toasts, dispatch] = useReducer(toasterReducer, []);
    const createToast = useCallback((contentBuilder, options = {}) => {
        if (!options.duration) {
            options.duration = options.action ? DEFAULT_DURATION_WITH_ACTION : DEFAULT_DURATION;
        }
        const id = currentId++;
        if (options.key) {
            dispatch({
                type: 'update',
                payload: {
                    isClosing: true,
                    key: options.key,
                },
            });
        }
        const key = options.key ?? `${DEFAULT_TOAST_KEY_PREFIX}${id}`;
        dispatch({
            type: 'add',
            payload: {
                action: options.action,
                contentBuilder,
                'data-tag': options['data-tag'],
                duration: options.duration,
                id,
                key,
            },
        });
        return {
            close: () => dispatch({
                type: 'update',
                payload: {
                    isClosing: true,
                    id,
                },
            }),
        };
    }, []);
    const toaster = useMemo(() => ({
        closeAll: () => dispatch({ type: 'closeAll' }),
        error: (content, options = {}) => createToast((setState) => (<ErrorToast action={options.action} setState={setState}>
              {content}
            </ErrorToast>), options),
        loading: (content, options = {}) => createToast((setState) => (<LoadingToast action={options.action} setState={setState}>
              {content}
            </LoadingToast>), { duration: 'infinite', ...options }),
        success: (content, options = {}) => createToast((setState) => (<SuccessToast action={options.action} setState={setState}>
              {content}
            </SuccessToast>), options),
        custom: (content, options = {}) => createToast((setState) => (<CustomToast showCloseButton={options.showCloseButton ?? true} setState={setState}>
              {content}
            </CustomToast>), options),
    }), [createToast]);
    return (<ToasterContext.Provider value={toaster}>
      {children}
      <ToasterContainer aria-live="polite" data-tag="toaster" data-overlay-dismiss="false">
        {toasts.map((toast) => (<Toast action={toast.action} data-tag={toast['data-tag']} duration={toast.duration} isClosing={toast.isClosing} key={`${toast.key}-${toast.id}`} onClose={() => dispatch({
                type: 'remove',
                payload: {
                    id: toast.id,
                },
            })} contentBuilder={toast.contentBuilder}/>))}
      </ToasterContainer>
    </ToasterContext.Provider>);
};
export const useToaster = () => useContext(ToasterContext);
/**
 * @deprecated Use `useToaster` in a function component instead
 */
export const ToasterConsumer = ToasterContext.Consumer;
//# sourceMappingURL=Toaster.jsx.map