import {
    useEffect,
    type FC,
    useRef
} from "react";
import {
    TouchableWithoutFeedback,
    useWindowDimensions,
    Animated,
    Easing,
    View
} from "react-native";
import type IToastProps from "./type";
import stylesheet, {
    getToastType,
    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";

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

    const {
        bottom
    } = useSafeAreaInsets();

    const {
        width: windowWidth
    } = useWindowDimensions();

    const TRANSFORM_DISTANCE = 75;

    const transformAnim = useRef(new Animated.Value(TRANSFORM_DISTANCE)).current;
    const opacityAnim = useRef(new Animated.Value(0)).current;

    const currentType = getToastType({
        type
    });

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

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

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

    const closeAnimation = (_onClosed?: (props: {
        id: string;
    }) => void) => {
        Animated.parallel([
            Animated.timing(transformAnim, {
                duration: closeAnimationDelay,
                toValue: TRANSFORM_DISTANCE,
                useNativeDriver: true,
                easing: Easing.linear
            }),
            Animated.timing(opacityAnim, {
                duration: closeAnimationDelay,
                easing: Easing.linear,
                useNativeDriver: true,
                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={currentType.iconColor}
                size={18}
            />
        </View>;
    };

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

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

        return <Button
            icon={() => {
                if(action?.title) {
                    return null;
                }

                return <XIcon
                    color={colors.content.text[currentType.actionColor]}
                    size={18}
                />;
            }}
            title={action && action.title ? action.title : undefined}
            onPress={() => {
                if(isCloseOnPressActionButton) closeAnimation();

                if(action && action.onPress) action.onPress({
                    closeAnimation: ({
                        onClosed: _onClosed
                    }) => closeAnimation(_onClosed)
                });
            }}
            style={{
                ...action?.style,
                ...actionDynamicStyle
            }}
            isCustomPadding={true}
            spreadBehaviour="free"
            variant="ghost"
            size="small"
            type={type}
        />;
    };

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

    return <Portal
        name="toast-system"
    >
        <Animated.View
            style={[
                style,
                stylesheet.container,
                containerDynamicStyle,
                {
                    width: windowWidth - (spaces.spacingMd * 2),
                    transform: [
                        {
                            translateY: transformAnim
                        }
                    ],
                    opacity: opacityAnim
                }
            ]}
        >
            <TouchableWithoutFeedback
                onPress={() => {
                    if(isCloseOnPress) {
                        closeAnimation();
                    }
                }}
            >
                {children ? children : renderContainer()}
            </TouchableWithoutFeedback>
        </Animated.View>
    </Portal>;
};
export default Toast;
