import { ref, reactive, computed, watch, onMounted, onBeforeUnmount, h, resolveComponent } from "vue";
import { defineVxeComponent } from "../../ui/src/comp.mjs";
import XEUtils from "xe-utils";
import "../../ui/index.mjs";
import { getConfig } from "../../../../@vxe-ui/core/es/src/config.mjs";
import { useSize, usePermission } from "../../../../@vxe-ui/core/es/src/useFns.mjs";
import { createEvent } from "../../../../@vxe-ui/core/es/src/event.mjs";
import { renderEmptyElement } from "../../../../@vxe-ui/core/es/index.esm.mjs";
const VxeTextEllipsisComponent = defineVxeComponent({
  name: "VxeTextEllipsis",
  props: {
    href: String,
    target: String,
    content: [String, Number],
    lineClamp: [String, Number],
    status: String,
    title: [String, Number],
    loading: Boolean,
    offsetLength: [String, Number],
    routerLink: Object,
    underline: {
      type: Boolean,
      default: () => getConfig().textEllipsis.underline
    },
    /**
     * 权限码
     */
    permissionCode: [String, Number],
    size: {
      type: String,
      default: () => getConfig().textEllipsis.size || getConfig().size
    }
  },
  emits: [
    "click"
  ],
  setup(props, context) {
    const { emit } = context;
    const xID = XEUtils.uniqueId();
    const { computeSize } = useSize(props);
    const { computePermissionInfo } = usePermission(props);
    const refElem = ref();
    const realityElem = ref();
    const reactData = reactive({
      resizeObserver: null,
      visibleLen: 0
    });
    const refMaps = {
      refElem
    };
    const computeTextLineClamp = computed(() => {
      return XEUtils.toNumber(props.lineClamp);
    });
    const computeTextContent = computed(() => {
      return XEUtils.toValueString(props.content);
    });
    const computeTextOffsetLength = computed(() => {
      return props.offsetLength ? XEUtils.toNumber(props.offsetLength) : 0;
    });
    const computeVisibleContent = computed(() => {
      const { visibleLen } = reactData;
      const textLineClamp = computeTextLineClamp.value;
      const textContent = computeTextContent.value;
      const textOffsetLength = computeTextOffsetLength.value;
      if (textLineClamp > 1) {
        if (textContent.length > visibleLen) {
          return `${textContent.slice(0, Math.max(1, visibleLen - 3 + textOffsetLength))}...`;
        }
        return textContent;
      }
      return textContent;
    });
    const computeMaps = {};
    const $xeTextEllipsis = {
      xID,
      props,
      context,
      reactData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, createEvent(evnt, { $textEllipsis: $xeTextEllipsis }, params));
    };
    const calculateFont = (targetWidth) => {
      const el = refElem.value;
      const ryEl = realityElem.value;
      if (el && ryEl) {
        let fontSize = 12;
        try {
          fontSize = Math.max(10, XEUtils.toNumber(getComputedStyle(ryEl).fontSize));
        } catch (e) {
        }
        const textContent = computeTextContent.value;
        let currIndex = Math.floor(targetWidth / fontSize);
        let currStr = textContent.slice(0, currIndex);
        ryEl.textContent = currStr;
        reactData.visibleLen = currStr.length;
        let maxCount = 0;
        while (targetWidth > ryEl.clientWidth && maxCount < 30) {
          maxCount++;
          const offsetIndex = Math.floor((targetWidth - ryEl.clientWidth) / fontSize);
          if (offsetIndex) {
            currIndex += offsetIndex;
            currStr = textContent.slice(0, currIndex);
            ryEl.textContent = currStr;
            reactData.visibleLen = currStr.length;
          } else {
            break;
          }
        }
        ryEl.textContent = "";
        ryEl.style.display = "";
        ryEl.style.position = "";
        ryEl.style.top = "";
        ryEl.style.left = "";
      }
    };
    const updateStyle = () => {
      const el = refElem.value;
      const ryEl = realityElem.value;
      const textContent = computeTextContent.value;
      const textLineClamp = computeTextLineClamp.value;
      if (el && ryEl) {
        const cWidth = el.clientWidth;
        ryEl.style.display = "block";
        ryEl.style.position = "absolute";
        ryEl.style.top = "-3000px";
        ryEl.style.left = "-3000px";
        ryEl.textContent = textContent;
        const sWidth = ryEl.offsetWidth;
        const targetWidth = Math.floor(cWidth * textLineClamp);
        if (targetWidth > sWidth) {
          reactData.visibleLen = textContent.length;
        } else {
          calculateFont(targetWidth);
        }
      } else {
        reactData.visibleLen = textContent.length;
      }
    };
    const textEllipsisMethods = {
      dispatchEvent
    };
    const clickEvent = () => {
      emit("click", {});
    };
    const initObserver = () => {
      const { resizeObserver } = reactData;
      const textLineClamp = computeTextLineClamp.value;
      if (!resizeObserver) {
        const el = refElem.value;
        if (el && textLineClamp > 1) {
          if (window.ResizeObserver) {
            const observerObj = new window.ResizeObserver(XEUtils.throttle(() => {
              updateStyle();
            }, 300, { leading: true, trailing: true }));
            observerObj.observe(el);
            reactData.resizeObserver = observerObj;
          }
        }
      }
    };
    const textEllipsisPrivateMethods = {};
    Object.assign($xeTextEllipsis, textEllipsisMethods, textEllipsisPrivateMethods);
    const renderContent = () => {
      const { routerLink, href, target, title } = props;
      const visibleContent = computeVisibleContent.value;
      if (routerLink) {
        return h(resolveComponent("router-link"), {
          class: "vxe-text-ellipsis--link",
          title,
          target,
          to: routerLink
        }, {
          default() {
            return renderContent();
          }
        });
      }
      if (href) {
        return h("a", {
          class: "vxe-text-ellipsis--link",
          href,
          target,
          title
        }, visibleContent);
      }
      return h("span", {
        class: "vxe-text-ellipsis--content"
      }, visibleContent);
    };
    const renderVN = () => {
      const { loading, status, title, underline } = props;
      const permissionInfo = computePermissionInfo.value;
      const vSize = computeSize.value;
      const textLineClamp = computeTextLineClamp.value;
      if (!permissionInfo.visible) {
        return renderEmptyElement();
      }
      return h("div", {
        ref: refElem,
        class: ["vxe-text-ellipsis", textLineClamp > 1 ? "is--multi" : "is--single", {
          [`size--${vSize}`]: vSize,
          [`theme--${status}`]: status,
          "is--underline": underline,
          "is--loading": loading
        }],
        title,
        onClick: clickEvent
      }, [
        h("span", {
          ref: realityElem,
          class: "vxe-text-ellipsis--reality"
        }),
        renderContent()
      ]);
    };
    watch(() => props.content, () => {
      updateStyle();
    });
    watch(() => props.lineClamp, () => {
      initObserver();
      updateStyle();
    });
    onMounted(() => {
      initObserver();
      updateStyle();
    });
    onBeforeUnmount(() => {
      const { resizeObserver } = reactData;
      const el = refElem.value;
      const ryEl = realityElem.value;
      if (ryEl) {
        ryEl.textContent = "";
      }
      if (resizeObserver) {
        if (el) {
          resizeObserver.unobserve(el);
        }
        resizeObserver.disconnect();
        reactData.resizeObserver = null;
      }
    });
    $xeTextEllipsis.renderVN = renderVN;
    return $xeTextEllipsis;
  },
  render() {
    return this.renderVN();
  }
});
export {
  VxeTextEllipsisComponent as default
};
