import React, { useCallback, useId, useRef, useState } from "react";
import { useNativeValidity } from "../../../utils/index.js";
import { Suggestions } from "../Suggestions.js";
import { StyledInput, StyledInputContainer, StyledLabel, StyledPrefix, StyledSuffix, StyledWrapper, } from "./Input.styled.js";
const InputInner = ({ className, children, prefix, suffix, onFocus, onBlur, onKeyDown, onChange, suggestions, onSuggestionMatch, error, label, pinnedLabel = true, placeholder, id, ...props }, ref) => {
    const [focused, setFocused] = useState(false);
    const [internalHasValue, setInternalHasValue] = useState(() => {
        var _a;
        return Boolean((_a = props.value) !== null && _a !== void 0 ? _a : props.defaultValue);
    });
    const isControlled = props.value !== undefined;
    const hasValue = isControlled ? Boolean(props.value) : internalHasValue;
    const validity = useNativeValidity(error);
    const suggestionsId = useId();
    const generatedInputId = useId();
    const inputId = id !== null && id !== void 0 ? id : (label ? generatedInputId : undefined);
    const infoRef = useRef({});
    const handleFocus = useCallback((e) => {
        setFocused(true);
        onFocus === null || onFocus === void 0 ? void 0 : onFocus(e);
    }, [onFocus]);
    const handleBlur = useCallback((e) => {
        setFocused(false);
        validity.onBlur(e);
        onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
    }, [onBlur, validity]);
    const handleKeyDown = useCallback((e) => {
        if (e.code === undefined) {
            infoRef.current.picked = true;
        }
        onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
    }, [onKeyDown]);
    const handleChange = useCallback((e) => {
        if (!isControlled) {
            setInternalHasValue(Boolean(e.currentTarget.value));
        }
        validity.onChange(e);
        if (!suggestions) {
            onChange === null || onChange === void 0 ? void 0 : onChange(e);
            return;
        }
        const val = e.currentTarget.value;
        const matched = suggestions.find(s => {
            if (typeof s === "string") {
                return s === val;
            }
            return s.value === val;
        });
        if (matched) {
            onSuggestionMatch === null || onSuggestionMatch === void 0 ? void 0 : onSuggestionMatch(val, Boolean(infoRef.current.picked));
        }
        infoRef.current.picked = false;
        onChange === null || onChange === void 0 ? void 0 : onChange(e);
    }, [isControlled, suggestions, onChange, onSuggestionMatch, validity]);
    const prefixElem = prefix ? React.createElement(StyledPrefix, null, prefix) : null;
    const suffixElem = suffix ? React.createElement(StyledSuffix, null, suffix) : null;
    const extraProps = {};
    if (suggestions) {
        extraProps.list = suggestionsId;
    }
    const floating = Boolean(label) && (pinnedLabel || focused || hasValue);
    const showPlaceholder = !label || floating;
    const effectivePlaceholder = showPlaceholder ? placeholder : undefined;
    const labelElem = label
        ? (React.createElement(StyledLabel, { htmlFor: inputId, floating: floating, error: validity.finalError }, label))
        : null;
    return (React.createElement(StyledWrapper, { className: className, focused: focused, disabled: Boolean(props.disabled), readOnly: Boolean(props.readOnly), error: validity.finalError },
        prefixElem,
        React.createElement(StyledInputContainer, null,
            labelElem,
            React.createElement(StyledInput, { ref: ref, ...props, ...extraProps, id: inputId, placeholder: effectivePlaceholder, onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, onInvalid: validity.onInvalid, "data-error": validity.finalError }),
            React.createElement(Suggestions, { id: suggestionsId, suggestions: suggestions })),
        suffixElem));
};
const InputRef = React.forwardRef(InputInner);
InputRef.displayName = "Input";
InputRef.toString = () => StyledWrapper.toString();
const Input = InputRef;
const InputContainerSelector = StyledInputContainer.toString();
const InputLabelSelector = StyledLabel.toString();
const InputInputSelector = StyledInput.toString();
const InputPrefixSelector = StyledPrefix.toString();
const InputSuffixSelector = StyledSuffix.toString();
export { Input, InputContainerSelector, InputLabelSelector, InputInputSelector, InputPrefixSelector, InputSuffixSelector, };
//# sourceMappingURL=Input.js.map