<template>
  <div class="reactive-layout" ref="containerRef">
    <slot></slot>
    <template v-for="n in lineNum">
      <div
        class="flex justify-between"
        :class="{
          ' mb-[26px]': n !== lineNum,
        }"
      >
        <template
          v-for="item in list.slice(
            (n - 1) * maxNumInOneLine,
            (n - 1) * maxNumInOneLine + maxNumInOneLine
          )"
        >
          <slot
            name="element"
            :="item"
            ref="elementRef"
            class="flex-shrink-0"
          ></slot>
        </template>
        <template v-if="n === lineNum">
          <div
            v-for="nn in insertNum"
            :style="{
              width: widthOfElement + 'px',
            }"
          ></div>
        </template>
      </div>
    </template>
  </div>
</template>

<script setup lang="ts">
import { throttle } from "lodash";
import { computed, onBeforeUnmount, onMounted, ref } from "vue";

const props = defineProps<{
  elementWidth: number;
  list: any[];
  ELEMENT_MIN_GAP?: number;
}>();

const containerRef = ref<HTMLDivElement>();
const elementRef = ref<HTMLDivElement>();
const ELEMENT_MIN_GAP = props.ELEMENT_MIN_GAP || 26;

const widthOfContainer = ref(1000);
const widthOfElement = ref(props.elementWidth);

const maxNumInOneLine = ref(1);
const insertNum = computed(() => {
  const temp = props.list.length % maxNumInOneLine.value;
  return temp === 0
    ? 0
    : maxNumInOneLine.value - (props.list.length % maxNumInOneLine.value);
}); // 补充

const lineNum = computed(() => {
  return getLineNum(props.list.length, maxNumInOneLine.value);
});

onMounted(() => {
  widthOfContainer.value = containerRef.value?.clientWidth!;
  maxNumInOneLine.value = getMaxNumInOneLine(
    widthOfContainer.value!,
    widthOfElement.value,
    ELEMENT_MIN_GAP
  );
});

const handleResize = () => {
  widthOfContainer.value = containerRef.value?.clientWidth!;
  maxNumInOneLine.value = getMaxNumInOneLine(
    widthOfContainer.value!,
    widthOfElement.value,
    ELEMENT_MIN_GAP
  );
};

window.onresize = throttle(handleResize, 100);

onBeforeUnmount(() => {
  window.onresize = null;
});

function getMaxNumInOneLine(
  containerWidth: number,
  elementWidth: number,
  MIN_GAP: number
) {
  const numOfMaxItemInOneLine = Math.floor(
    (MIN_GAP + containerWidth) / (elementWidth + MIN_GAP)
  );
  return numOfMaxItemInOneLine;
}

function getLineNum(listLen: number, numInOneLine: number) {
  return Math.ceil(listLen / numInOneLine);
}
</script>

<style></style>
