/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module AccuDraw
 */
import "./AccuDrawInputField.scss";
import classnames from "classnames";
import * as React from "react";
import { Key } from "ts-key-enum";
import { Icon } from "@itwin/core-react";
import { useRefs } from "@itwin/core-react/internal";
import { Input } from "@itwin/itwinui-react";
import { FrameworkAccuDraw } from "./FrameworkAccuDraw.js";
import { UiFramework } from "../UiFramework.js";
import { SvgLock } from "@itwin/itwinui-icons-react";
import { useAllowLettersInAccuDrawInputFields } from "../preview/allow-letters-in-accudraw-input-fields/useAllowLettersInAccuDrawInputFields.js";
function isLetter(char) {
    return char.length === 1 && char.toLowerCase() !== char.toUpperCase();
}
const ForwardRefAccuDrawInput = React.forwardRef(function ForwardRefAccuDrawInputField(props, ref) {
    const { className, style, id, label, 
    // eslint-disable-next-line deprecation/deprecation
    iconSpec, icon, labelClassName, labelStyle, labelCentered, field, isLocked, onValueChanged, valueChangedDelay, onEnterPressed, onEscPressed, ...inputProps } = props;
    const [stringValue, setStringValue] = React.useState("");
    const timeoutId = React.useRef(0);
    const [needValueChanged, setNeedValueChanged] = React.useState(false);
    const [needSelection, setNeedSelection] = React.useState(false);
    const [isFocusField, setIsFocusField] = React.useState(false);
    const inputElementRef = React.useRef(null);
    const refs = useRefs(inputElementRef, ref); // combine ref needed for target with the forwardRef needed by the Parent when parent is a Type Editor.
    const allowLettersInAccuDrawInputFields = useAllowLettersInAccuDrawInputFields();
    React.useEffect(() => {
        const formattedValue = FrameworkAccuDraw.getFieldDisplayValue(field);
        setStringValue(formattedValue);
    }, [field]);
    const handleChange = React.useCallback((event) => {
        const value = event.currentTarget.value;
        if (value === undefined)
            return;
        if (stringValue !== value) {
            setStringValue(value);
            setNeedValueChanged(true);
        }
    }, [stringValue]);
    const unsetTimeout = () => {
        if (timeoutId) {
            window.clearTimeout(timeoutId.current);
            timeoutId.current = 0;
        }
    };
    React.useEffect(() => {
        // After setStringValue & re-render
        if (needValueChanged) {
            if (valueChangedDelay) {
                unsetTimeout();
                timeoutId.current = window.setTimeout(() => {
                    onValueChanged(stringValue);
                }, valueChangedDelay);
            }
            else {
                onValueChanged(stringValue);
            }
            setNeedValueChanged(false);
        }
    }, [onValueChanged, valueChangedDelay, stringValue, needValueChanged]);
    React.useEffect(() => {
        // On unmount
        return () => unsetTimeout();
    }, []);
    const handleKeyDown = React.useCallback((e) => {
        switch (e.key) {
            case Key.Escape.valueOf():
                onEscPressed && onEscPressed();
                return;
            case Key.Enter.valueOf():
                onEnterPressed && onEnterPressed();
                return;
        }
        if (isLetter(e.key)) {
            if (!allowLettersInAccuDrawInputFields) {
                e.preventDefault();
                UiFramework.keyboardShortcuts.processKey(e.key, e.altKey, e.ctrlKey, e.shiftKey);
            }
        }
    }, [onEscPressed, onEnterPressed, allowLettersInAccuDrawInputFields]);
    React.useEffect(() => {
        return FrameworkAccuDraw.onAccuDrawSetFieldValueToUiEvent.addListener((args) => {
            if (args.field === field && stringValue !== args.formattedValue) {
                setStringValue(args.formattedValue);
                if (isFocusField)
                    setNeedSelection(true);
            }
        });
    }, [field, isFocusField, stringValue]);
    React.useEffect(() => {
        if (needSelection) {
            if (inputElementRef.current)
                inputElementRef.current.select();
            setNeedSelection(false);
        }
    }, [needSelection]);
    React.useEffect(() => {
        return FrameworkAccuDraw.onAccuDrawSetFieldFocusEvent.addListener((args) => {
            setIsFocusField(args.field === field);
        });
    }, [field]);
    const inputClassNames = classnames("uifw-accudraw-input-field", className);
    const labelClassNames = classnames("uifw-accudraw-input-label", labelCentered && "uifw-label-centered", labelClassName);
    return (React.createElement(React.Fragment, null,
        React.createElement("label", { htmlFor: id, className: labelClassNames, style: labelStyle },
            label,
            icon ? icon : iconSpec && React.createElement(Icon, { iconSpec: iconSpec })),
        React.createElement(Input, { ...inputProps, ref: refs, id: id, value: stringValue, className: inputClassNames, style: style, autoComplete: "off", onChange: handleChange, onKeyDown: handleKeyDown, size: "small" }),
        React.createElement("span", { className: "uifw-accudraw-lock" }, isLocked && React.createElement(SvgLock, null))));
});
/** Input field for AccuDraw UI.
 * @public
 */
export const AccuDrawInputField = ForwardRefAccuDrawInput;
//# sourceMappingURL=AccuDrawInputField.js.map