"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importStar(require("react"));
const prop_types_1 = tslib_1.__importDefault(require("prop-types"));
const react_native_1 = require("react-native");
const Animatable = tslib_1.__importStar(require("react-native-animatable"));
const styles = react_native_1.StyleSheet.create({
    containerDefault: {},
    cellDefault: {
        borderColor: 'gray',
        borderWidth: 1,
    },
    cellFocusedDefault: {
        borderColor: 'black',
        borderWidth: 2,
    },
    textStyleDefault: {
        color: 'gray',
        fontSize: 24,
    },
    textStyleFocusedDefault: {
        color: 'black',
    },
});
class SmoothPinCodeInput extends react_1.Component {
    state = {
        maskDelay: false,
        focused: false,
    };
    ref = react_1.default.createRef();
    inputRef = react_1.default.createRef();
    animate = ({ animation = 'shake', duration = 650 }) => {
        if (!this.props.animated) {
            return new Promise((resolve, reject) => reject(new Error('Animations are disabled')));
        }
        return this.ref.current[animation](duration);
    };
    shake = () => this.animate({ animation: 'shake' });
    focus = () => {
        return this.inputRef.current.focus();
    };
    blur = () => {
        return this.inputRef.current.blur();
    };
    clear = () => {
        return this.inputRef.current.clear();
    };
    _inputCode = (code) => {
        const { password, codeLength = 4, onTextChange, onFulfill } = this.props;
        if (this.props.restrictToNumbers) {
            code = (code.match(/[0-9]/g) || []).join('');
        }
        if (onTextChange) {
            onTextChange(code);
        }
        if (code.length === codeLength && onFulfill) {
            onFulfill(code);
        }
        // handle password mask
        const maskDelay = password && code.length > this.props.value.length; // only when input new char
        this.setState({ maskDelay });
        if (maskDelay) {
            // mask password after delay
            clearTimeout(this.maskTimeout);
            this.maskTimeout = setTimeout(() => {
                this.setState({ maskDelay: false });
            }, this.props.maskDelay);
        }
    };
    _keyPress = (event) => {
        if (event.nativeEvent.key === 'Backspace') {
            const { value, onBackspace } = this.props;
            if (value === '' && onBackspace) {
                onBackspace();
            }
        }
    };
    _onFocused = () => {
        this.setState({ focused: true });
        if (typeof this.props.onFocus === 'function') {
            this.props.onFocus();
        }
    };
    _onBlurred = () => {
        this.setState({ focused: false });
        if (typeof this.props.onBlur === 'function') {
            this.props.onBlur();
        }
    };
    useIndexedAccessibilityLabel = (idx) => {
        if (typeof this.props.useIndexedAccessibilityLabel === 'string')
            return `${this.props.useIndexedAccessibilityLabel} ${idx}`;
        return `Insira o PIN ${idx}`;
    };
    useIndexedTestID = (idx) => {
        if (typeof this.props.useIndexedTestID === 'string')
            return `${this.props.useIndexedTestID} ${idx}`;
        return `Insira o PIN ${idx}`;
    };
    componentWillUnmount() {
        clearTimeout(this.maskTimeout);
    }
    // eslint-disable-next-line sonarjs/cognitive-complexity
    render() {
        const { value, codeLength, cellSize, cellSpacing, placeholder, password, mask, autoFocus, containerStyle, cellStyle, cellStyleFocused, cellStyleFilled, textStyle, textStyleFocused, keyboardType, animationFocused, animated, testID, editable, inputProps, disableFullscreenUI, } = this.props;
        const { maskDelay, focused } = this.state;
        return (<Animatable.View ref={this.ref} style={[
                {
                    alignItems: 'stretch',
                    flexDirection: 'row',
                    justifyContent: 'center',
                    position: 'relative',
                    width: cellSize * codeLength + cellSpacing * (codeLength - 1),
                    height: cellSize,
                },
                containerStyle,
            ]}>
        <react_native_1.View style={{
                position: 'absolute',
                margin: 0,
                height: '100%',
                flexDirection: react_native_1.I18nManager.isRTL ? 'row-reverse' : 'row',
                alignItems: 'center',
            }}>
          {Array.apply(null, Array(codeLength)).map((_, idx) => {
                const cellFocused = focused && idx === value.length;
                const filled = idx < value.length;
                const last = idx === value.length - 1;
                const showMask = filled && password && (!maskDelay || !last);
                const isPlaceholderText = typeof placeholder === 'string';
                const isMaskText = typeof mask === 'string';
                const pinCodeChar = value.charAt(idx);
                let cellText = null;
                if (filled || placeholder !== null) {
                    if (showMask && isMaskText) {
                        cellText = mask;
                    }
                    else if (!filled && isPlaceholderText) {
                        cellText = placeholder;
                    }
                    else if (pinCodeChar) {
                        cellText = pinCodeChar;
                    }
                }
                const placeholderComponent = !isPlaceholderText
                    ? placeholder
                    : null;
                const maskComponent = showMask && !isMaskText ? mask : null;
                const isCellText = typeof cellText === 'string';
                return (<Animatable.View key={idx} style={[
                        {
                            width: cellSize,
                            height: cellSize,
                            marginLeft: cellSpacing / 2,
                            marginRight: cellSpacing / 2,
                            flexDirection: 'row',
                            alignItems: 'center',
                            justifyContent: 'center',
                        },
                        cellStyle,
                        cellFocused ? cellStyleFocused : {},
                        filled ? cellStyleFilled : {},
                    ]} animation={idx === value.length && focused && animated
                        ? animationFocused
                        : null} iterationCount="infinite" duration={500} accessibilityLabel={this.useIndexedAccessibilityLabel(idx)} testID={this.useIndexedTestID(idx)}>
                {isCellText && !maskComponent && (<react_native_1.Text style={[textStyle, cellFocused ? textStyleFocused : {}]}>
                    {cellText}
                  </react_native_1.Text>)}
                {!isCellText && !maskComponent && placeholderComponent}
                {isCellText && maskComponent}
              </Animatable.View>);
            })}
        </react_native_1.View>
        <react_native_1.TextInput disableFullscreenUI={disableFullscreenUI} value={value} ref={this.inputRef} onChangeText={this._inputCode} onKeyPress={this._keyPress} onFocus={() => this._onFocused()} onBlur={() => this._onBlurred()} spellCheck={false} autoFocus={autoFocus} keyboardType={keyboardType} numberOfLines={1} caretHidden maxLength={codeLength} selection={{
                start: value.length,
                end: value.length,
            }} style={{
                flex: 1,
                opacity: 0,
                textAlign: 'center',
            }} testID={testID || undefined} editable={editable} {...inputProps}/>
      </Animatable.View>);
    }
    static defaultProps = {
        value: '',
        codeLength: 4,
        cellSize: 48,
        cellSpacing: 4,
        placeholder: '',
        password: false,
        mask: '*',
        maskDelay: 200,
        keyboardType: 'numeric',
        autoFocus: false,
        restrictToNumbers: false,
        containerStyle: styles.containerDefault,
        cellStyle: styles.cellDefault,
        cellStyleFocused: styles.cellFocusedDefault,
        textStyle: styles.textStyleDefault,
        textStyleFocused: styles.textStyleFocusedDefault,
        animationFocused: 'pulse',
        animated: true,
        editable: true,
        inputProps: {},
        disableFullscreenUI: true,
        useIndexedAccessibilityLabel: undefined,
        useIndexedTestID: undefined,
    };
}
SmoothPinCodeInput.propTypes = {
    value: prop_types_1.default.string,
    codeLength: prop_types_1.default.number,
    cellSize: prop_types_1.default.number,
    cellSpacing: prop_types_1.default.number,
    placeholder: prop_types_1.default.oneOfType([prop_types_1.default.string, prop_types_1.default.element]),
    mask: prop_types_1.default.oneOfType([prop_types_1.default.string, prop_types_1.default.element]),
    maskDelay: prop_types_1.default.number,
    password: prop_types_1.default.bool,
    autoFocus: prop_types_1.default.bool,
    restrictToNumbers: prop_types_1.default.bool,
    containerStyle: prop_types_1.default.style,
    cellStyle: prop_types_1.default.style,
    cellStyleFocused: prop_types_1.default.style,
    cellStyleFilled: prop_types_1.default.style,
    textStyle: prop_types_1.default.style,
    textStyleFocused: prop_types_1.default.style,
    animated: prop_types_1.default.bool,
    animationFocused: prop_types_1.default.oneOfType([prop_types_1.default.string, prop_types_1.default.object]),
    onFulfill: prop_types_1.default.func,
    onChangeText: prop_types_1.default.func,
    onBackspace: prop_types_1.default.func,
    onTextChange: prop_types_1.default.func,
    testID: prop_types_1.default.any,
    onFocus: prop_types_1.default.func,
    onBlur: prop_types_1.default.func,
    keyboardType: prop_types_1.default.string,
    editable: prop_types_1.default.bool,
    inputProps: prop_types_1.default.exact(react_native_1.TextInput.propTypes),
    useIndexedAccessibilityLabel: prop_types_1.default.string,
    useIndexedTestID: prop_types_1.default.string,
};
exports.default = SmoothPinCodeInput;
//# sourceMappingURL=SmoothPinCodeInput.js.map