import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/*
 * Copyright (c) 2023-2025 Datalayer, Inc.
 * Distributed under the terms of the Modified BSD License.
 */
import React from 'react';
import { toast } from 'react-toastify';
import { Notification } from '@jupyterlab/apputils';
import { Button } from '@primer/react';
import { JupyterReactTheme } from '@datalayer/jupyter-react';
import { isInsideJupyterLab } from '../utils/index.js';
const TOAST_POSITION = 'bottom-right';
const THEME_STORAGE_KEY = 'datalayer-theme';
function resolveToastTheme() {
    if (typeof window === 'undefined') {
        return 'dark';
    }
    let preferredMode;
    try {
        const raw = window.localStorage.getItem(THEME_STORAGE_KEY);
        if (raw) {
            const parsed = JSON.parse(raw);
            preferredMode = parsed?.state?.colorMode;
        }
    }
    catch {
        // Ignore parsing/storage access errors and fall back to media query.
    }
    if (preferredMode === 'light') {
        return 'light';
    }
    if (preferredMode === 'dark') {
        return 'dark';
    }
    const systemPrefersDark = window.matchMedia?.('(prefers-color-scheme: dark)')?.matches;
    return systemPrefersDark ? 'dark' : 'light';
}
const displayType2Class = {
    accent: 'primary',
    link: 'invisible',
    warn: 'danger',
    default: 'default',
};
/**
 * Create a button with customized callback in a toast
 */
function ToastButton({ action, closeToast }) {
    const clickHandler = (event) => {
        action.callback(event);
        if (!event.defaultPrevented) {
            closeToast();
        }
    };
    return (_jsx(Button, { title: action.caption ?? action.label, onClick: clickHandler, variant: displayType2Class[action.displayType ?? 'default'], size: "small", children: action.label }));
}
/**
 * Helper function to construct the notification content
 *
 * @param message Message to print in the notification
 * @param closeHandler Function closing the notification
 * @param actions Toast actions
 */
function createContent(message, closeHandler, actions) {
    return (_jsxs(_Fragment, { children: [_jsx("div", { className: "jp-toast-message", children: message.split('\n').map((part, index) => (_jsxs(React.Fragment, { children: [index > 0 ? _jsx("br", {}) : null, part] }, `part-${index}`))) }), (actions?.length ?? 0) > 0 && (_jsxs("div", { className: "jp-toast-buttonBar", children: [_jsx("div", { className: "jp-toast-spacer" }), actions.map((action, idx) => {
                        return (_jsx(JupyterReactTheme, { children: _jsx(ToastButton, { action: action, closeToast: closeHandler }, 'button-' + idx) }));
                    })] }))] }));
}
export const useToast = () => {
    // This CANNOT use Jupyter React hooks as it may be used outside Jupyter React context.
    const insideJupyterLab = isInsideJupyterLab();
    const enqueueToast = (message, options = { variant: 'info' }) => {
        const { actions, autoClose } = options;
        const theme = resolveToastTheme();
        switch (options.variant) {
            case 'info': {
                return insideJupyterLab
                    ? Notification.info(message, {
                        autoClose: autoClose ?? 5000,
                        actions,
                    })
                    : toast.info(({ closeToast }) => createContent(message, () => {
                        if (closeToast)
                            closeToast();
                    }, actions), { autoClose, position: TOAST_POSITION, theme });
            }
            case 'success': {
                return insideJupyterLab
                    ? Notification.success(message, {
                        autoClose: autoClose ?? 5000,
                        actions,
                    })
                    : toast.success(({ closeToast }) => createContent(message, () => {
                        if (closeToast)
                            closeToast();
                    }, actions), { autoClose, position: TOAST_POSITION, theme });
            }
            case 'warning': {
                return insideJupyterLab
                    ? Notification.warning(message, {
                        autoClose: autoClose ?? false,
                        actions,
                    })
                    : toast.warning(({ closeToast }) => createContent(message, () => {
                        if (closeToast)
                            closeToast();
                    }, actions), {
                        autoClose: autoClose ?? false,
                        position: TOAST_POSITION,
                        theme,
                    });
            }
            case 'error': {
                return insideJupyterLab
                    ? Notification.error(message, {
                        autoClose: autoClose ?? false,
                        actions,
                    })
                    : toast.error(({ closeToast }) => createContent(message, () => {
                        if (closeToast)
                            closeToast();
                    }, actions), {
                        autoClose: autoClose ?? false,
                        position: TOAST_POSITION,
                        theme,
                    });
            }
        }
    };
    const trackAsyncTask = (promise, options) => {
        const theme = resolveToastTheme();
        return insideJupyterLab
            ? Notification.promise(promise, options)
            : toast.promise(promise, {
                error: { render: options.error.message, ...options.error.options },
                pending: options.pending.message,
                success: {
                    render: options.success.message,
                    ...options.success.options,
                },
            }, {
                position: TOAST_POSITION,
                theme,
                ...options.pending.options,
            });
    };
    return Object.freeze({
        /**
         * Emit a message as a toast.
         *
         * @param message Toast message
         * @param options Toast option
         * @returns Toast id
         */
        enqueueToast,
        /**
         * Dismiss a toast
         *
         * @param id Toast id
         */
        dismiss: (id) => {
            if (insideJupyterLab) {
                Notification.dismiss(id);
            }
            else {
                toast.dismiss(id);
            }
        },
        /**
         * Track the progress of an asynchronous task
         * and display a message depending on the outcome.
         *
         * @param promise Asynchronous task
         * @param options Task progress options
         * @returns Toast id
         */
        trackAsyncTask,
    });
};
export default useToast;
