import { jsx as _jsx } from "react/jsx-runtime";
import { useRef, useState } from 'react';
import Box from '../box';
import { KeyboardKeys, vui } from '../core';
import Icon from '../icon';
import { mergeRefs } from '../utils';
import theme from './theme';
export const Rating = vui((props, ref) => {
    const { value: propValue = 0, isDisabled = false, max: propMax, onChange, showAll: showAllProp = true, variant = 'yellow', size, ...rest } = props;
    const [hoverValue, setHoverValue] = useState(null);
    const [internalValue, setInternalValue] = useState(propValue || 0);
    const [focusedStar, setFocusedStar] = useState(null);
    const containerRef = useRef(null);
    const isInteractive = !isDisabled && onChange !== undefined;
    const showAll = showAllProp || isInteractive;
    const { variants } = theme ?? {};
    const color = isDisabled ? 'sandstone.79' : variants[variant].color;
    if (propValue < 0) {
        console.error(`Rating: value (${propValue}) cannot be negative`);
    }
    const value = Math.max(0, propValue);
    const max = propMax ? propMax : Math.max(value, 5);
    if (value > max) {
        console.error(`Rating: value (${value}) cannot be greater than max (${max})`);
    }
    const handleValueChange = (newValue) => {
        if (!isInteractive)
            return;
        const clampedValue = Math.max(0, Math.min(newValue, max));
        setInternalValue(clampedValue);
        onChange?.(clampedValue);
    };
    const handleStarClick = (clickedValue) => {
        if (!isInteractive)
            return;
        const newValue = clickedValue === internalValue ? 0 : clickedValue;
        handleValueChange(newValue);
    };
    const handleStarHover = (hoveredValue) => {
        if (!isInteractive)
            return;
        setHoverValue(hoveredValue);
    };
    const handleMouseLeave = () => {
        if (!isInteractive)
            return;
        setHoverValue(null);
    };
    const handleKeyDown = (event) => {
        if (!isInteractive)
            return;
        const currentValue = propValue !== undefined ? propValue : internalValue;
        switch (event.key) {
            case KeyboardKeys.ArrowRight:
            case KeyboardKeys.ArrowUp:
                event.preventDefault();
                handleValueChange(Math.min(currentValue + 1, max));
                break;
            case KeyboardKeys.ArrowLeft:
            case KeyboardKeys.ArrowDown:
                event.preventDefault();
                handleValueChange(Math.max(currentValue - 1, 0));
                break;
            case KeyboardKeys.Home:
                event.preventDefault();
                handleValueChange(0);
                break;
            case KeyboardKeys.End:
                event.preventDefault();
                handleValueChange(max);
                break;
        }
    };
    const handleFocus = () => {
        if (!isInteractive)
            return;
        if (focusedStar === null) {
            setFocusedStar(propValue !== undefined ? propValue : internalValue);
        }
    };
    const handleBlur = () => {
        if (!isInteractive)
            return;
        setFocusedStar(null);
    };
    const displayValue = hoverValue !== null ? hoverValue : value !== undefined ? value : internalValue;
    return (_jsx(Box, { "aria-label": "Rating", "aria-valuemax": max, "aria-valuemin": 0, "aria-valuenow": displayValue, className: "vui-rating", focusRing: 3, focusRingColor: "focusColor", onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, onMouseLeave: handleMouseLeave, outline: "none", ref: mergeRefs(ref, containerRef), role: "slider", tabIndex: isInteractive ? 0 : -1, ...rest, children: Array.from({ length: max }).map((_, index) => {
            const starValue = index + 1;
            const fullStar = index < displayValue;
            return (_jsx(Box, { className: "vui-rating-star", cursor: isInteractive ? 'pointer' : undefined, gap: "1px", onClick: () => handleStarClick(starValue), onFocus: () => setFocusedStar(starValue), onMouseEnter: () => handleStarHover(starValue), tabIndex: -1, children: fullStar ? (_jsx(FullStar, { color: color, size: size })) : showAll ? (_jsx(EmptyStar, { color: "sandstone.79", size: size })) : null }, index));
        }) }));
});
const FullStar = (props) => (_jsx(Icon, { color: props.color, name: "fasStar", size: props.size }));
const EmptyStar = (props) => (_jsx(Icon, { color: props.color, name: "falStar", size: props.size }));
Rating.displayName = 'Rating';
export default Rating;
//# sourceMappingURL=rating.js.map