import React, { forwardRef, useState } from "react";
import { cx, getSizeValueFromProp, isNumber } from "../../utils";
import { IconMinus, IconPlus } from "../_Icon";
import { ActionButton, NumberInput } from "./ui";
import { classes, privateTokens } from "./NumberInput.tokens";
import { base } from "./NumberInput.styles";
import { base as viewCSS } from "./variations/_view/base";
import { base as sizeCSS } from "./variations/_size/base";
import { base as shapeCSS } from "./variations/_shape/base";
import { base as inputBackgroundTypeCSS } from "./variations/_background-type/base";
import { base as segmentationCSS } from "./variations/_segmentation/base";
import { base as disabledCSS } from "./variations/_disabled/base";
import { getPreciseValue } from "./utils";
export const numberInputRoot = (Root)=>/*#__PURE__*/ forwardRef(({ className, style, width, value: outerValue, min, max, step = 1, precision = 2, isLoading, loader, size, view, clear, shape, segmentation, inputBackgroundType = 'fill', disabled, textBefore, textAfter, customIncrementButton, incrementIcon, customDecrementButton, decrementIcon, isManualInput, displayWithoutValue = 'input', limitBehavior = 'disabled', onChange, onIncrement, onDecrement, ...rest }, ref)=>{
        if (outerValue && !isNumber(outerValue) && outerValue !== undefined && outerValue !== '-' && outerValue !== '.') {
            console.error('`value` должен быть undefined, числом или строкой с числом');
        }
        const [isInputFocused, setIsInputFocused] = useState(false);
        const [isAnimationRun, setIsAnimationRun] = useState(false);
        const [innerValue, setInnerValue] = useState('');
        const [shouldFocusInput, setShouldFocusInput] = useState(false);
        const value = outerValue ?? innerValue;
        const innerWidth = width ? getSizeValueFromProp(width) : '100%';
        const actionIconSize = size === 'xs' ? 'xs' : 's';
        const solidViewClass = segmentation === 'solid' ? classes.solidView : undefined;
        const segmentedViewClass = segmentation === 'segmented' ? classes.segmentedView : undefined;
        const clearViewClass = clear ? classes.clearView : undefined;
        const disabledClass = disabled ? classes.disabled : undefined;
        const loadingClass = isLoading ? classes.loading : undefined;
        const focusedClass = isInputFocused ? classes.focused : undefined;
        const isMinValue = (currentValue)=>min !== undefined && currentValue <= min;
        const isMaxValue = (currentValue)=>max !== undefined && currentValue >= max;
        const isValueEmpty = (value === '' || value === undefined) && !isManualInput;
        const onlyShowIncrement = isValueEmpty && displayWithoutValue === 'increment';
        const onlyShowDecrement = isValueEmpty && displayWithoutValue === 'decrement';
        const decrementAtLimit = isNumber(value) && value !== '' && isMinValue(Number(value)) && !isAnimationRun;
        const incrementAtLimit = isNumber(value) && value !== '' && isMaxValue(Number(value)) && !isAnimationRun;
        const decrementButtonDisabled = (decrementAtLimit && limitBehavior !== 'hidden' || isLoading) && !disabled ? classes.actionButtonDecrementDisabled : undefined;
        const incrementButtonDisabled = (incrementAtLimit && limitBehavior !== 'hidden' || isLoading) && !disabled ? classes.actionButtonIncrementDisabled : undefined;
        const decrementHiddenClass = decrementAtLimit && limitBehavior === 'hidden' ? classes.decrementHidden : undefined;
        const incrementHiddenClass = incrementAtLimit && limitBehavior === 'hidden' ? classes.incrementHidden : undefined;
        const onlyIncrementShownClass = onlyShowIncrement ? classes.onlyIncrementShown : undefined;
        const onlyDecrementShownClass = onlyShowDecrement ? classes.onlyDecrementShown : undefined;
        const handleDecrement = ()=>{
            if (isLoading || disabled || isAnimationRun) {
                return;
            }
            if (onlyShowDecrement) {
                setShouldFocusInput(true);
            }
            const processedValue = isNumber(value) && value !== '' ? Number(value) : max ?? 0;
            const preciseDiff = getPreciseValue(processedValue - step, precision);
            const diffValue = Number(preciseDiff);
            const resValue = min !== undefined && diffValue <= min ? min : diffValue;
            setInnerValue(resValue);
            if (onDecrement) {
                onDecrement(resValue);
            }
            if (onChange) {
                onChange(null, resValue);
            }
        };
        const handleIncrement = ()=>{
            if (isLoading || disabled || isAnimationRun) {
                return;
            }
            if (onlyShowIncrement) {
                setShouldFocusInput(true);
            }
            const processedValue = isNumber(value) && value !== '' ? Number(value) : min ?? 0;
            const preciseDiff = getPreciseValue(processedValue + step, precision);
            const diffValue = Number(preciseDiff);
            const resValue = max !== undefined && diffValue >= max ? max : diffValue;
            setInnerValue(resValue);
            if (onIncrement) {
                onIncrement(resValue);
            }
            if (onChange) {
                onChange(null, resValue);
            }
        };
        const decrementButton = customDecrementButton || /*#__PURE__*/ React.createElement(ActionButton, {
            className: cx(classes.actionButtonDecrement, decrementButtonDisabled, solidViewClass, segmentedViewClass),
            icon: decrementIcon || /*#__PURE__*/ React.createElement(IconMinus, {
                color: "inherit",
                size: actionIconSize
            }),
            onClick: handleDecrement,
            tabIndex: onlyShowDecrement ? 0 : -1
        });
        const incrementButton = customIncrementButton || /*#__PURE__*/ React.createElement(ActionButton, {
            className: cx(classes.actionButtonIncrement, incrementButtonDisabled, solidViewClass, segmentedViewClass),
            icon: incrementIcon || /*#__PURE__*/ React.createElement(IconPlus, {
                color: "inherit",
                size: actionIconSize
            }),
            onClick: handleIncrement,
            tabIndex: onlyShowIncrement ? 0 : -1
        });
        return /*#__PURE__*/ React.createElement(Root, {
            view: view,
            size: size,
            disabled: disabled,
            clear: clear,
            shape: shape,
            segmentation: segmentation,
            isLoading: isLoading,
            ...segmentation === 'solid' ? {
                inputBackgroundType: 'clear'
            } : {
                inputBackgroundType
            },
            className: cx(className, solidViewClass, segmentedViewClass, clearViewClass, disabledClass, loadingClass, focusedClass, decrementHiddenClass, incrementHiddenClass, onlyIncrementShownClass, onlyDecrementShownClass),
            style: {
                ...style,
                [privateTokens.inputWidth]: innerWidth
            }
        }, !onlyShowIncrement && decrementButton, !onlyShowIncrement && !onlyShowDecrement && /*#__PURE__*/ React.createElement(NumberInput, {
            ref: ref,
            segmentation: segmentation,
            value: value,
            precision: precision,
            min: min,
            max: max,
            isManualInput: isManualInput,
            textBefore: textBefore,
            textAfter: textAfter,
            isLoading: isLoading,
            loader: loader,
            disabled: disabled,
            isInputFocused: isInputFocused,
            setIsInputFocused: setIsInputFocused,
            setIsAnimationRun: setIsAnimationRun,
            setInnerValue: setInnerValue,
            onChange: onChange,
            onDecrementKey: handleDecrement,
            onIncrementKey: handleIncrement,
            shouldFocusInput: shouldFocusInput,
            onFocusHandled: ()=>setShouldFocusInput(false),
            ...rest
        }), !onlyShowDecrement && incrementButton);
    });
export const numberInputConfig = {
    name: 'NumberInput',
    tag: 'div',
    layout: numberInputRoot,
    base,
    variations: {
        view: {
            css: viewCSS
        },
        size: {
            css: sizeCSS
        },
        shape: {
            css: shapeCSS
        },
        inputBackgroundType: {
            css: inputBackgroundTypeCSS
        },
        segmentation: {
            css: segmentationCSS
        },
        disabled: {
            css: disabledCSS,
            attrs: true
        }
    },
    defaults: {
        view: 'default',
        size: 'l',
        shape: 'cornered',
        segmentation: 'default'
    }
};
