"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get getDynamicLabelClasses () {
        return getDynamicLabelClasses;
    },
    get textAreaConfig () {
        return textAreaConfig;
    },
    get textAreaRoot () {
        return textAreaRoot;
    }
});
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
const _react1 = require("@emotion/react");
const _utils = require("../../utils");
const _hooks = require("../../hooks");
const _mixins = require("./mixins");
const _hooks1 = require("./hooks");
const _TextAreastyles = require("./TextArea.styles");
const _TextAreatokens = require("./TextArea.tokens");
const _base = require("./variations/_view/base");
const _base1 = require("./variations/_size/base");
const _base2 = require("./variations/_read-only/base");
const _base3 = require("./variations/_disabled/base");
const _base4 = require("./variations/_hint-view/base");
const _base5 = require("./variations/_hint-size/base");
const _Hint = require("./ui/Hint/Hint");
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
const { innerPlaceholderUp, focusedOuterPlaceholderColor, hidePlaceHolder, styledContainer, styledTextArea, styledTextAreaWrapper, styledPlaceholder, styledHelpers, hasHeaderSlot, styledContentWrapper } = _TextAreatokens.classes;
const base = (0, /*#__PURE__*/ _react1.css)(_mixins.applyDynamicLabel, ";position:relative;box-sizing:border-box;display:flex;flex-direction:column;", "base");
const getDimensionValue = (value)=>{
    if (value === undefined || value === null || value === '') return undefined;
    return Number.isNaN(Number(value)) ? String(value) : `${value}rem`;
};
// TODO: Удалить после отказа от старых библиотек plasma-web / plasma-b2c
const fallbackStatusMap = {
    '': 'primary',
    success: 'positive',
    warning: 'warning',
    error: 'negative'
};
const HINT_DEFAULT_OFFSET = [
    0,
    0
];
const getDynamicLabelClasses = (props, focused)=>{
    const { readOnly, label, labelPlacement, rows, value, size } = props;
    // Добавить класс отвечающий за изменение цвета плейсхолдера при фокусе
    const withFocusedOuterUpPlaceholder = !readOnly && focused && (!label || labelPlacement === 'outer') ? focusedOuterPlaceholderColor : undefined;
    // Добавить класс отвечающий за поднятие и уменьшение плейсхолдера
    const withInnerPlaceholderUp = labelPlacement === 'inner' && label && !rows && size !== 'xs' && (!readOnly && (value || focused) || readOnly && value) ? innerPlaceholderUp : undefined;
    // Добавить класс отвечающий за скрытие плейсхолдера
    const withHidePlaceholder = value && !label || labelPlacement === 'inner' && (focused && !readOnly || value) && label && rows || labelPlacement === 'outer' && value || labelPlacement === 'inner' && size === 'xs' && value ? hidePlaceHolder : undefined;
    return [
        withFocusedOuterUpPlaceholder,
        withInnerPlaceholderUp,
        withHidePlaceholder
    ];
};
const textAreaRoot = (Root)=>/*#__PURE__*/ (0, _react.forwardRef)((props, innerRef)=>{
        const { id, className, style, // layout
        label, labelPlacement = 'inner', titleCaption, placeholder, leftHelper, leftHelperPlacement = 'inner', rightHelperPlacement = 'inner', helperText, rightHelper, contentRight, headerSlot, requiredPlacement = 'right', hasRequiredIndicator = false, // hint
        hintTrigger = 'hover', hintText, hintView = 'default', hintSize = 'm', hintTargetIcon, hintPlacement = 'auto', hintHasArrow, hintOffset = HINT_DEFAULT_OFFSET, hintWidth, hintContentLeft, // variations
        appearance, status, view, size, readOnly, disabled, required = false, clear, optional = false, optionalText = 'optional', hasDivider, // controlled
        value, defaultValue, // textarea-specific
        resize, autoResize = false, minAuto = 0, maxAuto, height, width, rows, cols, // events
        onChange, // additional
        labelAriaHidden = false, ...rest } = props;
        const [isHintVisible, setIsHintVisible] = (0, _react.useState)(false);
        const computedHeight = getDimensionValue(height);
        const [helperWidth, setHelperWidth] = (0, _react.useState)('100%');
        const innerWidth = getDimensionValue(width) || helperWidth;
        const [focused, setFocused] = (0, _react.useState)(false);
        // TODO: перенести в общую переменную для value снаружи и внутри
        const [uncontrolledValue, setUncontrolledValue] = (0, _react.useState)();
        const outerRef = /*#__PURE__*/ (0, _react.createRef)();
        const hiddenRef = (0, _react.useRef)(null);
        const hintRef = (0, _react.useRef)(null);
        (0, _hooks.useOutsideClick)(()=>{
            setIsHintVisible(false);
        }, [
            hintRef
        ]);
        const isInnerLeftHelperPlacement = leftHelperPlacement === 'inner';
        const isInnerRightHelperPlacement = rightHelperPlacement === 'inner';
        const leftHelperText = leftHelper || helperText;
        const innerOptional = required ? false : optional;
        const hasLeftHelper = Boolean(leftHelper || helperText);
        const hasRightHelper = Boolean(rightHelper);
        const hasHelper = isInnerLeftHelperPlacement && hasLeftHelper || isInnerRightHelperPlacement && hasRightHelper;
        const hasOuterLabel = Boolean(label && labelPlacement === 'outer');
        const hasInnerLabel = Boolean(label && labelPlacement === 'inner' && size !== 'xs');
        const hasPlaceholderOptional = innerOptional && !hasOuterLabel;
        const hasHeader = Boolean(headerSlot) && !(clear || appearance === 'clear');
        const overriddenView = status !== undefined ? fallbackStatusMap[status] : view;
        const textareaHelperId = id ? `${id}-helper` : undefined;
        const hasExplicitHeight = Boolean(computedHeight);
        const placeholderLabel = hasInnerLabel ? label : placeholder;
        const applyAutoResize = autoResize || Boolean(clear || appearance === 'clear' || appearance === 'viewMode');
        const clearClass = clear || appearance === 'clear' ? _TextAreatokens.classes.clear : undefined;
        const hasHintClass = hintText ? _TextAreatokens.classes.hasHint : undefined;
        const hasRightContentClass = contentRight ? _TextAreatokens.classes.hasRightContent : undefined;
        const hasDividerClass = hasDivider ? _TextAreatokens.classes.hasDivider : undefined;
        const requiredPlacementClass = requiredPlacement === 'right' ? _TextAreatokens.classes.requiredAlignRight : undefined;
        const handleHintShow = ()=>setIsHintVisible(true);
        const handleHintHide = ()=>setIsHintVisible(false);
        const handleHintClick = (event)=>{
            if (!hintText || hintTrigger !== 'click') {
                return;
            }
            event.stopPropagation();
            const targetIsPopover = event.target === hintRef.current;
            const rootHasTarget = hintRef.current?.contains(event.target);
            if (!targetIsPopover && !rootHasTarget) {
                setIsHintVisible(true);
            }
        };
        (0, _react.useLayoutEffect)(()=>{
            if (outerRef.current) {
                setUncontrolledValue(outerRef.current.value);
            }
        }, [
            outerRef
        ]);
        (0, _react.useLayoutEffect)(()=>{
            if (!hiddenRef.current || !cols) {
                return;
            }
            const { width: elementWidth } = hiddenRef.current.getBoundingClientRect();
            setHelperWidth(`${elementWidth / _hooks1.ROOT_FONT_SIZE}rem`);
        }, [
            cols
        ]);
        (0, _hooks.useResizeObserver)(outerRef, (currentElement)=>{
            const { width: inlineWidth } = currentElement.style;
            if (inlineWidth) {
                const { width: elementWidth } = currentElement.getBoundingClientRect();
                setHelperWidth(`${elementWidth / _hooks1.ROOT_FONT_SIZE}rem`);
            }
        });
        (0, _hooks1.useAutoResize)(applyAutoResize, outerRef, value || uncontrolledValue, minAuto, maxAuto, resize, hiddenRef, size);
        const onFocusHandler = (0, _react.useCallback)(()=>{
            setFocused(true);
        }, []);
        const onBlurHandler = (0, _react.useCallback)(()=>{
            setFocused(false);
        }, []);
        const onChangeHandler = (0, _react.useCallback)((event)=>{
            // INFO: Для крайне редких кейсов, когда value снаружи не контролируется
            if (value === undefined) {
                setUncontrolledValue(event?.target.value);
            }
            onChange?.(event);
        }, [
            value,
            onChange
        ]);
        const handleTextAreaFocus = ()=>{
            if (readOnly || disabled || !outerRef?.current) {
                return;
            }
            outerRef.current.focus();
        };
        const dynamicLabelClasses = getDynamicLabelClasses({
            size,
            readOnly,
            label,
            labelPlacement,
            value: value || uncontrolledValue || defaultValue,
            rows,
            labelAriaHidden
        }, focused);
        const optionalTextNode = innerOptional ? /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledOptionalText, {
            inheritFont: !hasOuterLabel
        }, Boolean(hasPlaceholderOptional && (placeholderLabel || label)) && '\xa0', optionalText) : null;
        return /*#__PURE__*/ _react.default.createElement(Root, {
            view: overriddenView,
            size: size,
            disabled: disabled,
            readOnly: readOnly,
            style: {
                width: innerWidth,
                height: computedHeight,
                ...hasExplicitHeight && {
                    [_TextAreatokens.privateTokens.inputActualHeight]: '100%'
                },
                ...style
            },
            className: (0, _utils.cx)(clearClass, hasDividerClass, hasHintClass, className),
            onClick: handleTextAreaFocus,
            "data-root": true,
            ...hintText && {
                hintView,
                hintSize
            }
        }, (hasOuterLabel || titleCaption) && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.OuterLabelWrapper, {
            isInnerLabel: labelPlacement === 'inner'
        }, hasOuterLabel && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledIndicatorWrapper, null, /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledLabel, {
            "aria-hidden": labelAriaHidden
        }, label), hintText && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledHintWrapper, null, /*#__PURE__*/ _react.default.createElement(_Hint.HintComponent, {
            ref: hintRef,
            hintText: hintText,
            hintTrigger: hintTrigger,
            isHintVisible: isHintVisible,
            hintTargetIcon: hintTargetIcon,
            hintPlacement: hintPlacement,
            hintHasArrow: hintHasArrow,
            hintOffset: hintOffset,
            hintWidth: hintWidth,
            hintContentLeft: hintContentLeft,
            handleHintShow: handleHintShow,
            handleHintHide: handleHintHide,
            handleHintClick: handleHintClick
        })), required && hasRequiredIndicator && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledIndicator, {
            className: (0, _utils.cx)(_TextAreatokens.classes.outerLabelPlacement, requiredPlacementClass, hasHintClass)
        }), optionalTextNode), titleCaption && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.TitleCaption, null, titleCaption)), /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledContainer, {
            className: (0, _utils.cx)(styledContainer, ...dynamicLabelClasses),
            hasExplicitHeight: hasExplicitHeight,
            onFocus: onFocusHandler,
            onBlur: onBlurHandler
        }, !hasOuterLabel && /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, required && hasRequiredIndicator && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledIndicator, {
            className: (0, _utils.cx)(_TextAreatokens.classes.innerLabelPlacement, requiredPlacementClass)
        }), hintText && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledHintWrapper, {
            className: _TextAreatokens.classes.innerLabelPlacement
        }, /*#__PURE__*/ _react.default.createElement(_Hint.HintComponent, {
            ref: hintRef,
            hintText: hintText,
            hintTrigger: hintTrigger,
            isHintVisible: isHintVisible,
            hintTargetIcon: hintTargetIcon,
            hintPlacement: hintPlacement,
            hintHasArrow: hintHasArrow,
            hintOffset: hintOffset,
            hintWidth: hintWidth,
            hintContentLeft: hintContentLeft,
            size: size,
            handleHintShow: handleHintShow,
            handleHintHide: handleHintHide,
            handleHintClick: handleHintClick,
            isInnerLabel: true
        }))), /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledTextAreaWrapper, {
            className: (0, _utils.cx)(styledTextAreaWrapper, hasHeader && hasHeaderSlot),
            hasHelper: hasHelper,
            hasHeader: hasHeader,
            hasExplicitHeight: hasExplicitHeight,
            isClear: clear || appearance === 'clear'
        }, headerSlot && !clear && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledHeaderSlot, null, headerSlot), contentRight && !hasHeader && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledContent, null, contentRight), hasHeader && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledContentWrapper, {
            className: styledContentWrapper,
            hasHeader: hasHeader
        }, contentRight && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledContent, {
            hasHeader: hasHeader
        }, contentRight), headerSlot && placeholderLabel && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledPlaceholder, {
            hasContentRight: Boolean(contentRight),
            className: styledPlaceholder,
            htmlFor: id
        }, placeholderLabel, !hasOuterLabel && optionalTextNode)), /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledTextArea, {
            className: (0, _utils.cx)(styledTextArea, hasRightContentClass),
            id: id,
            hasContentRight: Boolean(contentRight),
            hasExplicitHeight: hasExplicitHeight,
            ref: (0, _utils.mergeRefs)(outerRef, innerRef),
            disabled: disabled,
            required: required,
            placeholder: placeholderLabel,
            "aria-describedby": textareaHelperId,
            value: value,
            readOnly: readOnly,
            rows: rows,
            cols: cols,
            resize: resize,
            defaultValue: defaultValue,
            onChange: onChangeHandler,
            ...rest
        }), Boolean(applyAutoResize || cols) && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledHiddenTextArea, {
            "aria-hidden": true,
            ref: hiddenRef,
            hasContentRight: Boolean(contentRight),
            value: value || uncontrolledValue || ' ',
            onChange: ()=>{},
            defaultValue: defaultValue,
            cols: cols
        })), hasHelper && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledHelpers, {
            className: styledHelpers,
            id: textareaHelperId
        }, hasLeftHelper && isInnerLeftHelperPlacement && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledLeftHelper, {
            className: focused ? _TextAreatokens.classes.leftHelperFocus : ''
        }, leftHelperText), hasRightHelper && isInnerRightHelperPlacement && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledRightHelper, {
            "data-root": true
        }, rightHelper)), !hasHeader && placeholderLabel && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledPlaceholder, {
            hasContentRight: Boolean(contentRight),
            className: styledPlaceholder,
            htmlFor: id
        }, placeholderLabel, !hasOuterLabel && optionalTextNode)), !isInnerLeftHelperPlacement && hasLeftHelper || !isInnerRightHelperPlacement && hasRightHelper ? /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledOutsideHelpersWrapper, {
            id: textareaHelperId
        }, !isInnerLeftHelperPlacement && hasLeftHelper && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledLeftHelper, null, leftHelperText), !isInnerRightHelperPlacement && hasRightHelper && /*#__PURE__*/ _react.default.createElement(_TextAreastyles.StyledRightHelper, {
            "data-root": true
        }, rightHelper)) : null);
    });
const textAreaConfig = {
    name: 'TextArea',
    tag: 'div',
    layout: textAreaRoot,
    base,
    variations: {
        size: {
            css: _base1.base
        },
        view: {
            css: _base.base
        },
        readOnly: {
            css: _base2.base,
            attrs: true
        },
        disabled: {
            css: _base3.base,
            attrs: true
        },
        hintView: {
            css: _base4.base
        },
        hintSize: {
            css: _base5.base
        }
    },
    defaults: {
        size: 'm',
        view: 'primary'
    }
};
