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