var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name2 in all)
    __defProp(target, name2, { get: all[name2], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var stdin_exports = {};
__export(stdin_exports, {
  default: () => stdin_default,
  rateProps: () => rateProps
});
module.exports = __toCommonJS(stdin_exports);
var import_vue = require("vue");
var import_utils = require("../utils");
var import_use = require("@vant/use");
var import_use_refs = require("../composables/use-refs");
var import_use_touch = require("../composables/use-touch");
var import_icon = require("../icon");
const [name, bem] = (0, import_utils.createNamespace)("rate");
function getRateStatus(value, index, allowHalf, readonly) {
  if (value >= index) {
    return {
      status: "full",
      value: 1
    };
  }
  if (value + 0.5 >= index && allowHalf && !readonly) {
    return {
      status: "half",
      value: 0.5
    };
  }
  if (value + 1 >= index && allowHalf && readonly) {
    const cardinal = 10 ** 10;
    return {
      status: "half",
      value: Math.round((value - index + 1) * cardinal) / cardinal
    };
  }
  return {
    status: "void",
    value: 0
  };
}
const rateProps = {
  size: import_utils.numericProp,
  icon: (0, import_utils.makeStringProp)("star"),
  color: String,
  count: (0, import_utils.makeNumericProp)(5),
  gutter: import_utils.numericProp,
  clearable: Boolean,
  readonly: Boolean,
  disabled: Boolean,
  voidIcon: (0, import_utils.makeStringProp)("star-o"),
  allowHalf: Boolean,
  voidColor: String,
  touchable: import_utils.truthProp,
  iconPrefix: String,
  modelValue: (0, import_utils.makeNumberProp)(0),
  disabledColor: String
};
var stdin_default = (0, import_vue.defineComponent)({
  name,
  props: rateProps,
  emits: ["change", "update:modelValue"],
  setup(props, {
    emit
  }) {
    const touch = (0, import_use_touch.useTouch)();
    const [itemRefs, setItemRefs] = (0, import_use_refs.useRefs)();
    const groupRef = (0, import_vue.ref)();
    const unselectable = (0, import_vue.computed)(() => props.readonly || props.disabled);
    const untouchable = (0, import_vue.computed)(() => unselectable.value || !props.touchable);
    const list = (0, import_vue.computed)(() => Array(+props.count).fill("").map((_, i) => getRateStatus(props.modelValue, i + 1, props.allowHalf, props.readonly)));
    let ranges;
    let groupRefRect;
    let minRectTop = Number.MAX_SAFE_INTEGER;
    let maxRectTop = Number.MIN_SAFE_INTEGER;
    const updateRanges = () => {
      groupRefRect = (0, import_use.useRect)(groupRef);
      const rects = itemRefs.value.map(import_use.useRect);
      ranges = [];
      rects.forEach((rect, index) => {
        minRectTop = Math.min(rect.top, minRectTop);
        maxRectTop = Math.max(rect.top, maxRectTop);
        if (props.allowHalf) {
          ranges.push({
            score: index + 0.5,
            left: rect.left,
            top: rect.top,
            height: rect.height
          }, {
            score: index + 1,
            left: rect.left + rect.width / 2,
            top: rect.top,
            height: rect.height
          });
        } else {
          ranges.push({
            score: index + 1,
            left: rect.left,
            top: rect.top,
            height: rect.height
          });
        }
      });
    };
    const getScoreByPosition = (x, y) => {
      for (let i = ranges.length - 1; i > 0; i--) {
        if (y >= groupRefRect.top && y <= groupRefRect.bottom) {
          if (x > ranges[i].left && y >= ranges[i].top && y <= ranges[i].top + ranges[i].height) {
            return ranges[i].score;
          }
        } else {
          const curTop = y < groupRefRect.top ? minRectTop : maxRectTop;
          if (x > ranges[i].left && ranges[i].top === curTop) {
            return ranges[i].score;
          }
        }
      }
      return props.allowHalf ? 0.5 : 1;
    };
    const select = (value) => {
      if (unselectable.value || value === props.modelValue) return;
      emit("update:modelValue", value);
      emit("change", value);
    };
    const onTouchStart = (event) => {
      if (untouchable.value) {
        return;
      }
      touch.start(event);
      updateRanges();
    };
    const onTouchMove = (event) => {
      if (untouchable.value) {
        return;
      }
      touch.move(event);
      if (touch.isHorizontal() && !touch.isTap.value) {
        const {
          clientX,
          clientY
        } = event.touches[0];
        (0, import_utils.preventDefault)(event);
        select(getScoreByPosition(clientX, clientY));
      }
    };
    const renderStar = (item, index) => {
      const {
        icon,
        size,
        color,
        count,
        gutter,
        voidIcon,
        disabled,
        voidColor,
        allowHalf,
        iconPrefix,
        disabledColor
      } = props;
      const score = index + 1;
      const isFull = item.status === "full";
      const isVoid = item.status === "void";
      const renderHalf = allowHalf && item.value > 0 && item.value < 1;
      let style;
      if (gutter && score !== +count) {
        style = {
          paddingRight: (0, import_utils.addUnit)(gutter)
        };
      }
      const onClickItem = (event) => {
        updateRanges();
        let value = allowHalf ? getScoreByPosition(event.clientX, event.clientY) : score;
        if (props.clearable && touch.isTap.value && value === props.modelValue) {
          value = 0;
        }
        select(value);
      };
      return (0, import_vue.createVNode)("div", {
        "key": index,
        "ref": setItemRefs(index),
        "role": "radio",
        "style": style,
        "class": bem("item"),
        "tabindex": disabled ? void 0 : 0,
        "aria-setsize": count,
        "aria-posinset": score,
        "aria-checked": !isVoid,
        "onClick": onClickItem
      }, [(0, import_vue.createVNode)(import_icon.Icon, {
        "size": size,
        "name": isFull ? icon : voidIcon,
        "class": bem("icon", {
          disabled,
          full: isFull
        }),
        "color": disabled ? disabledColor : isFull ? color : voidColor,
        "classPrefix": iconPrefix
      }, null), renderHalf && (0, import_vue.createVNode)(import_icon.Icon, {
        "size": size,
        "style": {
          width: item.value + "em"
        },
        "name": isVoid ? voidIcon : icon,
        "class": bem("icon", ["half", {
          disabled,
          full: !isVoid
        }]),
        "color": disabled ? disabledColor : isVoid ? voidColor : color,
        "classPrefix": iconPrefix
      }, null)]);
    };
    (0, import_use.useCustomFieldValue)(() => props.modelValue);
    (0, import_use.useEventListener)("touchmove", onTouchMove, {
      target: groupRef
    });
    return () => (0, import_vue.createVNode)("div", {
      "ref": groupRef,
      "role": "radiogroup",
      "class": bem({
        readonly: props.readonly,
        disabled: props.disabled
      }),
      "tabindex": props.disabled ? void 0 : 0,
      "aria-disabled": props.disabled,
      "aria-readonly": props.readonly,
      "onTouchstartPassive": onTouchStart
    }, [list.value.map(renderStar)]);
  }
});
