import {
    type FC,
    useEffect,
    useRef
} from "react";
import {
    TouchableOpacity,
    Animated,
    Easing,
    View
} from "react-native";
import type ISwitchProps from "./type";
import stylesheet, {
    getSwitchType,
    useStyles
} from "./stylesheet";
import {
    NCoreUIKitLocalize,
    NCoreUIKitTheme
} from "../../core/hooks";
import type ITextProps from "../text/type";
import Loading from "../loading";
import Text from "../text";

const Switch: FC<ISwitchProps> = ({
    displayBehaviourWhileLoading = "disabled",
    spreadBehaviour = "baseline",
    animationDuration = 100,
    isOptional = false,
    isDisabled = false,
    type = "neutral",
    isFlip = false,
    customLocalize,
    subTitleStyle,
    optionalText,
    customTheme,
    titleStyle,
    isLoading,
    isActive,
    subTitle,
    onPress,
    title,
    style,
    ...props
}) => {
    const {
        inlineSpaces,
        colors,
        spaces
    } = NCoreUIKitTheme.useContext(customTheme);

    const {
        localize
    } = NCoreUIKitLocalize.useContext(customLocalize);

    const indicatorAnim = useRef(new Animated.Value(0)).current;

    const currentType = getSwitchType({
        type
    });

    const SWITCH_INDICATOR_SIZE = 20;

    const {
        indicatorContainer: indicatorContainerDynamicStyle,
        contentContainer: contentContainerDynamicStyle,
        titleContainer: titleContainerDynamicStyle,
        optionalText: optionalTextDynamicStyle,
        container: containerDynamicStyle,
        indicator: indicatorDynamicStyle,
        subTitle: subTitleDynamicStyle,
        loading: loadingDynamicStyle,
        overlay: overlayDynamicStyle,
        title: titleDynamicStyle
    } = useStyles({
        displayBehaviourWhileLoading,
        SWITCH_INDICATOR_SIZE,
        spreadBehaviour,
        inlineSpaces,
        currentType,
        isDisabled,
        isLoading,
        isActive,
        isFlip,
        colors,
        spaces,
        type
    });

    useEffect(() => {
        if(isActive) {
            Animated.timing(indicatorAnim, {
                toValue: (SWITCH_INDICATOR_SIZE / 2) + spaces.spacingSm,
                duration: animationDuration,
                useNativeDriver: true,
                easing: Easing.linear
            }).start();
        } else {
            Animated.timing(indicatorAnim, {
                duration: animationDuration,
                useNativeDriver: true,
                easing: Easing.linear,
                toValue: 0
            }).start();
        }
    }, [isActive]);

    const titleProps: ITextProps = {
        color: currentType.titleColor,
    };

    const subTitleProps: ITextProps = {
        color: currentType.subTitleColor,
    };

    const indicatorIconProps: {
        color: keyof NCoreUIKit.IconContentColors;
        customColor?: string;
    } = {
        color: currentType.indicatorColor
    };

    if (isDisabled || isLoading) {
        const stateType = type === "danger" ? "error" : type;

        subTitleProps.customColor = colors.system.state.content.disabled[stateType];
        titleProps.customColor = colors.system.state.content.disabled[stateType];

        if(isActive && stateType === "neutral") {
            indicatorIconProps.customColor = colors.system.state.border.disabled.primary;
        } else {
            indicatorIconProps.customColor = colors.system.state.border.disabled[stateType];
        }
    }

    const renderOptionalText = () => {
        if(!isOptional && !optionalText) {
            return null;
        }

        return <Text
            variant="labelLargeSize"
            color={titleProps.color}
            style={[
                optionalTextDynamicStyle
            ]}
            {...titleProps}
        >
            ( {isOptional ? localize("is-optional") : optionalText} )
        </Text>;
    };

    const renderTitle = () => {
        if (!title) {
            return null;
        }

        return <View
            style={[
                stylesheet.titleContainer,
                titleContainerDynamicStyle
            ]}
        >
            <Text
                variant="bodyMediumSize"
                style={[
                    titleStyle,
                    stylesheet.title,
                    titleDynamicStyle
                ]}
                {...titleProps}
            >
                {title}
            </Text>
            {renderOptionalText()}
        </View>;
    };

    const renderIndicator = () => {
        return <Animated.View
            style={[
                stylesheet.indicator,
                indicatorDynamicStyle,
                {
                    transform: [{
                        translateX: indicatorAnim
                    }]
                }
            ]}
        />;
    };

    const renderIndicatorContainer = () => {
        if (isLoading) {
            return <Loading
                style={[
                    loadingDynamicStyle
                ]}
            />;
        }

        return <View
            style={[
                stylesheet.indicatorContainer,
                indicatorContainerDynamicStyle
            ]}
        >
            {renderIndicator()}

            {renderOverlay()}
        </View>;
    };

    const renderOverlay = () => {
        return <View
            style={[
                stylesheet.overlay,
                overlayDynamicStyle
            ]}
        />;
    };

    const renderSubtitle = () => {
        if(!subTitle) {
            return null;
        }

        return <Text
            {...subTitleProps}
            style={[
                subTitleStyle,
                stylesheet.subTitle,
                subTitleDynamicStyle
            ]}
        >
            {subTitle}
        </Text>;
    };

    const renderContent = () => {
        if(!title) {
            return null;
        }

        return <View
            style={[
                stylesheet.contentContainer,
                contentContainerDynamicStyle
            ]}
        >
            {renderTitle()}
            {renderSubtitle()}
        </View>;
    };

    return (
        <TouchableOpacity
            {...props}
            onPress={isDisabled || isLoading ? () => null : onPress ? onPress : undefined}
            disabled={isDisabled || isLoading || !onPress}
            style={[
                style,
                stylesheet.container,
                containerDynamicStyle
            ]}
        >
            {isFlip ? null : renderIndicatorContainer()}

            {renderContent()}

            {isFlip ? renderIndicatorContainer() : null}
        </TouchableOpacity>
    );
};
export default Switch;
