/**
 * @license MIT
 * author: Cube Dev Team
 * @cube-dev/ui-kit v0.0.0-canary-d4047d7
 * Released under the MIT license.
 */

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useFocusableRef } from '@react-spectrum/utils';
import { forwardRef, useMemo, useRef } from 'react';
import { useHover, useRadio } from 'react-aria';
import { useProviderProps } from '../../../provider.js';
import { extractStyles, filterBaseProps, OUTER_STYLES, tasty, } from '../../../tasty/index.js';
import { mergeProps } from '../../../utils/react/index.js';
import { useFocus } from '../../../utils/react/interactions.js';
import { Item } from '../../content/Item/Item.js';
import { INLINE_LABEL_STYLES, useFieldProps, useFormProps } from '../../form/index.js';
import { HiddenInput } from '../../HiddenInput.js';
import { useRadioProvider } from './context.js';
import { RadioGroup } from './RadioGroup.js';
export { useRadio };
const RadioButtonElement = tasty(Item, {
    qa: 'RadioButton',
    as: 'label',
    styles: {
        preset: 't3m',
        lineHeight: '1fs',
        flexGrow: 1,
        Label: {
            placeSelf: {
                '': 'center start',
                '!has-prefix & !has-suffix & !has-icon & !has-right-icon': 'center',
            },
        },
    },
});
const TabRadioButtonSelectedElement = tasty(RadioButtonElement, {
    styles: {
        fill: '#white',
        shadow: '$item-shadow',
    },
});
const RadioWrapperElement = tasty({
    as: 'label',
    qa: 'RadioWrapper',
    styles: {
        position: 'relative',
        display: 'grid',
        placeItems: 'center start',
        placeContent: 'center start',
        gap: '1x',
        flow: 'column',
        preset: 'default',
        width: 'min-content',
        margin: {
            '': '1x right',
            button: '0',
        },
        zIndex: {
            '': 'initial',
            checked: 1,
        },
        flexGrow: 1,
    },
});
const RadioNormalElement = tasty({
    styles: {
        display: 'grid',
        placeItems: 'center',
        radius: 'round',
        fill: {
            '': '#white',
            disabled: '#dark.04',
        },
        color: {
            checked: '#purple-text',
            'invalid & checked': '#danger-text',
            'disabled | !checked': '#clear',
            'disabled & checked': '#dark.12',
        },
        border: {
            '': '#dark-04',
            checked: '#purple-text',
            invalid: '#danger-text.50',
            disabled: '#dark.12',
        },
        width: '2x',
        height: '2x',
        outline: {
            '': '#purple-text.0',
            focused: '1bw #purple-text',
        },
        outlineOffset: 1,
        transition: 'theme',
        whiteSpace: 'nowrap',
        RadioCircle: {
            display: 'block',
            radius: 'round',
            width: '1x',
            height: '1x',
            fill: 'currentColor',
        },
    },
});
const RadioCircleElement = _jsx("div", { "data-element": "RadioCircle" });
const RadioLabelElement = tasty({
    qa: 'RadioLabel',
    styles: INLINE_LABEL_STYLES,
});
function Radio(props, ref) {
    props = useProviderProps(props);
    props = useFormProps(props);
    props = useFieldProps(props, { defaultValidationTrigger: 'onChange' });
    let { qa, isDisabled, isInvalid, children, label, autoFocus, labelStyles, labelProps, type, buttonType, size, icon, rightIcon, prefix, suffix, description, tooltip, hotkeys, 'aria-label': ariaLabel, form, ...otherProps } = props;
    label = label || children;
    let styles = extractStyles(otherProps, OUTER_STYLES);
    labelStyles = {
        ...INLINE_LABEL_STYLES,
        ...labelStyles,
    };
    let radioGroupProps = useRadioProvider();
    let state = radioGroupProps && radioGroupProps.state;
    let name = radioGroupProps && radioGroupProps.name;
    let contextSize = radioGroupProps?.size;
    let contextButtonType = radioGroupProps?.buttonType;
    let contextType = radioGroupProps?.type;
    let contextIsDisabled = radioGroupProps?.isDisabled;
    if (!state) {
        throw new Error('CubeUI: The Radio button is used outside the RadioGroup.');
    }
    // Determine effective type from props or context
    let effectiveType = type ?? contextType ?? 'radio';
    let isButton = effectiveType === 'button' || effectiveType === 'tabs';
    // Determine effective size with priority: prop > context > default
    let effectiveSize = (size ??
        contextSize ??
        (effectiveType === 'tabs' ? 'small' : 'medium'));
    // Apply size mapping for tabs mode button radios
    if (effectiveType === 'tabs' && isButton) {
        if (effectiveSize === 'small' || effectiveSize === 'medium') {
            effectiveSize = 'xsmall';
        }
        else if (effectiveSize === 'large') {
            effectiveSize = 'medium';
        }
        else if (effectiveSize === 'xlarge') {
            effectiveSize = 'large';
        }
        // 'xsmall' stays 'xsmall'
    }
    // Determine effective button type
    // In tabs mode, always use 'neutral' and ignore buttonType prop
    let effectiveButtonType;
    if (effectiveType === 'tabs') {
        effectiveButtonType = 'neutral'; // Force neutral for tabs, ignore buttonType
    }
    else {
        const baseButtonType = buttonType ?? contextButtonType ?? 'outline';
        // When buttonType is 'primary', use 'secondary' for non-selected and 'primary' for selected
        if (baseButtonType === 'primary') {
            effectiveButtonType =
                state.selectedValue === props.value ? 'primary' : 'secondary';
        }
        else {
            effectiveButtonType = baseButtonType;
        }
    }
    // Use context isDisabled if prop isDisabled is not explicitly set
    let effectiveIsDisabled = isDisabled ?? contextIsDisabled ?? false;
    let { isFocused, focusProps } = useFocus({ isDisabled: effectiveIsDisabled }, true);
    let { hoverProps, isHovered } = useHover({ isDisabled: effectiveIsDisabled });
    let inputRef = useRef(null);
    let domRef = useFocusableRef(ref, inputRef);
    let { inputProps, isDisabled: isRadioDisabled, isSelected: isRadioSelected, } = useRadio({
        name,
        ...props,
        isDisabled: effectiveIsDisabled,
    }, state, inputRef);
    const mods = useMemo(() => ({
        checked: isRadioSelected,
        invalid: !!isInvalid,
        disabled: isRadioDisabled,
        hovered: isHovered,
        button: isButton,
        focused: isFocused,
        tabs: effectiveType === 'tabs',
    }), [
        isRadioSelected,
        isInvalid,
        isRadioDisabled,
        isHovered,
        isButton,
        isFocused,
        effectiveType,
    ]);
    // Render button type using Item
    if (isButton) {
        const ButtonElement = isRadioSelected && contextType === 'tabs'
            ? TabRadioButtonSelectedElement
            : RadioButtonElement;
        return (_jsxs(ButtonElement, { ref: domRef, type: effectiveButtonType, theme: isInvalid ? 'danger' : 'default', size: effectiveSize, icon: icon, rightIcon: rightIcon, prefix: prefix, suffix: suffix, description: description, tooltip: tooltip, hotkeys: hotkeys, isSelected: isRadioSelected, isDisabled: isRadioDisabled, mods: mods, styles: styles, ...mergeProps(hoverProps, focusProps), children: [_jsx(HiddenInput, { qa: qa || 'Radio', "data-input-type": "radio", "aria-label": ariaLabel, ...inputProps, ref: inputRef, form: null, mods: { button: isButton, disabled: isRadioDisabled } }), label] }));
    }
    // Render classic radio type
    return (_jsxs(RadioWrapperElement, { styles: styles, ...hoverProps, ref: domRef, mods: mods, "data-type": type, children: [_jsx(HiddenInput, { qa: qa || 'Radio', "data-input-type": "radio", "aria-label": ariaLabel, ...mergeProps(inputProps, focusProps), ref: inputRef, mods: { button: isButton } }), _jsx(RadioNormalElement, { "data-element": "Input", mods: mods, "data-type": type, children: RadioCircleElement }), label && (_jsx(RadioLabelElement, { mods: mods, styles: labelStyles, ...filterBaseProps(labelProps), children: label }))] }));
}
/**
 * Radio buttons allow users to select a single option from a list of mutually exclusive options.
 * All possible options are exposed up front for users to compare.
 */
const _Radio = forwardRef(Radio);
const Tabs = tasty(RadioGroup, {
    type: 'tabs',
});
const ButtonGroup = tasty(RadioGroup, {
    type: 'button',
});
const __Radio = Object.assign(_Radio, {
    Group: RadioGroup,
    Tabs,
    ButtonGroup,
    Button: _Radio,
});
__Radio.displayName = 'Radio';
export { __Radio as Radio };

        