import {
    useEffect,
    useState,
    type FC,
    useRef
} from "react";
import {
    TouchableWithoutFeedback,
    Animated,
    Easing,
    View
} from "react-native";
import type ISnackBarProps from "./type";
import stylesheet, {
    getSnackBarType,
    useStyles
} from "./stylesheet";
import {
    NCoreUIKitTheme
} from "../../core/hooks";
import {
    useSafeAreaInsets
} from "react-native-safe-area-context";
import {
    X as XIcon
} from "lucide-react-native";
import {
    Portal
} from "../../helpers/portalize";
import Button from "../button";
import Text from "../text";
import {
    windowHeight
} from "../../utils";

const SnackBar: FC<ISnackBarProps> = ({
    isCloseOnPressActionButton = true,
    closeAnimationDelay = 350,
    openAnimationDelay = 200,
    contentContainerStyle,
    autoCloseDelay = 5000,
    isCloseOnPress = true,
    isShowAction = true,
    isFullWidth = false,
    isInlineSafeArea,
    icon: CustomIcon,
    type = "neutral",
    customTheme,
    onClosed,
    subTitle,
    children,
    onPress,
    action,
    style,
    title,
    id
}) => {
    const {
        radiuses,
        colors,
        spaces
    } = NCoreUIKitTheme.useContext(customTheme);

    const {
        top
    } = useSafeAreaInsets();

    const [
        isMeasured,
        setIsMeasured
    ] = useState(false);

    const contentHeight = useRef<number>(windowHeight);

    const transformAnim = useRef(new Animated.Value(-contentHeight.current + -top + -spaces.spacingSm)).current;
    const opacityAnim = useRef(new Animated.Value(0)).current;

    const currentType = getSnackBarType({
        type
    });

    const {
        contentContainer: contentContainerDynamicStyle,
        containerObject: containerObjectDynamicStyle,
        iconContainer: iconContainerDynamicStyle,
        container: containerDynamicStyle,
        subTitle: subTitleDynamicStyle,
        action: actionDynamicStyle,
        title: titleDynamicStyle
    } = useStyles({
        isInlineSafeArea,
        safeAreaTop: top,
        isFullWidth,
        currentType,
        radiuses,
        spaces,
        colors,
        type
    });

    useEffect(() => {
        if(isMeasured) {
            transformAnim.setValue(-contentHeight.current + -top + -spaces.spacingSm);

            Animated.parallel([
                Animated.timing(opacityAnim, {
                    duration: openAnimationDelay,
                    useNativeDriver: true,
                    easing: Easing.linear,
                    toValue: 1
                }),
                Animated.timing(transformAnim, {
                    duration: openAnimationDelay,
                    useNativeDriver: true,
                    easing: Easing.linear,
                    toValue: 0
                })
            ]).start();

            setTimeout(() => {
                closeAnimation();
            }, autoCloseDelay);
        }
    }, [isMeasured]);

    const closeAnimation = (_onClosed?: (props: {
        id: string;
    }) => void) => {
        Animated.parallel([
            Animated.timing(transformAnim, {
                toValue: -contentHeight.current + -top + -spaces.spacingSm,
                duration: closeAnimationDelay,
                useNativeDriver: true,
                easing: Easing.linear
            }),
            Animated.timing(opacityAnim, {
                duration: closeAnimationDelay,
                useNativeDriver: true,
                easing: Easing.linear,
                toValue: 0
            })
        ]).start(({
            finished
        }) => {
            if(finished) {
                if(onClosed) onClosed({
                    id
                });

                if(_onClosed) _onClosed({
                    id
                });
            }
        });
    };

    const renderIcon = () => {
        if(!CustomIcon) {
            return null;
        }

        return <View
            style={[
                stylesheet.iconContainer,
                iconContainerDynamicStyle
            ]}
        >
            <CustomIcon
                color="default"
                size={18}
            />
        </View>;
    };

    const renderContent = () => {
        return <View
            style={[
                contentContainerStyle,
                stylesheet.contentContainer,
                contentContainerDynamicStyle
            ]}
        >
            <Text
                numberOfLines={3}
                style={{
                    ...stylesheet.title,
                    ...titleDynamicStyle
                }}
            >
                {title}
            </Text>
            {
                subTitle ?
                    <Text
                        variant="labelSmallSize"
                        numberOfLines={2}
                        color="low"
                        style={{
                            ...stylesheet.subTitle,
                            ...subTitleDynamicStyle
                        }}
                    >
                        {subTitle}
                    </Text>
                    :
                    null
            }
        </View>;
    };

    const renderAction = () => {
        if(!isShowAction) {
            return null;
        }

        return <Button
            title={action && action.title ? action.title : undefined}
            isCustomPadding={true}
            spreadBehaviour="free"
            onPress={() => {
                if(isCloseOnPressActionButton) closeAnimation();

                if(action && action.onPress) action.onPress({
                    closeAnimation: ({
                        onClosed: _onClosed
                    }) => closeAnimation(_onClosed)
                });
            }}
            icon={({
                color
            }) => {
                if(action?.title) {
                    return null;
                }

                return <XIcon
                    color={colors.content.icon[color ? color : "default"]}
                    size={18}
                />;
            }}
            style={{
                ...action?.style,
                ...actionDynamicStyle
            }}
            variant="ghost"
            type="neutral"
            size="small"
        />;
    };

    const renderContainer = () => {
        return <View
            style={[
                stylesheet.containerObject,
                containerObjectDynamicStyle
            ]}
        >
            {renderIcon()}
            {renderContent()}
            {renderAction()}
        </View>;
    };

    return <Portal name="snack-bar-system">
        <Animated.View
            onLayout={(event) => {
                const _contentHeight = event.nativeEvent.layout.height;

                contentHeight.current = _contentHeight;

                setIsMeasured(true);
            }}
            style={[
                style,
                stylesheet.container,
                containerDynamicStyle,
                {
                    opacity: opacityAnim,
                    transform: [{
                        translateY: transformAnim
                    }]
                }
            ]}
        >
            <TouchableWithoutFeedback
                onPress={() => {
                    if(onPress) onPress({
                        id
                    });

                    if(isCloseOnPress) {
                        closeAnimation();
                    }
                }}
            >
                {children ? children : renderContainer()}
            </TouchableWithoutFeedback>
        </Animated.View>
    </Portal>;
};
export default SnackBar;
