import { defineComponent, reactive, ref, onBeforeMount, onMounted, nextTick, onBeforeUnmount, watch, provide, toRefs, createElementBlock, openBlock, normalizeStyle, renderSlot, withDirectives, Fragment, renderList, createBlock, mergeProps, withCtx, createVNode, vShow } from "vue";
import st from "./grid-item.vue.mjs";
import { useResize as wo } from "../../../@vexip-ui/hooks/dist/index.mjs";
import { createEventEmitter as Zr, debounce as no, isNull as ie } from "../../../@vexip-ui/utils/dist/index.mjs";
import { validateLayout as k, compact as $, LAYOUT_KEY as T, EMITTER_KEY as v, bottom as A, getLayoutItem as C, moveElement as x, getAllCollisions as L, cloneLayout as Y } from "../helpers/common.mjs";
import { getBreakpointFromWidth as y, getColsFromBreakpoint as B, findOrGenerateResponsiveLayout as v$1 } from "../helpers/responsive.mjs";
const De = /* @__PURE__ */ defineComponent({
  __name: "grid-layout",
  props: {
    autoSize: { type: Boolean, default: true },
    colNum: { default: 12 },
    rowHeight: { default: 150 },
    maxRows: { default: 1 / 0 },
    margin: { default: () => [10, 10] },
    isDraggable: { type: Boolean, default: true },
    isResizable: { type: Boolean, default: true },
    isMirrored: { type: Boolean, default: false },
    isBounded: { type: Boolean, default: false },
    useCssTransforms: { type: Boolean, default: true },
    verticalCompact: { type: Boolean, default: true },
    restoreOnDrag: { type: Boolean, default: false },
    layout: {},
    responsive: { type: Boolean, default: false },
    responsiveLayouts: { default: () => ({}) },
    transformScale: { default: 1 },
    breakpoints: { default: () => ({ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }) },
    cols: { default: () => ({ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }) },
    preventCollision: { type: Boolean, default: false },
    useStyleCursor: { type: Boolean, default: true }
  },
  emits: [
    "layout-before-mount",
    "layout-mounted",
    "layout-updated",
    "breakpoint-changed",
    "update:layout",
    "layout-ready"
  ],
  setup(Y$1, { expose: N, emit: $$1 }) {
    const a = Y$1, u = $$1, t = reactive({
      width: -1,
      mergedStyle: {},
      lastLayoutLength: 0,
      isDragging: false,
      placeholder: {
        x: 0,
        y: 0,
        w: 0,
        h: 0,
        i: ""
      },
      layouts: {},
      // array to store all layouts from different breakpoints
      lastBreakpoint: null,
      // store last active breakpoint
      originalLayout: null
      // store original Layout
    }), k$1 = /* @__PURE__ */ new Map(), o = ref(a.layout), g = ref(), { observeResize: A$1, unobserveResize: U } = wo(), r = Zr();
    r.on("resizeEvent", q), r.on("dragEvent", G), onBeforeMount(() => {
      u("layout-before-mount", o.value);
    }), onMounted(() => {
      u("layout-mounted", o.value), nextTick(() => {
        k(o.value), t.originalLayout = o.value, nextTick(() => {
          D(), g.value && A$1(g.value, no(C$1, 16)), $(o.value, a.verticalCompact), u("layout-updated", o.value), y$1(), C$1();
        });
      });
    }), onBeforeUnmount(() => {
      r.clearAll(), g.value && U(g.value);
    });
    function q(e, n, l, f, d, c) {
      S(e, n, l, f, d, c);
    }
    function G(e, n, l, f, d, c) {
      E(e, n, l, f, d, c);
    }
    watch(
      () => t.width,
      (e, n) => {
        nextTick(() => {
          r.emit("updateWidth", e), n === -1 && nextTick(() => {
            u("layout-ready", o.value);
          }), y$1();
        });
      }
    ), watch(
      () => [a.layout, a.layout.length],
      () => {
        o.value = a.layout, R();
      }
    ), watch(
      () => a.colNum,
      (e) => {
        r.emit("setColNum", e);
      }
    ), watch(
      () => a.rowHeight,
      (e) => {
        r.emit("setRowHeight", e);
      }
    ), watch(
      () => a.isDraggable,
      (e) => {
        r.emit("setDraggable", e);
      }
    ), watch(
      () => a.isResizable,
      (e) => {
        r.emit("setResizable", e);
      }
    ), watch(
      () => a.isBounded,
      (e) => {
        r.emit("setBounded", e);
      }
    ), watch(
      () => a.transformScale,
      (e) => {
        r.emit("setTransformScale", e);
      }
    ), watch(
      () => a.responsive,
      (e) => {
        e || (u("update:layout", t.originalLayout), r.emit("setColNum", a.colNum)), C$1();
      }
    ), watch(
      () => a.maxRows,
      (e) => {
        r.emit("setMaxRows", e);
      }
    ), watch([() => a.margin, () => a.margin[1]], y$1), provide(
      T,
      reactive({
        ...toRefs(a),
        ...toRefs(t),
        increaseItem: K,
        decreaseItem: j
      })
    ), provide(v, r), N({ state: t, getItem: P, resizeEvent: S, dragEvent: E, layoutUpdate: R });
    function K(e) {
      k$1.set(e.i, e);
    }
    function j(e) {
      k$1.delete(e.i);
    }
    function P(e) {
      return k$1.get(e);
    }
    function R() {
      if (!ie(o.value) && !ie(t.originalLayout)) {
        if (o.value.length !== t.originalLayout.length) {
          const e = J(o.value, t.originalLayout);
          if (e.length > 0)
            if (o.value.length > t.originalLayout.length)
              t.originalLayout = t.originalLayout.concat(e);
            else {
              const n = new Set(e.map((l) => l.i));
              t.originalLayout = t.originalLayout.filter((l) => !n.has(l.i));
            }
          t.lastLayoutLength = o.value.length, D();
        }
        $(o.value, a.verticalCompact), r.emit("updateWidth", t.width), y$1(), u("layout-updated", o.value);
      }
    }
    function y$1() {
      t.mergedStyle = {
        height: V()
      };
    }
    function C$1() {
      g.value && (t.width = g.value.offsetWidth), r.emit("resizeEvent");
    }
    function V() {
      if (!a.autoSize) return;
      const e = parseFloat(a.margin[1]);
      return A(o.value) * (a.rowHeight + e) + e + "px";
    }
    let b;
    function E(e, n, l, f, d, c) {
      let i = C(o.value, n);
      ie(i) && (i = { h: 0, w: 0, x: 0, y: 0, i: "" }), e === "dragstart" && !a.verticalCompact && (b = o.value.reduce(
        (v2, { i: x2, x: p, y: h }) => ({
          ...v2,
          [x2]: { x: p, y: h }
        }),
        {}
      )), e === "dragmove" || e === "dragstart" ? (t.placeholder.i = n, t.placeholder.x = i.x, t.placeholder.y = i.y, t.placeholder.w = c, t.placeholder.h = d, nextTick(() => {
        t.isDragging = true;
      }), r.emit("updateWidth", t.width)) : nextTick(() => {
        t.isDragging = false;
      }), o.value = x(o.value, i, l, f, true, a.preventCollision), a.restoreOnDrag ? (i.static = true, $(o.value, a.verticalCompact, b), i.static = false) : $(o.value, a.verticalCompact), r.emit("compact"), y$1(), e === "dragend" && (b = void 0, u("layout-updated", o.value));
    }
    function S(e, n, l, f, d, c) {
      let i = C(o.value, n);
      ie(i) && (i = { h: 0, w: 0, x: 0, y: 0, i: "" });
      let v2;
      if (a.preventCollision) {
        const x2 = L(o.value, { ...i, w: c, h: d }).filter(
          (p) => p.i !== i.i
        );
        if (v2 = x2.length > 0, v2) {
          let p = 1 / 0, h = 1 / 0;
          x2.forEach((L2) => {
            L2.x > i.x && (p = Math.min(p, L2.x)), L2.y > i.y && (h = Math.min(h, L2.y));
          }), Number.isFinite(p) && (i.w = p - i.x), Number.isFinite(h) && (i.h = h - i.y);
        }
      }
      v2 || (i.w = c, i.h = d), e === "resizestart" || e === "resizemove" ? (t.placeholder.i = n, t.placeholder.x = l, t.placeholder.y = f, t.placeholder.w = i.w, t.placeholder.h = i.h, nextTick(() => {
        t.isDragging = true;
      }), r.emit("updateWidth", t.width)) : e && nextTick(() => {
        t.isDragging = false;
      }), a.responsive && X(), $(o.value, a.verticalCompact), r.emit("compact"), y$1(), e === "resizeend" && u("layout-updated", o.value);
    }
    function X() {
      const e = y(a.breakpoints, t.width);
      if (e === t.lastBreakpoint)
        return;
      const n = B(e, a.cols);
      !ie(t.lastBreakpoint) && !t.layouts[t.lastBreakpoint] && (t.layouts[t.lastBreakpoint] = Y(o.value));
      const l = v$1(
        t.originalLayout,
        t.layouts,
        a.breakpoints,
        e,
        t.lastBreakpoint,
        n,
        a.verticalCompact
      );
      t.layouts[e] = l, t.lastBreakpoint !== e && u("breakpoint-changed", e, l), o.value = l, u("update:layout", l), t.lastBreakpoint = e, r.emit("setColNum", n);
    }
    function D() {
      t.layouts = Object.assign({}, a.responsiveLayouts);
    }
    function J(e, n) {
      const l = new Set(n.map((i) => i.i)), f = new Set(e.map((i) => i.i)), d = e.filter((i) => !l.has(i.i)), c = n.filter((i) => !f.has(i.i));
      return d.concat(c);
    }
    return (e, n) => (openBlock(), createElementBlock("div", {
      ref_key: "wrapper",
      ref: g,
      class: "vgl-layout",
      style: normalizeStyle(t.mergedStyle)
    }, [
      e.$slots.default ? renderSlot(e.$slots, "default", { key: 0 }) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(o.value, (l) => (openBlock(), createBlock(st, mergeProps({
        key: l.i,
        ref_for: true
      }, l), {
        default: withCtx(() => [
          renderSlot(e.$slots, "item", { item: l })
        ]),
        _: 2
      }, 1040))), 128)),
      withDirectives(createVNode(st, {
        class: "vgl-item--placeholder",
        x: t.placeholder.x,
        y: t.placeholder.y,
        w: t.placeholder.w,
        h: t.placeholder.h,
        i: t.placeholder.i
      }, null, 8, ["x", "y", "w", "h", "i"]), [
        [vShow, t.isDragging]
      ])
    ], 4));
  }
});
export {
  De as default
};
