import React, { Fragment, useCallback, useEffect, useState, forwardRef, useImperativeHandle } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Styled from 'styled-components/native';
import { selectOpenAction, changeSelectedItemAction } from '~/GlobalReducers/selectbox';
import Theme from '~/Themes';
import Icon from '~/Components/UIControls/Icon';
import { ActivityIndicator, Keyboard, TouchableOpacity, View, Modal } from 'react-native';
import DownIcon from '~/Assets/Svgs/Selectbox/down.svg';
import { usePrevious } from '../Hooks';

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 SelectboxLabel = Styled.Text`
    font-size: 16px;
    font-family: ${Theme.Fonts.Regular};
    include-font-padding: false;
    align-items: center;
    color: #43425d;
    flex: 1;
`;
const SelectboxDefaultLabel = Styled(SelectboxLabel)`
    color: #9aa3ac;
`;
const DownArrow = Styled(Icon)`
    margin-right: 3px;
    margin-left: 3px;
`;
const onChangeDefault = (item) => {};
const onCancelDefault = () => {};
export const Selectbox = forwardRef(({
        items=[], itemChangeMode='value', style={}, itemRender=null, selectedValue=null, selectedText='', initialValue=null, defaultLabel='선택', 
        onChange=onChangeDefault, onCancel=onCancelDefault, loading=false, editable=true, hidden=false, emptyLabel=null
    }, ref) => {

    const dispatch = useDispatch();
    const selectOpen = useCallback((select) => dispatch(selectOpenAction(select)), []);
    const changeSelectedItem = useCallback((item) => dispatch(changeSelectedItemAction(item)), []);

    const [selectedItem, setSelectedItem] = useState(null);

    const findSelectedItem = () => {
        let findedItem = items.find(item => item.value == (selectedValue == null ? initialValue : selectedValue));
        if(typeof findedItem === 'undefined') findedItem = null;
        setSelectedItem(findedItem);

        return findedItem;
    };

    const prevEditable = usePrevious(editable);
    const prevItems = usePrevious(items);
    const prevSelectedValue = usePrevious(selectedValue);
    useEffect(() => {
        if((itemChangeMode == 'value' && JSON.stringify(items) !== JSON.stringify(prevItems))
            || (itemChangeMode == 'reference' && items !== prevItems)
            || selectedValue != prevSelectedValue
            || editable != prevEditable) {
            const findedItem = findSelectedItem();

            // editable 이 변경되는시점에 onChange 이벤트 발생해야 함.
            if(typeof prevEditable !== 'undefined' && prevEditable != editable) {
                onChange(findedItem || {label:'', value:''});
            }
        } else {
            // editable 이 변경되는시점에 onChange 이벤트 발생해야 함.
            if(typeof prevEditable !== 'undefined' && prevEditable != editable) {
                onChange(selectedItem || {label:'', value:''});
            }
        }
    }, [items, selectedValue, editable]);

    useImperativeHandle(ref, () => ({
        openSelect: () => {
            selectOpen({
                show:true, items:items, itemRender:itemRender, 
                onChange:onChange, onCancel:onCancel, 
                setSelectedItem:setSelectedItem
            });
        },
    }), [items, itemRender, onChange, onCancel, setSelectedItem]);

    //console.log('>>>>>> selectedValue : ', selectedValue, ', selectedItem : ', selectedItem);

    const Container = editable ? Styled(TouchableOpacity)`${ContainerStyle}` : Styled(View)`${ContainerStyle}`;
    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 };

    return (
        hidden ? (
            <Fragment />
        ) : (
            <Fragment>
            {loading ? (
                <Container style={[backgroundStyle, style, { justifyContent: 'center', alignItems: 'center', ...borderStyle}]}>
                    <ActivityIndicator size="small" color="#555555" />
                </Container>
            ) : (
                <Container style={[backgroundStyle, style, {...borderStyle}]} onPress={() => { 
                    if(editable) {
                        selectOpen({
                            show:true, 
                            items:emptyLabel ? [{label:emptyLabel, value:''}, ...items] : items, 
                            itemRender:itemRender, 
                            onChange:onChange, 
                            onCancel:onCancel, 
                            setSelectedItem:setSelectedItem
                        })
                    }
                }}>
                    {selectedItem == null || selectedItem.value == null || selectedItem.value === '' ? 
                        <SelectboxDefaultLabel numberOfLines={1} ellipsizeMode="tail">
                            {editable ? (emptyLabel ? emptyLabel : defaultLabel) : (selectedText ? selectedText : "")}
                        </SelectboxDefaultLabel>
                        :
                        <SelectboxLabel numberOfLines={1} ellipsizeMode="tail">{selectedItem.label}</SelectboxLabel>
                    }
                    {editable && <DownIcon width={18} height={9} color="#b9bac4" />}
                </Container>
            )}
            </Fragment>
        )
    )
});

const ListProviderContainer = Styled.TouchableOpacity`
    position: absolute;
    width: 100%; height:100%;
    padding: 20px;
    background-color: black; opacity:0.7;
`;
const ListContainer = Styled.ScrollView`
    position: absolute;
    left:10%; top:20%;
    width:80%; height: 60%;
    padding: 10px;
    background-color: white;
    border-radius: 5px;
`;
const Item = Styled.TouchableOpacity`
    flex-direction: row;
    width: 100%;
    height: 50px;
    padding-left: 10px;
    align-items: center;
    background-color: white;
`;
const SelectedItem = Styled(Item)`
    background-color: #dedede;
`;
const Label = Styled.Text`
    font-size: 20px;
    color: #555555;
`;
const SelectedLabel = Styled(Label)`
`;
export const SelectboxListProvider = () => {
    const payload = useSelector(({ GlobalSelect }) => GlobalSelect.select);
    const dispatch = useDispatch();
    const selectOpen = useCallback((select) => dispatch(selectOpenAction(select)), []);

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

    return (
        payload.show ?
        <Modal animationType="fade" transparent={true}>
            <ListProviderContainer onPress={() => { payload.onCancel(); selectOpen({show:false}); }}>
            </ListProviderContainer>
            <ListContainer>
                {payload.items.map((item, index) => (
                    <Item key={index} onPress={() => { 
                        console.log('SelectboxProvider change - ', {...item});
                        payload.setSelectedItem({...item}); 
                        payload.onChange({...item});
                        selectOpen({show:false});
                    }}>
                        <Label>{item.label}</Label>
                    </Item>
                ))}
            </ListContainer>
        </Modal>
        : null
    )
};