import {useEffect, useRef, useState, useId} from "@wordpress/element";

export default function Input({
                                  value,
                                  setValue,
                                  className,
                                  inputClassName,
                                  type,
                                  disabled,
                                  isReverse,
                                  placeholder,
                                  staticPlaceholder,
                                  autofocus,
                                  validate,
                                  errorMessage,
                                  children,
                                  actions,
                                  extraActions,
                                  onKeyDown,
                                  sanitizeValue,
                                  onBlur
                              }) {
    const inputRef = useRef(null);
    const [isFocused, setIsFocused] = useState(false);
    const isValueEmpty = value === undefined || value === null || value === '';
    const shouldShowStaticPlaceholder = !placeholder || (!!staticPlaceholder && isFocused && isValueEmpty);

    const fieldId = useId();

    useEffect(() => {
        if (autofocus) {
            inputRef.current?.focus();
        }
    }, []);

    /**
     * Check value before apply
     *
     * @param {string} newValue New value
     */
    const updateValue = (newValue) => {
        if (disabled) {
            return;
        }
        // Sanitize value if sanitize function provided (before type checks and validation)
        if (typeof sanitizeValue === 'function') {
            newValue = sanitizeValue(newValue);
        }
        // Integer
        if (type === 'integer') {
            const matches = newValue.match(/^\d+$/);
            if (matches?.length) {
                newValue = matches[0];
            } else {
                newValue = newValue.slice(0, -1);
            }
        } else if (type === 'float') {
            const matches = newValue.match(/^\d+(\.\d*)?$/);
            if (matches?.length) {
                newValue = matches[0];
            } else {
                newValue = newValue.slice(0, -1);
            }
        }
        setValue(newValue);
        // Validate
        if (value !== newValue && typeof validate === 'function') {
            validate(newValue);
        }
    }

    return <div
        className={`lbaic-settings-input-holder${className ? ' ' + className : ''}${actions?.length > 0 ? ' lbaic-settings-input-has-actions' : ''}${children ? ' lbaic-settings-input-has-children' : ''}${disabled ? ' lbaic-settings-input-disabled' : ''}${isReverse ? ' lbaic-settings-input-reverse' : ''}${errorMessage ? ' lbaic-settings-input-error' : ''}`}>
        {extraActions?.length > 0 && (
            <div className='lbaic-settings-input-extra-actions'>
                {extraActions.map((item, i) => {
                    const CurrentAction = item.component;
                    // Use disabled from extraAction props if provided, otherwise use Input's disabled
                    const actionDisabled = item.props?.disabled !== undefined ? item.props.disabled : disabled;
                    return <CurrentAction key={i} {...item.props} inputRef={inputRef} disabled={actionDisabled}/>;
                })}
            </div>
        )}
        {Boolean(placeholder) && (
            <div className='lbaic-settings-input-placeholder'>
                <label htmlFor={fieldId} className='lbaic-settings-input-placeholder-in'>{placeholder}</label>
            </div>
        )}
        <div
            className={`lbaic-settings-input-holder-in lbaic-settings-input-h-42${actions?.length ? ' has-actions-' + actions.length : ''}`}>
            {children ? <div className='lbaic-settings-input-children'>{children}</div> : null}
            <input
                ref={inputRef}
                id={fieldId}
                className={`lbaic-settings-input${inputClassName ? ' ' + inputClassName : ''}`}
                type='text'
                value={value}
                placeholder={staticPlaceholder}
                onChange={(e) => updateValue(e.target.value)}
                onKeyDown={onKeyDown}
                onFocus={() => setIsFocused(true)}
                onBlur={(e) => {
                    setIsFocused(false);
                    if (typeof onBlur === 'function') {
                        onBlur(e);
                    }
                }}
                autoComplete="off"
            />
            {actions?.length > 0 &&
                <div className='lbaic-settings-input-actions'>
                    {actions.map((item, i) => {
                        const CurrentAction = item.component;
                        // Use disabled from action props if provided, otherwise use Input's disabled
                        const actionDisabled = item.props?.disabled !== undefined ? item.props.disabled : disabled;
                        return <CurrentAction key={i} {...item.props} inputRef={inputRef} disabled={actionDisabled}/>;
                    })}
                </div>}
        </div>
        {errorMessage &&
            <div className='lbaic-settings-input-error-message'>
                <p className='lbaic-settings-input-error-message-in'>{errorMessage}</p>
            </div>}
    </div>
}