"use client";
import { jsx, jsxs } from "../../packages/jsx/src/jsx-runtime.js";
import { Highlight, Prism } from "prism-react-renderer";
import { forwardRef } from "react";
import { Tooltip } from "../Tooltip/Tooltip.js";
import { colorsByMode } from "../../tokens/Color.js";
import { BorderRadius } from "../../tokens/BorderRadius.js";
import { Spacing } from "../../tokens/Spacing.js";
import { Flex } from "../../atoms/Flex/Flex.js";
import { buildTransition, buildColor } from "../../tokens/utils.js";
import { Opacity } from "../../tokens/Opacity.js";
import { Button } from "../Button/Button.js";
import { Text } from "../../atoms/Text/Text.js";
import { classNames } from "../../utils/classNames.js";
const colors = colorsByMode.dark;
const syntaxTheme = {
  tabSize: 2,
  ".plain": {
    color: `${colors.White88} !important`
  },
  ".comment, .prolog, .doctype, .cdata": {
    color: `${colors.White48} !important`,
    fontStyle: "italic !important"
  },
  ".tag, .number, .string, .boolean, .regex": {
    color: "#FF79C6 !important"
  },
  ".type, .builtin, .class-name, .maybe-class-name": {
    color: `${colors.Yellow} !important`
  },
  ".keyword": {
    color: "#9787F4 !important"
  },
  ".function, .namespace": {
    color: `${colors.Green} !important`
  },
  ".punctuation, .operator": {
    color: `${colors.White64} !important`
  },
  ".tag-id, .selector, .atrule-id": {
    color: "#eeebff !important"
  },
  ".attr-name": {
    color: "#c4b9fe !important"
  },
  ".deleted": {
    textDecorationLine: "line-through !important"
  },
  ".inserted": {
    textDecorationLine: "underline !important"
  },
  ".italic": {
    fontStyle: "italic !important"
  },
  ".important, .bold": {
    fontWeight: "bold !important"
  },
  ".important": {
    color: "#c4b9fe !important"
  }
};
const customizeLanguages = async () => {
  (typeof global !== "undefined" ? global : window).Prism = Prism;
  await import("prismjs/components/prism-bash.js");
  await import("prismjs/components/prism-json.js");
  await import("prismjs/components/prism-python.js");
  await import("prismjs/components/prism-solidity.js");
  Prism.languages.typescript = Prism.languages.ts = Prism.languages.tsx;
};
void customizeLanguages();
const CodeBlockWrapper = forwardRef(({ code, children, ...props }, ref) => /* @__PURE__ */ jsx(
  "pre",
  {
    ref,
    dir: "ltr",
    sx: {
      // Making it a column flex container to support `maxHeight`
      display: "flex",
      flexDirection: "column",
      borderRadius: [BorderRadius.S, null, BorderRadius.M],
      bg: "White8",
      overflow: "hidden",
      isolation: "isolate"
    },
    ...props,
    children: /* @__PURE__ */ jsxs("div", { sx: { overflow: "auto" }, children: [
      /* @__PURE__ */ jsx(
        "div",
        {
          sx: {
            // This extra element with a transparent `border` acting as a `padding` is a hack to prevent collapsing the right padding when the code overflows horizontally
            width: "min-content",
            border: "transparent",
            borderWidth: [Spacing["16px"], null, Spacing["32px"]]
          },
          children
        }
      ),
      /* @__PURE__ */ jsx(
        "div",
        {
          sx: {
            // Hide the copy button on small touch devices (e.g. phones), because the smaller padding means the button has to appear on top of the code and it's never hidden (since there is no `hover` capability)
            "@media (hover: none)": {
              display: ["none", null, "block"]
            },
            zIndex: 1,
            // Using `sticky` position instead of `absolute` to prevent the copy button from appearing on top of the scrollbar if there is one (e.g. if there is a `maxHeight`)
            position: "sticky",
            bottom: "calc(100% - 48px)",
            left: "calc(100% - 48px)",
            width: 0,
            height: 0,
            pointerEvents: "none"
          },
          children: /* @__PURE__ */ jsx(
            Flex.Center,
            {
              sx: {
                position: "absolute",
                left: 0,
                bottom: 0,
                width: "48px",
                height: "48px",
                borderBottomLeftRadius: [BorderRadius.S, null, BorderRadius.M],
                border: "White8",
                borderTop: "none",
                borderRight: "none",
                bg: buildColor(["Background", "White8"]),
                // On non-touch devices, show the copy button on hover
                "@media (hover: hover)": {
                  opacity: Opacity["0%"],
                  ".gds-Code:hover &": {
                    opacity: Opacity["100%"]
                  },
                  transition: buildTransition("OPACITY", "400ms")
                }
              },
              children: /* @__PURE__ */ jsx(Tooltip, { content: "Copy", children: /* @__PURE__ */ jsx("div", { sx: { pointerEvents: "auto" }, children: /* @__PURE__ */ jsx(Button.Copy, { variant: "tertiary", value: code }) }) })
            }
          )
        }
      )
    ] })
  }
));
CodeBlockWrapper.displayName = "Code._CodeBlockWrapper";
const CodeInlineWrapper = forwardRef(({ code: _code, children, ...props }, ref) => (
  /**
   * The `vertical-align: top` ensures that the surrounding (non-code) text has a consistent line height.
   * It wouldn't be an issue if we didn't change the code's font size to be a ratio of the text's font size,
   * but it looks better that way and it prevents the (semi-transparent) background from overlapping when
   * the code is wrapped at certain font sizes.
   */
  /* @__PURE__ */ jsx("code", { ref, sx: { verticalAlign: "top" }, ...props, children: /* @__PURE__ */ jsx(
    "span",
    {
      sx: {
        top: "0.1em",
        // align the code with the surrounding text
        px: "0.35em",
        pt: "0.3em",
        pb: "0.2em",
        borderRadius: `clamp(${BorderRadius.S}, 0.25em, ${BorderRadius.M})`,
        bg: "White8",
        boxDecorationBreak: "clone",
        fontSize: "clamp(0.7em, calc(0.5em + 7px), 1em)"
      },
      children
    }
  ) })
));
CodeInlineWrapper.displayName = "Code._CodeInlineWrapper";
const CodeBase = forwardRef(
  ({ variant, language = "plain", size, className, children, ...props }, ref) => {
    const Wrapper = variant === "block" ? CodeBlockWrapper : CodeInlineWrapper;
    const Line = variant === "block" ? "div" : "span";
    return /* @__PURE__ */ jsx(Highlight, { code: children, language, children: ({ className: highlightClassName, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsx(Text.M, { as: "child", size, children: /* @__PURE__ */ jsx(
      Wrapper,
      {
        ref,
        code: children,
        className: classNames(["gds-Code", className, highlightClassName]),
        sx: syntaxTheme,
        ...props,
        children: tokens.map((line, lineIndex) => /* @__PURE__ */ jsx(Line, { ...getLineProps({ line }), children: line.map((token, tokenIndex) => /* @__PURE__ */ jsx("span", { ...getTokenProps({ token }) }, tokenIndex)) }, lineIndex))
      }
    ) }) });
  }
);
CodeBase.displayName = "Code";
const CodeBlock = forwardRef((props, ref) => /* @__PURE__ */ jsx(CodeBase, { ref, ...props, variant: "block" }));
CodeBlock.displayName = "Code.Block";
const CodeInline = forwardRef((props, ref) => /* @__PURE__ */ jsx(CodeBase, { ref, ...props, variant: "inline" }));
CodeInline.displayName = "Code.Inline";
const Code = Object.assign(CodeBase, {
  Block: CodeBlock,
  Inline: CodeInline
});
export {
  Code
};
