"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const comp = require("../../ui/src/comp.js");
const XEUtils = require("xe-utils");
require("../../ui/index.js");
const dom = require("../../ui/src/dom.js");
const anchorLink = require("./anchor-link.js");
const event = require("../../../../@vxe-ui/core/es/src/event.js");
const index_esm = require("../../../../@vxe-ui/core/es/index.esm.js");
const VxeAnchorComponent = comp.defineVxeComponent({
  name: "VxeAnchor",
  props: {
    modelValue: String,
    options: Array,
    container: [String, Object, Function],
    showMarker: {
      type: Boolean,
      default: true
    }
  },
  emits: [
    "update:modelValue",
    "change",
    "click"
  ],
  setup(props, context) {
    const { slots, emit } = context;
    const xID = XEUtils.uniqueId();
    const refElem = vue.ref();
    const refMarkerElem = vue.ref();
    const reactData = vue.reactive({
      activeHref: null,
      staticLinks: [],
      containerElem: null
    });
    const refMaps = {
      refElem
    };
    const computeAllHrefList = vue.computed(() => {
      const list = [];
      XEUtils.eachTree(reactData.staticLinks, (item) => {
        list.push(item.href || "");
      }, { children: "children" });
      return list;
    });
    const computeMaps = {};
    const $xeAnchor = {
      xID,
      props,
      context,
      reactData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const anchorMethods = {
      dispatchEvent(type, params, evnt) {
        emit(type, event.createEvent(evnt, { $anchor: $xeAnchor }, params));
      }
    };
    const getContainerElem = () => {
      const { container } = props;
      if (container) {
        if (XEUtils.isElement(container)) {
          return container;
        }
        if (XEUtils.isString(container)) {
          return document.querySelector(container);
        }
        if (XEUtils.isFunction(container)) {
          return container({ $anchor: $xeAnchor });
        }
      }
      return null;
    };
    const emitEvent = (value) => {
      reactData.activeHref = value;
      emit("update:modelValue", value);
    };
    const handleContainerScrollEvent = () => {
      const allHrefList = computeAllHrefList.value;
      const { containerElem } = reactData;
      if (containerElem) {
        const wrapperElList = containerElem.querySelectorAll(allHrefList.map((href) => `${href}`).join(","));
        for (let i = 0; i < wrapperElList.length; i++) {
          const wrapperEl = wrapperElList[i];
          const wrapperRect = wrapperEl.getBoundingClientRect();
          if (wrapperRect.top > 0) {
            const href = wrapperEl.id;
            reactData.activeHref = `#${href}`;
            break;
          }
        }
      }
    };
    const removeContainerElemScroll = () => {
      const { containerElem } = reactData;
      if (containerElem) {
        containerElem.removeEventListener("scroll", handleContainerScrollEvent);
      }
    };
    const updateContainerElem = () => {
      const containerElem = getContainerElem();
      reactData.containerElem = containerElem;
      if (containerElem) {
        containerElem.addEventListener("scroll", handleContainerScrollEvent, {
          passive: false
        });
      }
    };
    const updateMarkerPos = () => {
      vue.nextTick(() => {
        const { activeHref } = reactData;
        const elem = refElem.value;
        const markerEl = refMarkerElem.value;
        if (elem && markerEl) {
          if (activeHref) {
            const linkEl = elem.querySelector(`[href="${activeHref}"]`);
            if (linkEl) {
              const { top } = dom.getOffsetPos(linkEl, elem);
              markerEl.style.top = `${top}px`;
            }
          }
        }
      });
    };
    const anchorPrivateMethods = {
      handleClickLink(evnt, href) {
        evnt.preventDefault();
        const targetEl = document.getElementById(`${href}`.replace("#", ""));
        if (targetEl) {
          targetEl.scrollIntoView({
            behavior: "smooth"
          });
        }
        emitEvent(href);
        anchorMethods.dispatchEvent("click", { href }, evnt);
      }
    };
    Object.assign($xeAnchor, anchorMethods, anchorPrivateMethods);
    const renderSubItems = (options) => {
      const itemVNs = [];
      if (options) {
        options.forEach((item) => {
          const subItems = item.children;
          if (subItems && subItems.length) {
            itemVNs.push(vue.h(anchorLink.default, {
              content: item.content,
              title: item.title,
              href: item.href
            }, {
              sub: () => renderSubItems(subItems)
            }));
          } else {
            itemVNs.push(vue.h(anchorLink.default, {
              content: item.content,
              title: item.title,
              href: item.href
            }));
          }
        });
      }
      return itemVNs;
    };
    const renderVN = () => {
      const { options, showMarker } = props;
      const defaultSlot = slots.default;
      return vue.h("div", {
        ref: refElem,
        class: ["vxe-anchor", {
          "is--marker": showMarker
        }]
      }, [
        vue.h("div", {
          class: "vxe-anchor--list"
        }, defaultSlot ? defaultSlot({}) : renderSubItems(options)),
        showMarker ? vue.h("div", {
          ref: refMarkerElem,
          class: "vxe-anchor--marker"
        }) : index_esm.renderEmptyElement()
      ]);
    };
    vue.watch(() => props.modelValue, (val) => {
      reactData.activeHref = val;
    });
    vue.watch(() => reactData.activeHref, () => {
      updateMarkerPos();
    });
    vue.watch(() => props.container, () => {
      removeContainerElemScroll();
      updateContainerElem();
    });
    vue.onMounted(() => {
      vue.nextTick(() => {
        updateContainerElem();
      });
    });
    vue.onBeforeUnmount(() => {
      removeContainerElemScroll();
    });
    vue.provide("$xeAnchor", $xeAnchor);
    $xeAnchor.renderVN = renderVN;
    return $xeAnchor;
  },
  render() {
    return this.renderVN();
  }
});
exports.default = VxeAnchorComponent;
