import { _ as __rest } from './tslib.es6-es.js';
import React__default, { useState, useMemo, useCallback, useEffect, forwardRef, useId } from 'react';
import classnames from 'classnames';
import { u as useAtlantisFormFieldName } from './useAtlantisFormFieldName-es.js';
import { c as FormFieldWrapper, g as formFieldStyles } from './FormFieldWrapper-es.js';
import './Button-es.js';
import '@jobber/design';
import { F as FormFieldPostFix } from './FormFieldPostFix-es.js';
import { f as filterDataAttributes } from './filterDataAttributes-es.js';

var styles = {"mask":"_78-Lxj78xPg-","hiddenValue":"GoiXVXaU1Qs-","emptyValue":"oOrjwubmsVA-","spinning":"T3VvmDmzs-4-"};

function MaskElement({ isMasking, formattedValue, placeholderMask, }) {
    if (!isMasking) {
        return null;
    }
    return (React__default.createElement("div", { className: styles.mask, "aria-hidden": "true" },
        React__default.createElement("span", { className: styles.hiddenValue }, formattedValue),
        React__default.createElement("span", null, placeholderMask)));
}

function useInputMask({ value = "", pattern, delimiter = "*", strict = true, onChange, }) {
    const [isMasking, setIsMasking] = useState(!value);
    const patternInfo = useMemo(() => {
        const patternChars = pattern.split("");
        const specialChars = patternChars.filter(char => char !== delimiter);
        const maxCleanChars = patternChars.filter(char => char === delimiter).length;
        return {
            patternChars,
            specialChars,
            maxCleanChars,
        };
    }, [pattern, delimiter]);
    const inputValue = useMemo(() => {
        return value
            .split("")
            .filter(char => !patternInfo.specialChars.includes(char))
            .join("");
    }, [value, patternInfo.specialChars]);
    const formatValue = useCallback((unformattedValue) => {
        const { patternChars, specialChars, maxCleanChars } = patternInfo;
        const cleanValueChars = unformattedValue
            .split("")
            .filter(char => !specialChars.includes(char) && !Number.isNaN(Number(char)));
        const isOverCharLimit = cleanValueChars.length > maxCleanChars;
        if (!strict && isOverCharLimit) {
            return cleanValueChars.join("");
        }
        else {
            const formattedValue = patternChars.reduce(getMaskedValue([...cleanValueChars], specialChars), "");
            return formattedValue;
        }
    }, [patternInfo, strict]);
    const maskedOnChange = useCallback((newValue, event) => {
        const formatted = formatValue(newValue);
        onChange === null || onChange === void 0 ? void 0 : onChange(formatted, event);
    }, [formatValue, onChange]);
    const formattedValue = useMemo(() => formatValue(value), [formatValue, value]);
    useEffect(() => {
        const shouldMask = strict || inputValue.length < patternInfo.maxCleanChars;
        setIsMasking(shouldMask);
    }, [inputValue, patternInfo.maxCleanChars, strict]);
    const placeholderMask = useMemo(() => pattern
        .replace(new RegExp(`\\${delimiter}`, "g"), "_")
        .slice(value.length), [pattern, delimiter, value]);
    return {
        formattedValue,
        placeholderMask,
        isMasking,
        maskedOnChange,
        inputValue,
    };
}
function getMaskedValue(cleanVal, specialChars) {
    return (result, nextCharacter) => {
        if (!cleanVal.length)
            return result;
        if (specialChars.includes(nextCharacter))
            return result + nextCharacter;
        const nextValue = cleanVal.shift();
        return result + (nextValue !== undefined ? nextValue : "");
    };
}

const DEFAULT_PATTERN = "(***) ***-****";

/**
 * Combines the actions on the InputPhoneNumber such as onChange, onEnter, onFocus, onBlur, and onClear to forward information to the consumers of the InputPhoneNumber.
 * Do not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
 */
function useInputPhoneActions({ onChange, inputRef, onFocus, onBlur, onKeyDown, onEnter, onClick, onMouseDown, onMouseUp, onPointerDown, onPointerUp, }) {
    function handleClear() {
        var _a;
        onChange && onChange("");
        (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
    }
    function handleChange(event) {
        const newValue = event.currentTarget.value;
        onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
    }
    function handleFocus(event) {
        onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
    }
    function handleKeyDown(event) {
        onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
        if (!onEnter)
            return;
        if (event.key !== "Enter")
            return;
        if (event.shiftKey || event.ctrlKey)
            return;
        event.preventDefault();
        onEnter === null || onEnter === void 0 ? void 0 : onEnter(event);
    }
    function handleBlur(event) {
        onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
    }
    function handleClick(event) {
        onClick === null || onClick === void 0 ? void 0 : onClick(event);
    }
    function handleMouseDown(event) {
        onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
    }
    function handleMouseUp(event) {
        onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(event);
    }
    function handlePointerDown(event) {
        onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
    }
    function handlePointerUp(event) {
        onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp(event);
    }
    return {
        handleClear,
        handleChange,
        handleFocus,
        handleBlur,
        handleKeyDown,
        handleClick,
        handleMouseDown,
        handleMouseUp,
        handlePointerDown,
        handlePointerUp,
    };
}

const InputPhoneNumber = forwardRef(function InputPhoneNumberInternal(_a, ref) {
    var _b, _c, _d, _e;
    var { pattern = DEFAULT_PATTERN } = _a, props = __rest(_a, ["pattern"]);
    const inputPhoneNumberRef = (_b = ref) !== null && _b !== void 0 ? _b : React__default.useRef(null);
    const wrapperRef = React__default.useRef(null);
    const generatedId = useId();
    const id = props.id || generatedId;
    const { name } = useAtlantisFormFieldName({
        nameProp: props.name,
        id: id,
    });
    const { formattedValue, isMasking, placeholderMask, inputValue, maskedOnChange, } = useInputMask({
        value: props.value,
        pattern,
        strict: false,
        onChange: props.onChange,
    });
    const { handleChange, handleBlur, handleFocus, handleClear, handleKeyDown, handleClick, handleMouseDown, handleMouseUp, handlePointerDown, handlePointerUp, } = useInputPhoneActions({
        onChange: maskedOnChange,
        onBlur: props.onBlur,
        onFocus: props.onFocus,
        onEnter: props.onEnter,
        onKeyDown: props.onKeyDown,
        onClick: props.onClick,
        onMouseDown: props.onMouseDown,
        onMouseUp: props.onMouseUp,
        onPointerDown: props.onPointerDown,
        onPointerUp: props.onPointerUp,
        inputRef: inputPhoneNumberRef,
    });
    const descriptionIdentifier = `descriptionUUID--${id}`, descriptionVisible = props.description && !props.inline;
    const isInvalid = Boolean(props.error || props.invalid);
    const dataAttrs = filterDataAttributes(props);
    return (React__default.createElement(FormFieldWrapper, { disabled: props.disabled, size: props.size, inline: props.inline, wrapperRef: wrapperRef, error: (_c = props.error) !== null && _c !== void 0 ? _c : "", invalid: Boolean(props.error || props.invalid), identifier: id, descriptionIdentifier: descriptionIdentifier, description: props.description, clearable: (_d = props.clearable) !== null && _d !== void 0 ? _d : "never", onClear: handleClear, type: "tel", placeholder: props.placeholder, value: formattedValue, prefix: props.prefix, suffix: props.suffix, readonly: props.readOnly, loading: props.loading },
        React__default.createElement("input", Object.assign({ id: id, name: name, type: "tel", ref: inputPhoneNumberRef, className: classnames(formFieldStyles.input, {
                [styles.emptyValue]: inputValue.length === 0 && pattern[0] === "(",
            }), value: formattedValue, disabled: props.disabled, readOnly: props.readOnly, autoFocus: props.autoFocus, autoComplete: props.autoComplete, inputMode: props.inputMode, tabIndex: props.tabIndex, required: props.required, role: props.role, "aria-label": props["aria-label"], "aria-describedby": descriptionVisible ? descriptionIdentifier : props["aria-describedby"], "aria-invalid": isInvalid ? true : undefined, "aria-controls": props["aria-controls"], "aria-expanded": props["aria-expanded"], "aria-activedescendant": props["aria-activedescendant"], "aria-autocomplete": props["aria-autocomplete"], "aria-required": props["aria-required"], onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, onClick: handleClick, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp }, dataAttrs)),
        React__default.createElement(MaskElement, { isMasking: isMasking, formattedValue: formattedValue, placeholderMask: placeholderMask }),
        React__default.createElement(FormFieldPostFix, { variation: "spinner", visible: (_e = props.loading) !== null && _e !== void 0 ? _e : false })));
});

export { InputPhoneNumber as I };
