import { computed, ref, onMounted, watch, createVNode } from "vue";
import "./styles/code.scss";
import { makeThemeProps, provideTheme } from "../../composables/theme/index.mjs";
import { makeShapeProps, useShape } from "../../composables/shape/index.mjs";
import { useHighlighter } from "../../composables/highlighter/index.mjs";
import { useBackgroundColor } from "../../composables/color/index.mjs";
import { makeScrollbar, useScrollbar } from "../../composables/scrollbar/index.mjs";
import { defineComponent } from "../../utils/define-component.mjs";
import { flattenFragments } from "../../utils/dist/index.mjs";
const Code = defineComponent({
  name: "VeCode",
  props: {
    code: [String, Object],
    color: String,
    showLanguage: Boolean,
    showLineNumbers: Boolean,
    highlightedLineNumbers: Array,
    inline: Boolean,
    language: {
      type: String,
      default: "text"
    },
    ...makeThemeProps(),
    ...makeShapeProps(),
    ...makeScrollbar()
  },
  setup(props, {
    slots
  }) {
    const {
      themeClasses
    } = provideTheme(props);
    const {
      shapeClasses
    } = useShape(props);
    const highlighter = useHighlighter();
    const {
      scrollbarClasses
    } = useScrollbar(props);
    const code = computed(() => {
      var _a, _b;
      let value = "";
      if (props.code) {
        value = typeof props.code === "object" ? JSON.stringify(props.code, null, 2) : (_a = props.code) != null ? _a : "";
      } else if (slots.default) {
        value = (_b = flattenFragments(slots.default()).filter((node) => node.children && typeof node.children === "string")[0]) == null ? void 0 : _b.children;
      }
      return decodeURIComponent(value).replace(/\n$/, "").replace(/^\n/, "");
    });
    const highlightedCode = ref(code.value);
    const {
      backgroundColorClasses,
      backgroundColorStyles
    } = useBackgroundColor(props, "color");
    const language = computed(() => typeof props.code === "object" ? "json" : props.language);
    const lineNumbers = computed(() => code.value.split("\n").map((v, i) => i + 1));
    const highlightedLines = computed(() => {
      return lineNumbers.value.filter((lineNumber) => {
        var _a;
        return (_a = props.highlightedLineNumbers) == null ? void 0 : _a.some((v) => {
          let start = v;
          let end;
          if (typeof v === "object") {
            [start, end] = v;
          }
          if (start && end) {
            return lineNumber >= start && lineNumber <= end;
          }
          return lineNumber === start;
        });
      });
    });
    const highlight = async () => {
      var _a;
      highlightedCode.value = await ((_a = highlighter.value) == null ? void 0 : _a.highlight(code.value, language.value));
    };
    onMounted(highlight);
    watch([code, language], highlight);
    return () => {
      var _a;
      if (props.inline) {
        return createVNode("code", {
          "class": ["ve-code", "ve-code--inline", themeClasses.value, shapeClasses.value, backgroundColorClasses.value],
          "style": backgroundColorStyles.value,
          "innerHTML": highlightedCode.value
        }, null);
      }
      const showLines = props.showLineNumbers || !!((_a = props.highlightedLineNumbers) == null ? void 0 : _a.length);
      return createVNode("div", {
        "class": ["ve-code", "ve-code--block", {
          "ve-code--show-line-numbers": !!props.showLineNumbers
        }, themeClasses.value, shapeClasses.value, backgroundColorClasses.value],
        "style": backgroundColorStyles.value
      }, [showLines && createVNode("div", {
        "class": "ve-code__lines"
      }, [lineNumbers.value.map((number) => createVNode("div", {
        "class": "ve-code__line"
      }, [highlightedLines.value.includes(number) && createVNode("div", {
        "class": "ve-code__line-overlay",
        "innerHTML": "&nbsp;"
      }, null), props.showLineNumbers ? createVNode("span", {
        "class": "ve-code__line-number"
      }, [number]) : createVNode("br", null, null)]))]), createVNode("pre", {
        "class": ["ve-code__preformatted", scrollbarClasses.value]
      }, [createVNode("code", {
        "innerHTML": highlightedCode.value
      }, null)]), props.showLanguage && createVNode("span", {
        "class": "ve-code__language"
      }, [language.value])]);
    };
  }
});
export {
  Code
};
//# sourceMappingURL=code.mjs.map
