import { evaluate as M, getSide as H, getOppositePlacement as U, getExpandedPlacements as Z, getOppositeAxisPlacements as _, getAlignmentSides as ee, getSideAxis as W, clamp as z, getAlignment as Y, min as B, max as V, getAlignmentAxis as G, getPaddingObject as J, rectToClientRect as X, sides as te, getOppositeAxis as K, getAxisLength as N } from "../../utils/dist/floating-ui.utils.js";
function I(t, e, d) {
  let {
    reference: s,
    floating: r
  } = t;
  const n = W(e), o = G(e), m = N(o), l = H(e), u = n === "y", g = s.x + s.width / 2 - r.width / 2, a = s.y + s.height / 2 - r.height / 2, f = s[m] / 2 - r[m] / 2;
  let i;
  switch (l) {
    case "top":
      i = {
        x: g,
        y: s.y - r.height
      };
      break;
    case "bottom":
      i = {
        x: g,
        y: s.y + s.height
      };
      break;
    case "right":
      i = {
        x: s.x + s.width,
        y: a
      };
      break;
    case "left":
      i = {
        x: s.x - r.width,
        y: a
      };
      break;
    default:
      i = {
        x: s.x,
        y: s.y
      };
  }
  switch (Y(e)) {
    case "start":
      i[o] -= f * (d && u ? -1 : 1);
      break;
    case "end":
      i[o] += f * (d && u ? -1 : 1);
      break;
  }
  return i;
}
const se = async (t, e, d) => {
  const {
    placement: s = "bottom",
    strategy: r = "absolute",
    middleware: n = [],
    platform: o
  } = d, m = n.filter(Boolean), l = await (o.isRTL == null ? void 0 : o.isRTL(e));
  let u = await o.getElementRects({
    reference: t,
    floating: e,
    strategy: r
  }), {
    x: g,
    y: a
  } = I(u, s, l), f = s, i = {}, c = 0;
  for (let w = 0; w < m.length; w++) {
    const {
      name: x,
      fn: y
    } = m[w], {
      x: A,
      y: p,
      data: v,
      reset: h
    } = await y({
      x: g,
      y: a,
      initialPlacement: s,
      placement: f,
      strategy: r,
      middlewareData: i,
      rects: u,
      platform: o,
      elements: {
        reference: t,
        floating: e
      }
    });
    g = A ?? g, a = p ?? a, i = {
      ...i,
      [x]: {
        ...i[x],
        ...v
      }
    }, h && c <= 50 && (c++, typeof h == "object" && (h.placement && (f = h.placement), h.rects && (u = h.rects === !0 ? await o.getElementRects({
      reference: t,
      floating: e,
      strategy: r
    }) : h.rects), {
      x: g,
      y: a
    } = I(u, f, l)), w = -1);
  }
  return {
    x: g,
    y: a,
    placement: f,
    strategy: r,
    middlewareData: i
  };
};
async function j(t, e) {
  var d;
  e === void 0 && (e = {});
  const {
    x: s,
    y: r,
    platform: n,
    rects: o,
    elements: m,
    strategy: l
  } = t, {
    boundary: u = "clippingAncestors",
    rootBoundary: g = "viewport",
    elementContext: a = "floating",
    altBoundary: f = !1,
    padding: i = 0
  } = M(e, t), c = J(i), x = m[f ? a === "floating" ? "reference" : "floating" : a], y = X(await n.getClippingRect({
    element: (d = await (n.isElement == null ? void 0 : n.isElement(x))) == null || d ? x : x.contextElement || await (n.getDocumentElement == null ? void 0 : n.getDocumentElement(m.floating)),
    boundary: u,
    rootBoundary: g,
    strategy: l
  })), A = a === "floating" ? {
    x: s,
    y: r,
    width: o.floating.width,
    height: o.floating.height
  } : o.reference, p = await (n.getOffsetParent == null ? void 0 : n.getOffsetParent(m.floating)), v = await (n.isElement == null ? void 0 : n.isElement(p)) ? await (n.getScale == null ? void 0 : n.getScale(p)) || {
    x: 1,
    y: 1
  } : {
    x: 1,
    y: 1
  }, h = X(n.convertOffsetParentRelativeRectToViewportRelativeRect ? await n.convertOffsetParentRelativeRectToViewportRelativeRect({
    elements: m,
    rect: A,
    offsetParent: p,
    strategy: l
  }) : A);
  return {
    top: (y.top - h.top + c.top) / v.y,
    bottom: (h.bottom - y.bottom + c.bottom) / v.y,
    left: (y.left - h.left + c.left) / v.x,
    right: (h.right - y.right + c.right) / v.x
  };
}
const oe = (t) => ({
  name: "arrow",
  options: t,
  async fn(e) {
    const {
      x: d,
      y: s,
      placement: r,
      rects: n,
      platform: o,
      elements: m,
      middlewareData: l
    } = e, {
      element: u,
      padding: g = 0
    } = M(t, e) || {};
    if (u == null)
      return {};
    const a = J(g), f = {
      x: d,
      y: s
    }, i = G(r), c = N(i), w = await o.getDimensions(u), x = i === "y", y = x ? "top" : "left", A = x ? "bottom" : "right", p = x ? "clientHeight" : "clientWidth", v = n.reference[c] + n.reference[i] - f[i] - n.floating[c], h = f[i] - n.reference[i], b = await (o.getOffsetParent == null ? void 0 : o.getOffsetParent(u));
    let O = b ? b[p] : 0;
    (!O || !await (o.isElement == null ? void 0 : o.isElement(b))) && (O = m.floating[p] || n.floating[c]);
    const R = v / 2 - h / 2, E = O / 2 - w[c] / 2 - 1, T = B(a[y], E), L = B(a[A], E), C = T, F = O - w[c] - L, P = O / 2 - w[c] / 2 + R, S = z(C, P, F), k = !l.arrow && Y(r) != null && P !== S && n.reference[c] / 2 - (P < C ? T : L) - w[c] / 2 < 0, D = k ? P < C ? P - C : P - F : 0;
    return {
      [i]: f[i] + D,
      data: {
        [i]: S,
        centerOffset: P - S - D,
        ...k && {
          alignmentOffset: D
        }
      },
      reset: k
    };
  }
}), ce = function(t) {
  return t === void 0 && (t = {}), {
    name: "flip",
    options: t,
    async fn(e) {
      var d, s;
      const {
        placement: r,
        middlewareData: n,
        rects: o,
        initialPlacement: m,
        platform: l,
        elements: u
      } = e, {
        mainAxis: g = !0,
        crossAxis: a = !0,
        fallbackPlacements: f,
        fallbackStrategy: i = "bestFit",
        fallbackAxisSideDirection: c = "none",
        flipAlignment: w = !0,
        ...x
      } = M(t, e);
      if ((d = n.arrow) != null && d.alignmentOffset)
        return {};
      const y = H(r), A = H(m) === m, p = await (l.isRTL == null ? void 0 : l.isRTL(u.floating)), v = f || (A || !w ? [U(m)] : Z(m));
      !f && c !== "none" && v.push(..._(m, w, c, p));
      const h = [m, ...v], b = await j(e, x), O = [];
      let R = ((s = n.flip) == null ? void 0 : s.overflows) || [];
      if (g && O.push(b[y]), a) {
        const C = ee(r, o, p);
        O.push(b[C[0]], b[C[1]]);
      }
      if (R = [...R, {
        placement: r,
        overflows: O
      }], !O.every((C) => C <= 0)) {
        var E, T;
        const C = (((E = n.flip) == null ? void 0 : E.index) || 0) + 1, F = h[C];
        if (F)
          return {
            data: {
              index: C,
              overflows: R
            },
            reset: {
              placement: F
            }
          };
        let P = (T = R.filter((S) => S.overflows[0] <= 0).sort((S, k) => S.overflows[1] - k.overflows[1])[0]) == null ? void 0 : T.placement;
        if (!P)
          switch (i) {
            case "bestFit": {
              var L;
              const S = (L = R.map((k) => [k.placement, k.overflows.filter((D) => D > 0).reduce((D, Q) => D + Q, 0)]).sort((k, D) => k[1] - D[1])[0]) == null ? void 0 : L[0];
              S && (P = S);
              break;
            }
            case "initialPlacement":
              P = m;
              break;
          }
        if (r !== P)
          return {
            reset: {
              placement: P
            }
          };
      }
      return {};
    }
  };
};
function $(t, e) {
  return {
    top: t.top - e.height,
    right: t.right - e.width,
    bottom: t.bottom - e.height,
    left: t.left - e.width
  };
}
function q(t) {
  return te.some((e) => t[e] >= 0);
}
const le = function(t) {
  return t === void 0 && (t = {}), {
    name: "hide",
    options: t,
    async fn(e) {
      const {
        rects: d
      } = e, {
        strategy: s = "referenceHidden",
        ...r
      } = M(t, e);
      switch (s) {
        case "referenceHidden": {
          const n = await j(e, {
            ...r,
            elementContext: "reference"
          }), o = $(n, d.reference);
          return {
            data: {
              referenceHiddenOffsets: o,
              referenceHidden: q(o)
            }
          };
        }
        case "escaped": {
          const n = await j(e, {
            ...r,
            altBoundary: !0
          }), o = $(n, d.floating);
          return {
            data: {
              escapedOffsets: o,
              escaped: q(o)
            }
          };
        }
        default:
          return {};
      }
    }
  };
};
async function ne(t, e) {
  const {
    placement: d,
    platform: s,
    elements: r
  } = t, n = await (s.isRTL == null ? void 0 : s.isRTL(r.floating)), o = H(d), m = Y(d), l = W(d) === "y", u = ["left", "top"].includes(o) ? -1 : 1, g = n && l ? -1 : 1, a = M(e, t);
  let {
    mainAxis: f,
    crossAxis: i,
    alignmentAxis: c
  } = typeof a == "number" ? {
    mainAxis: a,
    crossAxis: 0,
    alignmentAxis: null
  } : {
    mainAxis: 0,
    crossAxis: 0,
    alignmentAxis: null,
    ...a
  };
  return m && typeof c == "number" && (i = m === "end" ? c * -1 : c), l ? {
    x: i * g,
    y: f * u
  } : {
    x: f * u,
    y: i * g
  };
}
const ae = function(t) {
  return t === void 0 && (t = 0), {
    name: "offset",
    options: t,
    async fn(e) {
      var d, s;
      const {
        x: r,
        y: n,
        placement: o,
        middlewareData: m
      } = e, l = await ne(e, t);
      return o === ((d = m.offset) == null ? void 0 : d.placement) && (s = m.arrow) != null && s.alignmentOffset ? {} : {
        x: r + l.x,
        y: n + l.y,
        data: {
          ...l,
          placement: o
        }
      };
    }
  };
}, re = function(t) {
  return t === void 0 && (t = {}), {
    name: "shift",
    options: t,
    async fn(e) {
      const {
        x: d,
        y: s,
        placement: r
      } = e, {
        mainAxis: n = !0,
        crossAxis: o = !1,
        limiter: m = {
          fn: (x) => {
            let {
              x: y,
              y: A
            } = x;
            return {
              x: y,
              y: A
            };
          }
        },
        ...l
      } = M(t, e), u = {
        x: d,
        y: s
      }, g = await j(e, l), a = W(H(r)), f = K(a);
      let i = u[f], c = u[a];
      if (n) {
        const x = f === "y" ? "top" : "left", y = f === "y" ? "bottom" : "right", A = i + g[x], p = i - g[y];
        i = z(A, i, p);
      }
      if (o) {
        const x = a === "y" ? "top" : "left", y = a === "y" ? "bottom" : "right", A = c + g[x], p = c - g[y];
        c = z(A, c, p);
      }
      const w = m.fn({
        ...e,
        [f]: i,
        [a]: c
      });
      return {
        ...w,
        data: {
          x: w.x - d,
          y: w.y - s
        }
      };
    }
  };
}, fe = function(t) {
  return t === void 0 && (t = {}), {
    options: t,
    fn(e) {
      const {
        x: d,
        y: s,
        placement: r,
        rects: n,
        middlewareData: o
      } = e, {
        offset: m = 0,
        mainAxis: l = !0,
        crossAxis: u = !0
      } = M(t, e), g = {
        x: d,
        y: s
      }, a = W(r), f = K(a);
      let i = g[f], c = g[a];
      const w = M(m, e), x = typeof w == "number" ? {
        mainAxis: w,
        crossAxis: 0
      } : {
        mainAxis: 0,
        crossAxis: 0,
        ...w
      };
      if (l) {
        const p = f === "y" ? "height" : "width", v = n.reference[f] - n.floating[p] + x.mainAxis, h = n.reference[f] + n.reference[p] - x.mainAxis;
        i < v ? i = v : i > h && (i = h);
      }
      if (u) {
        var y, A;
        const p = f === "y" ? "width" : "height", v = ["top", "left"].includes(H(r)), h = n.reference[a] - n.floating[p] + (v && ((y = o.offset) == null ? void 0 : y[a]) || 0) + (v ? 0 : x.crossAxis), b = n.reference[a] + n.reference[p] + (v ? 0 : ((A = o.offset) == null ? void 0 : A[a]) || 0) - (v ? x.crossAxis : 0);
        c < h ? c = h : c > b && (c = b);
      }
      return {
        [f]: i,
        [a]: c
      };
    }
  };
}, me = function(t) {
  return t === void 0 && (t = {}), {
    name: "size",
    options: t,
    async fn(e) {
      const {
        placement: d,
        rects: s,
        platform: r,
        elements: n
      } = e, {
        apply: o = () => {
        },
        ...m
      } = M(t, e), l = await j(e, m), u = H(d), g = Y(d), a = W(d) === "y", {
        width: f,
        height: i
      } = s.floating;
      let c, w;
      u === "top" || u === "bottom" ? (c = u, w = g === (await (r.isRTL == null ? void 0 : r.isRTL(n.floating)) ? "start" : "end") ? "left" : "right") : (w = u, c = g === "end" ? "top" : "bottom");
      const x = i - l.top - l.bottom, y = f - l.left - l.right, A = B(i - l[c], x), p = B(f - l[w], y), v = !e.middlewareData.shift;
      let h = A, b = p;
      if (a ? b = g || v ? B(p, y) : y : h = g || v ? B(A, x) : x, v && !g) {
        const R = V(l.left, 0), E = V(l.right, 0), T = V(l.top, 0), L = V(l.bottom, 0);
        a ? b = f - 2 * (R !== 0 || E !== 0 ? R + E : V(l.left, l.right)) : h = i - 2 * (T !== 0 || L !== 0 ? T + L : V(l.top, l.bottom));
      }
      await o({
        ...e,
        availableWidth: b,
        availableHeight: h
      });
      const O = await r.getDimensions(n.floating);
      return f !== O.width || i !== O.height ? {
        reset: {
          rects: !0
        }
      } : {};
    }
  };
};
export {
  oe as arrow,
  se as computePosition,
  j as detectOverflow,
  ce as flip,
  le as hide,
  fe as limitShift,
  ae as offset,
  X as rectToClientRect,
  re as shift,
  me as size
};
