import { jsxs, jsx, Fragment } from "react/jsx-runtime";
import * as React from "react";
import { ImStarFull, ImStarEmpty } from "react-icons/im";
import { useBindingState } from "../../form/hooks/useBindingState.js";
import { repeat } from "../../utils/arrays.js";
import { concat } from "../../utils/classNames.js";
import { clamp } from "../../utils/maths.js";
import "../../utils/globals.js";
import "zod";
import { useDidUpdateEffect } from "../../hooks/useDidUpdateEffect.js";
import { Button } from "../button/button.component.js";
import { useArmstrongConfig } from "../config/config.context.js";
import { Label } from "../label/label.component.js";
import { StatusWrapper } from "../statusWrapper/statusWrapper.component.js";
import { ValidationErrors } from "../validationErrors/validationErrors.component.js";
import { iconJsxFromDefinition } from "./rating.utils.js";
import "./rating.theme.css.js";
const RatingPart = React.forwardRef(({ index, value, onSelectPart, filledIcon, emptyIcon, step, mode, readOnly, disabled }, ref) => {
  const steps = Math.floor(1 / (step || 1));
  const isFilled = value && value >= index + 1;
  const isPart = value && value < index + 1 && value > index;
  return jsxs("div", { ref, className: "arm-rating-part", style: value ? {
    "--rating-amount": `${clamp((value - index) * 100, 0, 100)}%`
  } : void 0, "data-filled": isFilled, "data-part": isPart, children: [jsxs("div", { className: "arm-rating-part-icon-wrapper", children: [filledIcon && jsx("div", { className: "arm-rating-part-icon arm-rating-part-filled", children: jsx("div", { className: "arm-rating-part-icon-inner", children: iconJsxFromDefinition(filledIcon, index) }) }), emptyIcon && jsx("div", { className: "arm-rating-part-icon arm-rating-part-empty", children: jsx("div", { className: "arm-rating-part-icon-inner", children: iconJsxFromDefinition(emptyIcon, index) }) })] }), !readOnly && mode === "buttons" && jsx("div", { className: "arm-rating-part-buttons", children: repeat(steps, (buttonIndex) => {
    const inputValue = index + (steps === 2 ? 0.5 : 1) + (buttonIndex ? 0.5 : 0);
    return jsx(Button, { role: "radio", "aria-checked": inputValue === value, type: "button", className: "arm-rating-button", onClick: () => onSelectPart((step || 1) * (buttonIndex + 1)), "aria-label": inputValue.toString(), disabled }, buttonIndex);
  }) }), !readOnly && mode === "radio" && jsx("div", { className: "arm-rating-part-radios", children: repeat(steps, (buttonIndex) => {
    const inputValue = index + (steps === 2 ? 0.5 : 1) + (buttonIndex ? 0.5 : 0);
    return jsx("div", { className: "arm-rating-part-radio-wrapper", children: jsx("input", { className: "arm-rating-part-radio", type: "radio", onChange: () => onSelectPart((step || 1) * (buttonIndex + 1)), "aria-label": inputValue.toString(), value: inputValue, checked: inputValue === value, disabled }) }, buttonIndex);
  }) })] });
});
RatingPart.displayName = "RatingPart";
const Rating = React.forwardRef(
  ({ bind, value, onValueChange, filledIcon, emptyIcon, maximum, className, validationErrorMessages, validationMode, errorIcon, scrollValidationErrorsIntoView, step, error, statusPosition, pending, leftOverlay, rightOverlay, mode, disabled, statusClassName, validationErrorsClassName, labelClassName, labelId, label, required, requiredIndicator, displaySize, autoValidate, ...htmlProps }, ref) => {
    const [boundValue, setBoundValue, bindConfig] = useBindingState(bind, {
      value,
      onChange: onValueChange,
      validationErrorMessages,
      validationMode,
      autoValidate,
      validationErrorIcon: errorIcon
    });
    const globals = useArmstrongConfig({
      validationMode: bindConfig.validationMode,
      inputDisplaySize: displaySize,
      scrollValidationErrorsIntoView,
      requiredIndicator,
      validationErrorIcon: bindConfig.validationErrorIcon,
      autoValidate: bindConfig.autoValidate
    });
    const generatedLabelId = React.useId();
    const finalLabelId = labelId ?? generatedLabelId;
    useDidUpdateEffect(() => {
      if (globals.autoValidate) {
        bindConfig.validate();
      }
      bindConfig.setTouched(true);
    }, [boundValue]);
    return jsxs(Fragment, { children: [jsxs("div", { ref, role: "radiogroup", "aria-label": boundValue !== void 0 ? `Rating: ${boundValue}/${maximum}` : void 0, ...htmlProps, className: concat("arm-rating", className), "data-read-only": !setBoundValue, "data-size": globals.inputDisplaySize, children: [label && jsx(Label, { id: finalLabelId, className: concat("arm-rating-input-label", labelClassName), "data-disabled": disabled, required, displaySize: globals.inputDisplaySize, requiredIndicator: globals.requiredIndicator, children: label }), jsx("div", { className: "arm-rating-input-inner", "aria-labelledby": finalLabelId, children: jsx(StatusWrapper, { error, statusPosition, errorIcon: bindConfig.validationErrorIcon, validationMode: bindConfig.validationMode, pending, children: jsxs(Fragment, { children: [leftOverlay, jsxs("div", { className: "arm-rating-parts", children: [repeat(maximum, (index) => jsx(RatingPart, { index, filledIcon, emptyIcon, value: boundValue || void 0, onSelectPart: (proportion) => setBoundValue == null ? void 0 : setBoundValue(index + proportion), step, mode, disabled, readOnly: !setBoundValue }, index)), mode === "range" && jsx("input", { className: "arm-rating-range", type: "range", step, min: 0, max: maximum, disabled, value: boundValue || void 0, onChange: (event) => setBoundValue == null ? void 0 : setBoundValue(event.currentTarget.valueAsNumber) })] }), rightOverlay] }) }) })] }), !!(validationErrorMessages == null ? void 0 : validationErrorMessages.length) && bindConfig.shouldShowValidationErrorMessage && jsx(ValidationErrors, { validationErrors: validationErrorMessages, validationMode: bindConfig.validationMode, scrollIntoView: scrollValidationErrorsIntoView })] });
  }
  // type assertion to ensure generic works with RefForwarded component
  // DO NOT CHANGE TYPE WITHOUT CHANGING THIS, FIND TYPE BY INSPECTING React.forwardRef
);
Rating.defaultProps = {
  maximum: 5,
  filledIcon: jsx(ImStarFull, {}),
  emptyIcon: jsx(ImStarEmpty, {}),
  step: 1,
  mode: "buttons"
};
Rating.displayName = "Rating";
export {
  Rating
};
//# sourceMappingURL=rating.component.js.map
