import { jsxs, jsx } from "react/jsx-runtime";
import React, { useState, useRef, useCallback, useEffect, cloneElement } from "react";
import assert from "assert";
import { Stack } from "../Stack/Stack.mjs";
import { Text, Inline, IconClear, IconCritical, IconPositive } from "../Accordion/AccordionItem.mjs";
import { Columns } from "../Columns/Columns.mjs";
import { Column } from "../Column/Column.mjs";
import { ContentBlock } from "../ContentBlock/ContentBlock.mjs";
import { Box } from "../Box/Box.mjs";
import { TextLinkButton } from "../private/Placeholder/Placeholder.mjs";
import { ButtonIcon } from "../ButtonIcon/ButtonIcon.mjs";
import { lineHeightContainer } from "../../css/lineHeightContainer.css.mjs";
import { buildDataAttributes } from "../Accordion/Accordion.mjs";
import { toast } from "./Toast.css.mjs";
const useTimeout = ({ onTimeout, duration }) => {
  const [activated, setActivated] = useState(true);
  const timeoutRef = useRef();
  const stopTimeout = useCallback(() => {
    window.clearTimeout(timeoutRef.current);
    setActivated(false);
  }, []);
  useEffect(() => {
    if (activated) {
      timeoutRef.current = window.setTimeout(() => {
        onTimeout();
      }, duration);
      return () => {
        stopTimeout();
      };
    }
  }, [onTimeout, activated, duration, stopTimeout]);
  const startTimeout = useCallback(() => {
    setActivated(true);
  }, []);
  return {
    stopTimeout,
    startTimeout
  };
};
const toneToIcon = {
  critical: IconCritical,
  positive: IconPositive
};
const toastDuration = 1e4;
const borderRadius = "large";
const Action = ({ label, onClick, removeToast }) => {
  const handleClick = useCallback(() => {
    removeToast();
    onClick();
  }, [removeToast, onClick]);
  return /* @__PURE__ */ jsx(Text, { baseline: false, children: /* @__PURE__ */ jsx(Box, { component: "span", "aria-hidden": true, children: /* @__PURE__ */ jsx(TextLinkButton, { onClick: handleClick, hitArea: "large", children: label }) }) });
};
const ToastIcon = ({ tone, icon }) => {
  if (tone !== "neutral") {
    const Icon = toneToIcon[tone];
    return /* @__PURE__ */ jsx(Icon, { tone });
  }
  if (icon) {
    return cloneElement(icon, { tone });
  }
  return null;
};
const Toast = React.forwardRef(
  ({
    id,
    vanillaTheme,
    dedupeKey,
    message,
    description,
    tone,
    icon,
    onClose,
    closeLabel = "Close",
    action,
    shouldRemove,
    data,
    ...restProps
  }, ref) => {
    const remove = useCallback(
      () => onClose(dedupeKey, id),
      [onClose, dedupeKey, id]
    );
    const { stopTimeout, startTimeout } = useTimeout({
      duration: toastDuration,
      onTimeout: remove
    });
    useEffect(() => {
      if (shouldRemove) {
        stopTimeout();
        remove();
      }
    }, [shouldRemove, remove, stopTimeout]);
    assert(
      !icon || icon.props.size === void 0 && icon.props.tone === void 0,
      "Icons cannot set the 'size' or 'tone' prop when passed to a Toast component"
    );
    assert(
      !icon || icon && tone === "neutral",
      `Icons cannot be customised on a Toast component using '${tone}' tone`
    );
    const content = description ? /* @__PURE__ */ jsxs(Stack, { space: "xxsmall", children: [
      /* @__PURE__ */ jsx(Text, { weight: "medium", tone, baseline: false, children: message }),
      description ? /* @__PURE__ */ jsx(Text, { baseline: false, tone: "secondary", children: description }) : null,
      action ? /* @__PURE__ */ jsx(Action, { removeToast: remove, ...action }, action.label) : null
    ] }) : /* @__PURE__ */ jsxs(Inline, { space: "xxsmall", children: [
      /* @__PURE__ */ jsx(Box, { paddingRight: "medium", children: /* @__PURE__ */ jsx(Text, { weight: "medium", tone, baseline: false, children: message }) }),
      action ? /* @__PURE__ */ jsx(Action, { removeToast: remove, ...action }, action.label) : null
    ] });
    return /* @__PURE__ */ jsx(
      Box,
      {
        display: "flex",
        justifyContent: "center",
        role: "alert",
        ref,
        onMouseEnter: stopTimeout,
        onMouseLeave: startTimeout,
        className: vanillaTheme,
        ...buildDataAttributes({ data, validateRestProps: restProps }),
        children: /* @__PURE__ */ jsx(Box, { boxShadow: "large", borderRadius, children: /* @__PURE__ */ jsx(ContentBlock, { width: "xsmall", children: /* @__PURE__ */ jsx(
          Box,
          {
            background: { lightMode: "surfaceDark", darkMode: "surface" },
            position: "relative",
            borderRadius,
            paddingY: "medium",
            paddingX: "gutter",
            overflow: "hidden",
            className: toast,
            children: /* @__PURE__ */ jsxs(Columns, { space: "none", children: [
              tone !== "neutral" || tone === "neutral" && icon ? /* @__PURE__ */ jsx(Column, { width: "content", children: /* @__PURE__ */ jsx(Box, { paddingRight: "small", children: /* @__PURE__ */ jsx(ToastIcon, { tone, icon }) }) }) : null,
              /* @__PURE__ */ jsx(Column, { children: content }),
              /* @__PURE__ */ jsx(Column, { width: "content", children: /* @__PURE__ */ jsx(
                Box,
                {
                  width: "touchable",
                  display: "flex",
                  justifyContent: "flexEnd",
                  alignItems: "center",
                  className: lineHeightContainer.standard,
                  "aria-hidden": true,
                  children: /* @__PURE__ */ jsx(
                    ButtonIcon,
                    {
                      id: `${dedupeKey}-clear`,
                      icon: /* @__PURE__ */ jsx(IconClear, {}),
                      tone: "secondary",
                      variant: "transparent",
                      onClick: remove,
                      label: closeLabel,
                      data: process.env.NODE_ENV !== "production" ? { testid: "clearToast" } : {}
                    }
                  )
                }
              ) })
            ] })
          }
        ) }) })
      }
    );
  }
);
const ToastComponent = Toast;
export {
  ToastComponent
};
