import React, { Fragment, useEffect, useRef, useState } from 'react';
import { View, Text, TouchableOpacity, LayoutAnimation, Platform, UIManager, ScrollView, FlatList, StyleSheet } from 'react-native';
import { PopupLayout, useLayoutAction } from '~/Components/Layouts/PopupLayout';
import { SearchBoxIcon, DefaultButton, PrimaryButton } from '~/Components/Listing/Search';
import { DefaultAction } from '~/Components/UIControls/Popup/Context';
import { DragDrop, DragDropProvider } from '~/Components/UIControls/dragdrop';
import Icon from '~/Components/UIControls/Icon';
import { Util } from '~/Utils/utils';

if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
    UIManager.setLayoutAnimationEnabledExperimental(true);
}

const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        width: '100%',
        height: '100%',
    },
    destination: {
        backgroundColor: 'white',
        borderRightWidth: 1,
        borderColor: '#dedede',
        width: '50%',
    },
    destitem: {
        backgroundColor: '#ee4035',
        padding: 10,
        margin: 5,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        borderRadius: 7,
    },
    destitemtext: {
        color: 'white',
        marginVertical: 5,
    },
    src: {
        backgroundColor: 'white',
        width: '50%',
    },
    srcitem: {
        backgroundColor: '#005b96',
        padding: 10,
        margin: 5,
        flexDirection: 'row',
        alignItems: 'center',
        borderRadius: 7,
    },
    srcitemtext: {
        color: 'white',
        marginVertical: 5,
    },
});

export default Popup = ({ siteId = 0, popup = DefaultAction }) => {
    const [items, setItems] = useState([]);
    const [selectItems, setSelectItems] = useState([]);
    const src = useRef();
    const dest = useRef();
    const destMeasure = useRef(null);
    const lastSelectItem = useRef();
    const lastSelectItemMeasure = useRef(null);

    const updateMeasure = async () => {
        destMeasure.current = await Util.getMeasure(dest.current);
        if (lastSelectItem.current) {
            lastSelectItemMeasure.current = await Util.getMeasure(lastSelectItem.current);
        }
    };

    const handleDraggableCheck = (e, gesture) => {
        if (e.nativeEvent.locationX <= 80) {
            src.current.setNativeProps({ scrollEnabled: false });
            updateMeasure();
            return true;
        } else {
            src.current.setNativeProps({ scrollEnabled: true });
            return false;
        }
    };

    const handleDragStart = (e, gesture) => {};

    const handleDragEnd = (gesture, item) => {
        src.current.setNativeProps({ scrollEnabled: true });
        if (selectItems.findIndex((value) => value.name == item.name) != -1) {
            return false;
        }

        if (
            !!destMeasure.current &&
            gesture.moveX >= destMeasure.current.pageX &&
            gesture.moveX <= destMeasure.current.pageX + destMeasure.current.width &&
            gesture.moveY >= destMeasure.current.pageY &&
            gesture.moveY <= destMeasure.current.pageY + destMeasure.current.height
        ) {
            if (selectItems.length > 0 && lastSelectItemMeasure.current) {
                return {
                    dropX: lastSelectItemMeasure.current.pageX,
                    dropY: lastSelectItemMeasure.current.pageY + lastSelectItemMeasure.current.height,
                };
            } else {
                return {
                    dropX: destMeasure.current.pageX,
                    dropY: destMeasure.current.pageY,
                };
            }
        }
        return false;
    };

    const appendSelected = (item) => {
        if (selectItems.findIndex((value) => value.name == item.name) != -1) return;

        LayoutAnimation.configureNext(LayoutAnimation.create(150, LayoutAnimation.Types.easeInEaseOut, LayoutAnimation.Properties.opacity));

        setSelectItems([...selectItems, { name: item.name }]);
    };

    const removeSelected = (item) => {
        const newItems = selectItems.filter((value) => value.name != item.name);

        LayoutAnimation.configureNext(LayoutAnimation.create(150, LayoutAnimation.Types.easeInEaseOut, LayoutAnimation.Properties.opacity));

        setSelectItems(newItems);
    };

    const actionHandler = (action, parameter = {}) => {
        const actions = {
            onClose: () => {
                console.log('close...');
                popup.close();
            },
            onSelect: () => {
                console.log('select...');
                const names = selectItems.map((item) => item.name).join(',');
                popup.select(names);
            },
        };
        actions[action]();
    };

    useEffect(() => {
        let list = [];
        for (let i = 1; i < 200; i++) {
            list = [...list, { id: i, name: `이름${i}` }];
        }
        setItems(list);
    }, []);

    return (
        <PopupLayout title="사용자 선택" header={Header} actionHandler={actionHandler}>
            <View style={styles.container}>
                <DragDropProvider>
                    <View style={styles.destination} ref={dest}>
                        <ScrollView style={{ width: '100%', height: '100%' }}>
                            {selectItems.map((item, index) => {
                                const last = selectItems.length - 1 == index;
                                return (
                                    <View key={`select-item-${index}`} style={styles.destitem} ref={last ? lastSelectItem : undefined}>
                                        <Text style={styles.destitemtext}>{item.name}</Text>
                                        <TouchableOpacity onPress={() => removeSelected(item)}>
                                            <Icon iconFamily="AntDesign" iconName="minuscircle" size={20} color="white" />
                                        </TouchableOpacity>
                                    </View>
                                );
                            })}
                        </ScrollView>
                    </View>
                    <FlatList
                        style={[styles.src, { overflow: 'visible' }]}
                        ref={src}
                        data={items}
                        keyExtractor={(item, index) => `item-${index}`}
                        renderItem={({ item, index }) => {
                            return (
                                <DragDrop
                                    style={styles.srcitem}
                                    onDraggableCheck={handleDraggableCheck}
                                    onDragStart={handleDragStart}
                                    onDragEnd={(gesture) => {
                                        return handleDragEnd(gesture, item);
                                    }}
                                    hideWhenDrop={true}
                                    onRemove={() => {
                                        appendSelected(item);
                                    }}
                                >
                                    <Icon iconFamily="MaterialCommunityIcons" iconName="drag" size={20} color="white" />
                                    <Text style={styles.srcitemtext}>{item.name}</Text>
                                </DragDrop>
                            );
                        }}
                    />
                </DragDropProvider>
            </View>
        </PopupLayout>
    );
};

const Header = () => {
    const { callAction } = useLayoutAction();

    return (
        <Fragment>
            <DefaultButton
                onPress={() => {
                    callAction('onClose');
                }}
            >
                닫기
            </DefaultButton>
            <PrimaryButton
                onPress={() => {
                    callAction('onSelect');
                }}
            >
                선택
            </PrimaryButton>
        </Fragment>
    );
};
