import { defineComponent, ref, reactive, markRaw, toRefs, computed, onMounted, nextTick, onUnmounted, watch, createElementBlock, openBlock, normalizeClass, unref, createElementVNode, createCommentVNode, createVNode, Fragment, renderList, toDisplayString } from 'vue';
import breaks from '@bytemd/plugin-breaks';
import frontmatter from '@bytemd/plugin-frontmatter';
import gemoji from '@bytemd/plugin-gemoji';
import gfm from '@bytemd/plugin-gfm';
import highlight from '@bytemd/plugin-highlight';
import math from '@bytemd/plugin-math';
import mediumZoom from '@bytemd/plugin-medium-zoom';
import mermaid from '@bytemd/plugin-mermaid';
import * as BytemdVueNext from '@bytemd/vue-next';
import '../../../../utils/index.mjs';
import { getProcessor } from '../../../../../node_modules/.pnpm/bytemd@1.22.0/node_modules/bytemd/dist/index.mjs';
import zhHans from '../../../../../node_modules/.pnpm/bytemd@1.22.0/node_modules/bytemd/locales/zh_Hans.json.mjs';
import { findIndex, throttle, debounce } from 'lodash-es';
import '../config/index.mjs';
import { createNamespace } from '../../../../utils/create-namespace.mjs';
import { LlMarkdownPreviewerProps } from '../config/markdown-previewer.mjs';

"use strict";
const _hoisted_1 = ["onClick"];
var _sfc_main = /* @__PURE__ */ defineComponent({
  ...{ name: "LlMarkdownPreviewer" },
  __name: "markdown-previewer",
  props: LlMarkdownPreviewerProps,
  setup(__props) {
    const props = __props;
    const MarkdownViewer = BytemdVueNext.Viewer;
    const markDownRef = ref();
    const viewerContainer = ref();
    const bem = createNamespace("markdown-previewer");
    const pluginsList = [
      gfm(),
      gemoji(),
      highlight(),
      frontmatter(),
      mediumZoom(),
      breaks(),
      mermaid(),
      math()
    ];
    const state = reactive({
      plugins: markRaw(pluginsList),
      zh: zhHans,
      cateList: [],
      anchor: 0,
      scrollContainer: null,
      isManualScrolling: false,
      // 是否为手动点击滚动
      headingElements: []
      // 缓存标题元素信息
    });
    const { anchor, plugins, zh, cateList } = toRefs(state);
    const currentValue = computed(() => props.value || "");
    const getCataLogData = () => {
      try {
        getProcessor({
          plugins: [
            {
              rehype: (p) => p.use(() => (tree) => {
                if (tree && tree.children && tree.children.length) {
                  createCataLog(tree);
                }
              })
            }
          ]
        }).processSync(currentValue.value);
      } catch (error) {
        console.error("\u5904\u7406\u76EE\u5F55\u6570\u636E\u65F6\u51FA\u9519:", error);
      }
    };
    const createCataLog = (tree) => {
      const items = [];
      if (!tree.children) return;
      tree.children.filter((v) => v.type === "element").forEach((node) => {
        if (["h1", "h2", "h3", "h4", "h5", "h6"].includes(node.tagName) && node.children && node.children.length > 0) {
          const text = stringifyHeading(node);
          if (text.trim()) {
            items.push({
              tagName: node.tagName,
              text: text.trim()
            });
          }
        }
      });
      state.cateList = items;
    };
    const stringifyHeading = (node) => {
      let result = "";
      if (!node.children) return result;
      node.children.forEach((item) => {
        if (item.type === "text" && item.value) {
          result += item.value;
        } else if (item.children) {
          result += stringifyHeading(item);
        }
      });
      return result;
    };
    const transformToId = () => {
      try {
        const dom = document.querySelector(".markdown-body");
        if (!dom) return;
        const children = Array.from(dom.children);
        if (children.length === 0) return;
        children.forEach((child) => {
          if (["H1", "H2", "H3", "H4", "H5", "H6"].includes(child.tagName)) {
            const index = findIndex(
              state.cateList,
              (v) => v.text === child.textContent?.trim()
            );
            if (index >= 0) {
              child.setAttribute("id", `head-${index}`);
            }
          }
        });
      } catch (error) {
        console.error("\u8BBE\u7F6EID\u65F6\u51FA\u9519:", error);
      }
    };
    const scrollToSection = (sectionId, index) => {
      state.isManualScrolling = true;
      state.anchor = index;
      const section = document.getElementById(sectionId);
      if (section && state.scrollContainer) {
        const containerRect = state.scrollContainer.getBoundingClientRect();
        const sectionRect = section.getBoundingClientRect();
        const scrollTop = state.scrollContainer.scrollTop;
        const targetPosition = scrollTop + sectionRect.top - containerRect.top - 20;
        state.scrollContainer.scrollTo({
          top: targetPosition,
          behavior: "smooth"
        });
        setTimeout(() => {
          state.isManualScrolling = false;
        }, 800);
      }
    };
    const getScrollContainer = () => {
      try {
        const markdownBody = document.querySelector(".markdown-body");
        if (!markdownBody) return null;
        let element = markdownBody.parentElement;
        while (element && element !== document.documentElement) {
          const style = window.getComputedStyle(element);
          const overflow = style.overflow + style.overflowY + style.overflowX;
          if (/(auto|scroll)/.test(overflow) && element.scrollHeight > element.clientHeight) {
            return element;
          }
          element = element.parentElement;
        }
        return viewerContainer.value || document.documentElement;
      } catch (error) {
        console.error("\u83B7\u53D6\u6EDA\u52A8\u5BB9\u5668\u65F6\u51FA\u9519:", error);
        return document.documentElement;
      }
    };
    const cacheHeadingElements = () => {
      try {
        if (!state.scrollContainer) return;
        state.headingElements = state.cateList.map((_, index) => {
          const element = document.querySelector(`#head-${index}`);
          if (!element) return null;
          return {
            element,
            index,
            offsetTop: 0
            // 先初始化为0，在更新函数中计算
          };
        }).filter((item) => item !== null);
        updateHeadingPositions();
      } catch (error) {
        console.error("\u7F13\u5B58\u6807\u9898\u5143\u7D20\u65F6\u51FA\u9519:", error);
      }
    };
    const updateHeadingPositions = () => {
      try {
        if (!state.scrollContainer) return;
        state.headingElements.forEach((item) => {
          const elementRect = item.element.getBoundingClientRect();
          const containerRect = state.scrollContainer.getBoundingClientRect();
          item.offsetTop = state.scrollContainer.scrollTop + elementRect.top - containerRect.top;
        });
      } catch (error) {
        console.error("\u66F4\u65B0\u4F4D\u7F6E\u4FE1\u606F\u65F6\u51FA\u9519:", error);
      }
    };
    const handleScrollOptimized = throttle(() => {
      try {
        if (!state.scrollContainer || state.headingElements.length === 0 || state.isManualScrolling) {
          return;
        }
        const scrollTop = state.scrollContainer.scrollTop;
        const containerHeight = state.scrollContainer.clientHeight;
        const scrollHeight = state.scrollContainer.scrollHeight;
        if (scrollTop <= 0) {
          if (state.anchor !== 0) {
            state.anchor = 0;
          }
          return;
        }
        if (scrollTop + containerHeight >= scrollHeight) {
          const lastIndex = state.headingElements.length - 1;
          if (state.anchor !== lastIndex) {
            state.anchor = lastIndex;
          }
          return;
        }
        let activeIndex = 0;
        const containerTop = state.scrollContainer.getBoundingClientRect().top;
        for (let i = 0; i < state.headingElements.length; i++) {
          const item = state.headingElements[i];
          const elementRect = item.element.getBoundingClientRect();
          const elementTop = elementRect.top;
          if (elementTop <= containerTop + 10) {
            activeIndex = i;
          } else {
            break;
          }
        }
        if (state.anchor !== activeIndex) {
          state.anchor = activeIndex;
        }
      } catch (error) {
        console.error("\u6EDA\u52A8\u5904\u7406\u65F6\u51FA\u9519:", error);
      }
    }, 16);
    const debouncedUpdatePositions = debounce(() => {
      updateHeadingPositions();
    }, 100);
    const handleResize = debounce(() => {
      updateHeadingPositions();
    }, 200);
    const cleanup = () => {
      try {
        state.scrollContainer?.removeEventListener("scroll", handleScrollOptimized);
        window.removeEventListener("resize", handleResize);
        handleScrollOptimized.cancel?.();
        debouncedUpdatePositions.cancel?.();
        handleResize.cancel?.();
      } catch (error) {
        console.error("\u6E05\u7406\u65F6\u51FA\u9519:", error);
      }
    };
    const initScrollListener = () => {
      try {
        if (!state.scrollContainer) return;
        cacheHeadingElements();
        state.scrollContainer.addEventListener("scroll", handleScrollOptimized, {
          passive: true
        });
        window.addEventListener("resize", handleResize, {
          passive: true
        });
        state.anchor = 0;
      } catch (error) {
        console.error("\u521D\u59CB\u5316\u6EDA\u52A8\u76D1\u542C\u65F6\u51FA\u9519:", error);
      }
    };
    onMounted(async () => {
      try {
        getCataLogData();
        await nextTick();
        transformToId();
        await nextTick();
        state.scrollContainer = getScrollContainer();
        initScrollListener();
      } catch (error) {
        console.error("\u7EC4\u4EF6\u6302\u8F7D\u65F6\u51FA\u9519:", error);
      }
    });
    onUnmounted(() => {
      cleanup();
    });
    watch(
      () => props.value,
      async (newVal) => {
        if (newVal !== void 0) {
          cleanup();
          getCataLogData();
          await nextTick();
          transformToId();
          await nextTick();
          state.scrollContainer = getScrollContainer();
          initScrollListener();
        }
      },
      { immediate: true }
    );
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock(
        "div",
        {
          class: normalizeClass(unref(bem).b())
        },
        [
          createElementVNode(
            "div",
            {
              class: normalizeClass(unref(bem).e("wrapper"))
            },
            [
              createElementVNode(
                "div",
                {
                  ref_key: "viewerContainer",
                  ref: viewerContainer,
                  class: normalizeClass(unref(bem).e("view"))
                },
                [
                  createVNode(unref(MarkdownViewer), {
                    ref_key: "markDownRef",
                    ref: markDownRef,
                    locale: unref(zh),
                    value: currentValue.value,
                    plugins: unref(plugins)
                  }, null, 8, ["locale", "value", "plugins"])
                ],
                2
                /* CLASS */
              ),
              props.showCatalog && unref(cateList).length > 0 ? (openBlock(), createElementBlock(
                "div",
                {
                  key: 0,
                  class: normalizeClass(unref(bem).e("catalog"))
                },
                [
                  _cache[0] || (_cache[0] = createElementVNode(
                    "h6",
                    null,
                    "\u76EE\u5F55",
                    -1
                    /* CACHED */
                  )),
                  createElementVNode(
                    "ul",
                    {
                      class: normalizeClass(unref(bem).e("catalog-list"))
                    },
                    [
                      (openBlock(true), createElementBlock(
                        Fragment,
                        null,
                        renderList(unref(cateList), (item, index) => {
                          return openBlock(), createElementBlock("li", {
                            key: index,
                            class: normalizeClass([[{ active: unref(anchor) == index }, item.tagName + "-class"], "marker-item"]),
                            onClick: ($event) => scrollToSection("head-" + index, index)
                          }, toDisplayString(item.text), 11, _hoisted_1);
                        }),
                        128
                        /* KEYED_FRAGMENT */
                      ))
                    ],
                    2
                    /* CLASS */
                  )
                ],
                2
                /* CLASS */
              )) : createCommentVNode("v-if", true)
            ],
            2
            /* CLASS */
          )
        ],
        2
        /* CLASS */
      );
    };
  }
});

export { _sfc_main as default };
//# sourceMappingURL=markdown-previewer.vue2.mjs.map
