import React, { useState, Fragment, useCallback, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Styled from 'styled-components/native';
import Icon from '~/Components/UIControls/Icon';
import RNDateTimePicker from '@react-native-community/datetimepicker';
import { Platform, TouchableWithoutFeedback, Keyboard, TouchableOpacity, View } from 'react-native';
import { showAction } from '~/GlobalReducers/datetimepicker';
import Button from './Button';
import { Util } from '~/Utils/utils';
import DownIcon from '~/Assets/Svgs/Selectbox/down.svg';
import Theme from '~/Themes';
import { usePrevious } from '../Hooks';
import moment from 'moment';
import IconButton from './IconButton';

const ContainerStyle = `
    flex-direction: row;
    width: 100%;
    height: 40px;
    border: 1px solid #b9bac4;
    border-radius: 5px;
    align-items: center;
    padding-left: 19px;
    padding-right: 19px;
`;
const PickerLabel = Styled.Text`
    font-size: 15px;
    padding: 2px;
    padding-left: 0px;
    align-items: center;
    color: #43425d;
    flex: 1;
`;
const PickerDefaultLabel = Styled(PickerLabel)`
    color: #9aa3ac;
`;

const defaultOnChange = (newDate) => {};
const toDate = (date, nullValue='') => {
    const mv = moment(date);
    if(mv.isValid()) return mv.toDate();
    else return nullValue;
}
export const DateTimePicker = ({style={}, mode="date", labelStyle={}, onChange=defaultOnChange, date=null, minimumDate=null, maximumDate=null, placeholder='', editable=true, useClear=false, hideDownIcon=false}) => {
    const toDateString = (d, nullValue = '') => {
        const mv = moment(d);
        if(mode == "date") {
            if(mv.isValid()) return mv.format('YYYY-MM-DD');
            else return nullValue;
        } else {
            if(mv.isValid()) return mv.format('YYYY-MM-DD HH:mm:ss');
            else return nullValue;
        }
    }
    const [currentDate, setCurrentDate] = useState(moment(date).toDate());
    const payload = useSelector(({GlobalDateTimePicker}) => GlobalDateTimePicker.picker);
    const dispatch = useDispatch();
    const show = useCallback((payload) => dispatch(showAction(payload)), []);
    const changeHandler = (newDate) => {
        const mv = moment(newDate);
        if(mv.isValid()) {
            if(mode == "date") {
                //console.log('change handler - newdate(date) : ', newDate);
                setCurrentDate(new Date(newDate));
                onChange(moment(newDate).format('YYYY-MM-DD'));
            } else {
                //console.log('change handler - newdate(datetime) : ', newDate);
                setCurrentDate(moment(newDate).toDate());
                onChange(moment(newDate).format('YYYY-MM-DD HH:mm:ss'));
            }
        } else {
            setCurrentDate(null);
            onChange('');
        }
    }

    const clearValue = () => {
        changeHandler('');
    }

    const Container = editable ? Styled(TouchableOpacity)`${ContainerStyle}` : Styled(View)`${ContainerStyle}`;
    const Label = currentDate ? Styled(PickerLabel)`` : Styled(PickerDefaultLabel)``;
    const showParameter = {
        show: true, 
        mode: mode,
        minimumDate: minimumDate,
        maximumDate: maximumDate,
        date: currentDate, 
        onChange: changeHandler
    };
    const borderStyle = editable ? { borderColor: Theme.COLORS.EDITABLE_BORDER } : { borderColor: Theme.COLORS.READONLY_BORDER };
    const backgroundStyle = editable ? { backgroundColor: Theme.COLORS.EDITABLE_BACKGROUND } : { backgroundColor: Theme.COLORS.READONLY_BACKGROUND };

    const prevEditable = usePrevious(editable);

    useEffect(() => {
        setCurrentDate(date);
        if(typeof prevEditable !== 'undefined' && editable != prevEditable) {
            const mv = moment(date);
            if(mv.isValid()) {
                if(mode == "date") {
                    onChange(mv.format('YYYY-MM-DD'));
                } else {
                    onChange(mv.format('YYYY-MM-DD HH:mm:ss'));
                }
            } else {
                onChange('');
            }
        }
    }, [date, editable]);

    return (
        <Fragment>
            <Container style={[backgroundStyle, style, borderStyle]} onPress={() => { editable && show(showParameter); }}>
                <Label style={[labelStyle]} numberOfLines={1} ellipsizeMode="tail">{toDateString(currentDate, editable ? placeholder : '')}</Label>
                {editable && !hideDownIcon && <DownIcon width={18} height={9} color="#b9bac4" />}
                {editable && useClear && <IconButton iconFamily="AntDesign" iconName="closecircle" color="#b9bac4" size={26} style={{marginLeft:10}} onPress={clearValue} />}
            </Container>
        </Fragment>
    );
}

const ProviderContainerAndroid = Styled.TouchableOpacity`
    background-color: #000;
    opacity: 0.7;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
`;
const ProviderContainerIOS = Styled.View`
    position: absolute;
    left: 0; right: 0; top: 0; bottom: 0;
    flex-direction: column;
`;
const ProviderTopContainerIOS = Styled.TouchableOpacity`
    background-color: #000;
    opacity: 0.0;
    flex: 1;
`;
const ProviderBottomContainerIOS = Styled.View`
    flex-direction: column;
    background-color: #fff;
    border-color: #aaaaaa;
    border-top-width: 1px;
    left: 0;
    right: 0;
    bottom: 0;
`;
const PickerHeader = Styled.View`
    flex-direction: row;
    height: 50px;
    width: 100%;
    border-color: #dedede;
    border-bottom-width: 1px;
    align-items: center;
    justify-content: flex-end;
`;
const PickButton = Styled(Button)`
    width: 80px;
`;
const CancelButton = Styled(Button)`
    width: 80px;
`;

const STATUS_NOSELECTED = 0;    // 선택안됨
const STATUS_DATESELECTED = 1;  // 날짜선택됨
const STATUS_TIMESELECTED = 2;  // 시간까지선택됨
export const DateTimePickerProvider = () => {
    const payload = useSelector(({GlobalDateTimePicker}) => GlobalDateTimePicker.picker);
    const dispatch = useDispatch();
    const show = useCallback((payload) => dispatch(showAction(payload)), []);
    const isDateTime = payload.mode == "datetime";
    const [selected, setSelected] = useState({status:STATUS_NOSELECTED, date: '', time: '' });

    if(payload.show) {
        Keyboard.dismiss();
    }

    useEffect(() => {
        setSelected({status:STATUS_NOSELECTED,  date:'', time: '' });
    }, [payload]);

    return (
        <Fragment>
        {Platform.OS === "android" && (
            payload.show && 
            <ProviderContainerAndroid onPress={() => { show({show:false}) }}>
                {isDateTime ? (
                    <>
                    {(() => {
                        if(selected.status === STATUS_NOSELECTED) {
                            return (
                                <RNDateTimePicker value={toDate(payload.date, new Date())} 
                                mode={"date"} is24Hour={true} display="default" locale="ko-KR"
                                minimumDate={toDate(payload.minimumDate, null)} maximumDate={toDate(payload.maximumDate, null)}
                                onChange={(e, newDate) => { 
                                    if(newDate) {
                                        //console.log('date selected - ', newDate);
                                        setSelected({...selected, status:STATUS_DATESELECTED, date:newDate});
                                    } else {
                                        show({
                                            show:false, 
                                            date:Util.toDateString(newDate),
                                            mode:payload.mode,
                                            minimumDate:payload.minimumDate, 
                                            maximumDate:payload.maximumDate, 
                                            onChange:payload.onChange,
                                        });
                                    }
                                }} />
                            )
                        } else if(selected.status === STATUS_DATESELECTED) {
                            return (
                                <RNDateTimePicker value={selected.date}
                                mode={"time"} is24Hour={true} display="default" locale="ko-KR"
                                onChange={(e, newDate) => { 
                                    if(newDate) {
                                        const datetime = `${moment(selected.date).format('YYYY-MM-DD')} ${moment(newDate).format('HH:mm')}:00`;
                                        //console.log('selected datetime - ', datetime);
                                        payload.onChange(datetime);
                                        setSelected({...selected, status:STATUS_TIMESELECTED});
                                        show({
                                            show:false, 
                                            date:datetime,
                                            mode:payload.mode,
                                            minimumDate:payload.minimumDate, 
                                            maximumDate:payload.maximumDate, 
                                            onChange:payload.onChange,
                                        });
                                    } else {
                                        show({
                                            show:false, 
                                            date:Util.toDateString(newDate),
                                            mode:payload.mode,
                                            minimumDate:payload.minimumDate, 
                                            maximumDate:payload.maximumDate, 
                                            onChange:payload.onChange,
                                        });
                                    }
                                }} />
                            )
                        } else {
                            return (
                                <Fragment />
                            )
                        }
                    })()}
                    </>
                ) : (
                    <RNDateTimePicker value={toDate(payload.date, new Date())} 
                        mode={"date"} is24Hour={true} display="default" locale="ko-KR"
                        minimumDate={toDate(payload.minimumDate, null)} maximumDate={toDate(payload.maximumDate, null)}
                        onChange={(e, newDate) => { 
                            if(newDate) {
                                payload.onChange(moment(newDate).format('YYYY-MM-DD')); 
                                show({
                                    show:false, 
                                    date:moment(newDate).format('YYYY-MM-DD'),
                                    mode:payload.mode,
                                    minimumDate:payload.minimumDate, 
                                    maximumDate:payload.maximumDate, 
                                    onChange:payload.onChange,
                                });
                            } else {
                                show({
                                    show:false, 
                                    date:moment(newDate).format('YYYY-MM-DD'),
                                    mode:payload.mode,
                                    minimumDate:payload.minimumDate, 
                                    maximumDate:payload.maximumDate, 
                                    onChange:payload.onChange,
                                });
                            }
                        }} />
                )}
            </ProviderContainerAndroid>
        )}
        {Platform.OS === "ios" && (
            payload.show &&
            <ProviderContainerIOS>
                <ProviderTopContainerIOS onPress={() => { show({show:false}) }} />
                <ProviderBottomContainerIOS>
                    <PickerHeader>
                        <CancelButton
                            buttonStyle={{ height:35, backgroundColor:'white', borderWidth:1, borderColor:'#595959' }}
                            textStyle={{ color:'#595959' }}
                            onPress={() => { 
                                show({
                                    show:false, 
                                    date:'',
                                    mode:payload.mode,
                                    minimumDate:payload.minimumDate, 
                                    maximumDate:payload.maximumDate, 
                                    onChange:payload.onChange,
                                });
                            }}>취소</CancelButton>
                        <PickButton
                            buttonStyle={{ height:35 }}
                            onPress={() => { 
                                if(isDateTime) {
                                    if(selected.status === STATUS_NOSELECTED) {
                                        setSelected({...selected, status: STATUS_DATESELECTED});
                                    } else if(selected.status === STATUS_DATESELECTED) {
                                        const datetime = moment(selected.date).format('YYYY-MM-DD HH:mm') + ':00';
                                        payload.onChange(datetime); 
                                        show({
                                            show:false, 
                                            date:datetime, 
                                            mode:payload.mode,
                                            minimumDate:payload.minimumDate, 
                                            maximumDate:payload.maximumDate, 
                                            onChange:payload.onChange,
                                        });
                                    }
                                } else {
                                    payload.onChange(Util.toDateString(toDate(payload.date, new Date()))); 
                                    show({
                                        show:false, 
                                        date:Util.toDateString(payload.date), 
                                        mode:payload.mode,
                                        minimumDate:payload.minimumDate, 
                                        maximumDate:payload.maximumDate, 
                                        onChange:payload.onChange,
                                    });
                                }
                            }}>선택</PickButton>
                    </PickerHeader>
                    {isDateTime ? (
                        <>
                        {(() => {
                            if(selected.status === STATUS_NOSELECTED || selected.status === STATUS_DATESELECTED) {
                                const pickerMode = selected.status === STATUS_NOSELECTED ? "date" : "time";
                                return (
                                    <RNDateTimePicker value={toDate(selected.date, toDate(payload.date, new Date()))} 
                                    mode={pickerMode} locale="ko-KR" is24Hour={true} display="default" 
                                    minimumDate={toDate(payload.minimumDate, null)} maximumDate={toDate(payload.maximumDate, null)}
                                    onChange={(e, newDate) => { 
                                        setSelected({ ...selected, date: newDate });
                                    }} />
                                );
                            } else {
                                return <Fragment />;
                            }
                        })()}
                        </>
                    ) : (
                        <RNDateTimePicker value={toDate(payload.date, new Date())} 
                            mode={"date"} locale="ko-KR" is24Hour={true} display="default" 
                            minimumDate={toDate(payload.minimumDate, null)} maximumDate={toDate(payload.maximumDate, null)}
                            onChange={(e, newDate) => { 
                                show({
                                    show:true, 
                                    date:Util.toDateString(newDate), 
                                    mode:payload.mode,
                                    minimumDate:payload.minimumDate, 
                                    maximumDate:payload.maximumDate, 
                                    onChange:payload.onChange,
                                });
                            }} />
                     )}
               </ProviderBottomContainerIOS>
            </ProviderContainerIOS>
        )}
        </Fragment>
    )
}