<template>
  <div class="bg-table-btns" ref="bgTableBtnsRef">
    <slot></slot>
    <span
      class="bg-table-btn more"
      id="more_btn"
      v-if="state.children.length > limit"
      ref="lastEl"
      @mouseenter="showMoreBtns"
      @mouseleave="hideMoreBtns">
      <bg-icon style="font-size: 12px; color: #2b4695" icon="#bg-ic-s-more" />
      <teleport to="body">
        <div
          class="more-box"
          :style="state.style"
          v-if="state.showMore"
          @mouseenter="showMoreBtns"
          @mouseleave="hideMoreBtns">
          <span
            v-for="(item, index) in state.lastChildren"
            :key="'as' + index"
            @click="action(item.onClick, item.disabled)"
            :class="item.disabled ? 'disabled' : ''"
            >{{ item.name }}</span
          >
        </div>
      </teleport>
    </span>
  </div>
</template>

<script setup>
import { reactive, ref, onBeforeMount, onMounted, toRefs, provide, useSlots, h, render, nextTick } from "vue";
const slots = useSlots();

const props = defineProps({
  limit: {
    type: Number,
    default: 3,
  },
});

const bgTableBtnsRef = ref(null);
const lastEl = ref(null);
const state = reactive({
  children: [],
  index: 0,
  lastChildren: [],
  style: {},
  timer: null,
  showMore: false,
});

const action = (event, disable) => {
  if (disable) {
    return;
  }
  event();
  state.showMore = false
};

const calcTabs = () => {
  let tabSlots = slots.default() || [];
  state.lastChildren = [];
  if (tabSlots) {
    tabSlots.forEach((e, idx) => {
      if (idx + 2 > props.limit && tabSlots.length > props.limit && e.props) {
        state.lastChildren.push(e.props);
      }
    });
  }
};

const showMoreBtns = () => {
  calcTabs();
  dealData();
  nextTick(() => {
    updateSytle();
    if (state.timer) clearTimeout(state.timer);
    state.showMore = true;
  });
};
const hideMoreBtns = () => {
  if (state.timer) clearTimeout(state.timer);
  state.timer = setTimeout(() => {
    state.showMore = false;
  }, 50);
};
const updateSytle = () => {
  let { top, right } = lastEl.value.getBoundingClientRect();
  let { width } = window.document.body.getBoundingClientRect();
  state.style = {
    top: `${top + 16}px`,
    right: `${width - right - 16}px`,
  };
};

const dealData = () => {
  let children = bgTableBtnsRef.value.children || [];
  state.children = children;
  if (children.length > props.limit) {
    children[props.limit - 1].style.display = "none";
    children[props.limit - 1].style.width = "0px";
    state.index = props.limit - 2;
    state.lastChildren[0].name = children[props.limit - 1].innerText;
  }
  for (let index = 0; index < children.length; index++) {
    const e = children[index];
    if (index + 1 > props.limit && e.tagName == "A" && e.className.indexOf("bg-table-btn") !== -1) {
      e.style.display = "none";
      e.style.width = "0px";
      state.lastChildren[index - props.limit + 1].name = e.innerText;
    }
  }
};

onMounted(() => {
  calcTabs();
  dealData();
});
</script>

<style scoped>
.more {
  position: relative;
  z-index: 200;
}

.more-box {
  position: fixed;
  padding: 4px 0;
  background-color: #ffffff;
  box-shadow: 0px 4px 12px 0px rgba(18, 30, 63, 0.1);
  border-radius: 4px;
  border: solid 1px #e6e9ef;
  width: 88px;
  z-index: 300;
}

.more-box span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-all;
  white-space: nowrap;
  display: block;
  padding: 0 16px;
  margin: 0;
  color: #202531;
  line-height: 34px;
  padding-left: 16px;
  font-size: 16px;
  cursor: pointer;
}
.more-box span:hover {
  background-color: #f2f3f7;
  color: #202531;
}
.more-box .disabled {
  color: #a9b1c7;
  cursor: not-allowed;
}
.more-box .disabled:hover {
  background-color: #f2f3f7;
  color: #a9b1c7;
}
.more-box span::before {
  display: none;
}
</style>
