import React, { useState, useEffect, useLayoutEffect, useRef, Fragment } from 'react';
import Styled from 'styled-components/native';
import Theme from '~/Themes';
import { Util } from '~/Utils/utils';
import { usePrevious } from '../Hooks';
import { Text, TextInput, Platform } from 'react-native';
import { isTrue } from './Common';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';

const InputContainer = Styled.View`
    overflow:hidden;
    width: 100%;
    border: 1px solid #b9bac4;
    border-radius: 5px;
    padding-left: 18px;
    padding-right: 20px;
    flex-direction: row;
    align-items: center;
    min-height: 40px;
`;
const StyledInput = Styled.TextInput`
    color: #43425d;
    flex:1;
    border-width: 0px;
    padding: 0;
    font-size: 16;
    text-align-vertical: center;
`;
const StyledText = Styled.Text`
    color: #43425d;
    flex:1;
    min-height: 38px;
    border-width: 0px;
    padding: 0;
    font-size: 16;
    text-align-vertical: center;
`;
const LeftText = Styled.Text`
    color: #43425d;
    text-align:center;
    text-align-vertical:center;
    font-size: 12;
    width:20px;
    height:18px;
`;

export const InputFilters = {
    number: (text) => {
        return (text+'').replace(/[^0-9]/g, '');
    },
    decimal: (text) => {
        let result = (text+'').replace(/[^0-9\.]/g, '').replace(/[\.]{2,}/g, '.');
        let dotCount = (result.match(/\./g) || []).length;
        if(dotCount > 1) {
            for(var i=1; i<dotCount; i++) {
                let dotIndex = result.lastIndexOf('.');
                result = result.substr(0, dotIndex) + (result.length > dotIndex+1 ? result.substr(dotIndex+1) : '');
            }
        }
        if(result.length > 0 && result[0] == '.') {
            result = '0' + result;
        }
        return result;
    },
    maxNumber: (text, number) => {
        let num = isNaN(number) ? 0 : number;
        let numberValue = parseInt((text+'').replace(/[^0-9]/g, ''));
        if(numberValue > num) numberValue = num;
        if(isNaN(numberValue)) numberValue = '0';
        return numberValue + '';
    },
    numberRange: (text, minValue, maxValue) => {
        let numberValue = parseInt((text+'').replace(/[^0-9]/g, ''));
        if(numberValue < minValue) numberValue = minValue;
        if(numberValue > maxValue) numberValue = maxValue;
        if(isNaN(numberValue)) numberValue = '0';
        return numberValue + '';
    },
}

export default Input = ({
    style = {}, 
    inputStyle = {},
    placeholderTextColor="#9aa3ac", 
    placeholder="", 
    editable=true, 
    defaultValue='', 
    value,
    autosize=true,
    multiline=false,
    leftSvg="",
    leftSvgSize=18,
    leftText="",
    leftTextStyle={},
    onChangeText=(text)=>{},
    onPress=null,
    filter=null,    /* defaultValue 를 사용했을경우만 filter 가 적용된다. value 사용시 filter 적용 안됨. */
    control=null,
    ...rest
}) => {
    const inputRef = useRef();
    const inputCurrentText = useRef('');

    const toString = (value) => {
        if(typeof value === 'undefined') return value;
        if(value === null) return value;
        return value + '';
    }

    const isValidOnPress = () => {
        if(onPress && typeof onPress === 'function') return true;
        return false;
    }

    const onPressEvent = (text) => {
        if(onPress && typeof onPress === 'function') {
            onPress(text);
        }
    }

    const isValidFilter = () => {
        if(filter && typeof filter === 'function') return true;
        return false;
    }

    const textFilter = (text) => {
        if(isValidFilter()) {
            return filter(text);
        }
        return text;
    }

    const onChangeTextInterceptor = (text) => {
        if(isValidFilter()) {
            const value = textFilter(text);
            setInnerValue(value);
            onChangeText(value);
            inputCurrentText.current = value;
        } else {
            onChangeText(text);
            inputCurrentText.current = text;
        }
    }

    const [innerEditable, setInnerEditable] = useState(isTrue(editable));
    const [innerValue, setInnerValue] = useState(toString(defaultValue));
    const borderStyle = isTrue(editable) ? { borderColor: Theme.COLORS.EDITABLE_BORDER } : { borderColor: Theme.COLORS.READONLY_BORDER };
    const backgroundStyle = isTrue(editable) ? { backgroundColor: Theme.COLORS.EDITABLE_BACKGROUND } : { backgroundColor: Theme.COLORS.READONLY_BACKGROUND };

    const LeftSvg = Util.svg(leftSvg);
    const LeftSvgSize = (typeof leftSvgSize === 'number' ? {width:leftSvgSize, height:leftSvgSize} : leftSvgSize);
    const containerPadding = (!!LeftSvg || !!leftText ? {paddingLeft:10} : {});
    const inputPadding = (!!LeftSvg || !!leftText ? {paddingLeft:0} : {});

    const prevEditable = usePrevious(editable);
    const prevDefaultValue = usePrevious(defaultValue);
    useEffect(() => {
        if(typeof prevEditable !== 'undefined' && prevEditable !== editable) {
            onChangeTextInterceptor(defaultValue);
            if(isTrue(prevEditable) && isTrue(editable)) {
                setInnerEditable(false);
                setTimeout(() => {
                    setInnerEditable(true);
                }, 0);
                /*
                setInnerEditable((prev) => {
                    setInnerEditable(true);
                    return prev;
                });
                */

            } else {
                setInnerEditable(isTrue(editable));
            }
        }
    }, [editable]);

    useEffect(() => {
        if(typeof prevDefaultValue !== 'undefined' && prevDefaultValue == '' && defaultValue !== '') {
            setInnerValue(toString(defaultValue));
            if(!value && isValidFilter()) {
                inputCurrentText.current = defaultValue;
            }
        }
    }, [defaultValue]);

    useEffect(() => {
        try {
            if(inputRef && inputRef.current && inputRef.current.setNativeProps) {
                //inputRef.current.setNativeProps({ selection:{start:0,end:0 }});
            }
        } catch(error) {
            console.error(error);
        }
    }, [inputRef.current]);

    return (
        innerEditable ? (
            <InputContainer style={[borderStyle, backgroundStyle, style, containerPadding]}>
                {LeftSvg && <LeftSvg width={LeftSvgSize.width} height={LeftSvgSize.height} />}
                {!LeftSvg && !!leftText && <LeftText style={[leftTextStyle]}>{leftText}</LeftText>}
                <StyledInput style={[(multiline?{paddingBottom:3}:{}), inputStyle, inputPadding]} 
                    placeholderTextColor={placeholderTextColor} 
                    placeholder={isTrue(editable) ? placeholder : ''} 
                    editable={isTrue(editable)} 
                    defaultValue={toString(defaultValue)} 
                    value={value ? toString(value) : (isValidFilter() ? innerValue : null)}
                    multiline={multiline}
                    onChangeText={onChangeTextInterceptor}
                    onFocus={() => {
                        if(Platform.OS == 'android') {
                            try {
                                if(inputRef && inputRef.current && inputRef.current.setNativeProps) {
                                    /*
                                    inputRef.current.setNativeProps({ 
                                        selection:{start:inputCurrentText.current.length,end:inputCurrentText.current.length }, 
                                        text: inputCurrentText.current
                                    });
                                    */
                                }
                            } catch(error) {
                                console.error(error);
                            }
                        }
                    }}
                    onBlur={() => {
                        if(Platform.OS == 'android') {
                            try {
                                if(inputRef && inputRef.current && inputRef.current.setNativeProps) {
                                    /*
                                    inputRef.current.setNativeProps({ 
                                        selection:{ start:0, end:0 }, 
                                        text: inputCurrentText.current
                                    });
                                    */
                                }
                            } catch(error) {
                                console.error(error);
                            }
                        }
                    }}
                    ref={inputRef}
                    {...rest}/>
            </InputContainer>
        ) : (
            <InputContainer style={[borderStyle, backgroundStyle, style, containerPadding]}>
                {LeftSvg && <LeftSvg width={LeftSvgSize.width} height={LeftSvgSize.height} />}
                {!LeftSvg && !!leftText && <LeftText style={[leftTextStyle]}>{leftText}</LeftText>}
                {isValidOnPress() ? (
                    <TouchableWithoutFeedback style={{width:'100%'}} onPress={() => { 
                        onPressEvent(value ? toString(value) : (isValidFilter() ? innerValue : toString(defaultValue))); 
                    }}>
                        <StyledText style={[autosize ? {height:"auto", paddingTop:8, paddingBottom:8} : {}, inputStyle]}>
                            {value ? toString(value) : (isValidFilter() ? innerValue : toString(defaultValue))}
                        </StyledText>
                    </TouchableWithoutFeedback>
                ) : (
                    <StyledText style={[autosize ? {height:"auto", paddingTop:8, paddingBottom:8} : {}, inputStyle]}>
                        {value ? toString(value) : (isValidFilter() ? innerValue : toString(defaultValue))}
                    </StyledText>
                )}
            </InputContainer>
        )
    )
}