import { jsx } from "react/jsx-runtime";
import { u as useControllableState } from "../../index-vuqbEv5O.js";
import { createContext, useCallback, cloneElement, useState, useRef, Children, useEffect, useContext } from "react";
import { cn } from "../utils/cn.js";
import { c as createLucideIcon } from "../../createLucideIcon-Bni0WIE-.js";
/**
 * @license lucide-react v0.540.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */
const __iconNode = [
  [
    "path",
    {
      d: "M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",
      key: "r04s7s"
    }
  ]
];
const Star = createLucideIcon("star", __iconNode);
const RatingContext = createContext(null);
const useRating = () => {
  const context = useContext(RatingContext);
  if (!context) {
    throw new Error("useRating must be used within a Rating component");
  }
  return context;
};
const RatingButton = ({
  index: providedIndex,
  size = 20,
  className,
  icon = /* @__PURE__ */ jsx(Star, {})
}) => {
  const {
    value,
    readOnly,
    hoverValue,
    focusedStar,
    handleValueChange,
    handleKeyDown,
    setHoverValue,
    setFocusedStar
  } = useRating();
  const index = providedIndex ?? 0;
  const isActive = index < (hoverValue ?? focusedStar ?? value ?? 0);
  let tabIndex = -1;
  if (!readOnly) {
    tabIndex = value === index + 1 ? 0 : -1;
  }
  const handleClick = useCallback(
    (event) => {
      handleValueChange(event, index + 1);
    },
    [handleValueChange, index]
  );
  const handleMouseEnter = useCallback(() => {
    if (!readOnly) {
      setHoverValue(index + 1);
    }
  }, [readOnly, setHoverValue, index]);
  const handleFocus = useCallback(() => {
    setFocusedStar(index + 1);
  }, [setFocusedStar, index]);
  const handleBlur = useCallback(() => {
    setFocusedStar(null);
  }, [setFocusedStar]);
  return /* @__PURE__ */ jsx(
    "button",
    {
      className: cn(
        "rounded-full focus:outline-none focus-visible:ring-2 hover:scale-150 transition-all duration-200 focus-visible:ring-ring focus-visible:ring-offset-2",
        "p-0.5",
        readOnly && "cursor-default",
        className
      ),
      disabled: readOnly,
      onBlur: handleBlur,
      onClick: handleClick,
      onFocus: handleFocus,
      onKeyDown: handleKeyDown,
      onMouseEnter: handleMouseEnter,
      tabIndex,
      type: "button",
      children: cloneElement(icon, {
        width: size,
        height: size,
        style: {
          transition: "color 0.2s",
          color: isActive ? "var(--accent)" : "rgb(156, 163, 175)",
          fill: "currentColor",
          cursor: !readOnly ? "pointer" : void 0
        }
      })
    }
  );
};
const Rating = ({
  value: controlledValue,
  onValueChange: controlledOnValueChange,
  defaultValue = 0,
  onChange,
  readOnly = false,
  className,
  children,
  ...props
}) => {
  const [hoverValue, setHoverValue] = useState(null);
  const [focusedStar, setFocusedStar] = useState(null);
  const containerRef = useRef(null);
  const [value, onValueChange] = useControllableState({
    defaultProp: defaultValue,
    prop: controlledValue,
    onChange: controlledOnValueChange
  });
  const handleValueChange = useCallback(
    (event, newValue) => {
      if (!readOnly) {
        onChange?.(event, newValue);
        onValueChange?.(newValue);
      }
    },
    [readOnly, onChange, onValueChange]
  );
  const handleKeyDown = useCallback(
    (event) => {
      if (readOnly) {
        return;
      }
      const total = Children.count(children);
      let newValue = focusedStar !== null ? focusedStar : value ?? 0;
      switch (event.key) {
        case "ArrowRight":
          if (event.shiftKey || event.metaKey) {
            newValue = total;
          } else {
            newValue = Math.min(total, newValue + 1);
          }
          break;
        case "ArrowLeft":
          if (event.shiftKey || event.metaKey) {
            newValue = 1;
          } else {
            newValue = Math.max(1, newValue - 1);
          }
          break;
        default:
          return;
      }
      event.preventDefault();
      setFocusedStar(newValue);
      handleValueChange(event, newValue);
    },
    [focusedStar, value, children, readOnly, handleValueChange]
  );
  useEffect(() => {
    if (focusedStar !== null && containerRef.current) {
      const buttons = containerRef.current.querySelectorAll("button");
      buttons[focusedStar - 1]?.focus();
    }
  }, [focusedStar]);
  const contextValue = {
    value: value ?? 0,
    readOnly,
    hoverValue,
    focusedStar,
    handleValueChange,
    handleKeyDown,
    setHoverValue,
    setFocusedStar
  };
  return /* @__PURE__ */ jsx(RatingContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
    "div",
    {
      "aria-label": "Rating",
      className: cn("inline-flex items-center gap-0.5", className),
      onMouseLeave: () => setHoverValue(null),
      ref: containerRef,
      role: "radiogroup",
      ...props,
      children: Children.map(children, (child, index) => {
        if (!child) {
          return null;
        }
        return cloneElement(child, {
          index
        });
      })
    }
  ) });
};
export {
  Rating,
  RatingButton
};
