import {
    type FC
} from "react";
import {
    TouchableOpacity,
    Platform,
    View
} from "react-native";
import type ICheckBoxProps from "./type";
import stylesheet, {
    getCheckBoxType,
    useStyles
} from "./stylesheet";
import {
    NCoreUIKitLocalize,
    NCoreUIKitTheme
} from "../../core/hooks";
import type ITextProps from "../text/type";
import {
    Check as CheckIcon,
    Minus as MinusIcon
} from "lucide-react-native";
import Loading from "../loading";
import Text from "../text";

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

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

    const currentType = getCheckBoxType({
        type
    });

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

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

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

    const indicatorIconProps: {
        color: keyof NCoreUIKit.BorderContentColors;
        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(isChecked && 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 renderCheckIcon = () => {
        if(!isChecked) {
            return <View
                style={stylesheet.emptyIcon}
            />;
        }

        const selectedColor = indicatorIconProps.customColor ? indicatorIconProps.customColor : colors.content.border[indicatorIconProps.color];

        if(isChecked === "partially") {
            return <MinusIcon
                color={selectedColor}
                size={16}
            />;
        }

        return <CheckIcon
            color={selectedColor}
            size={16}
        />;
    };

    const renderCheckIndicator = () => {
        if (isLoading) {
            return <Loading
                style={{
                    ...loadingDynamicStyle
                }}
            />;
        }

        return <View
            style={[
                stylesheet.indicatorContainer,
                indicatorContainerDynamicStyle
            ]}
        >
            {renderCheckIcon()}
            {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
        ]}
        {...Platform.select({
            web: {
                dataSet: {
                    disablePressableDownEffect: "true"
                }
            },
            default: {}
        })}
    >
        {isFlip ? null : renderCheckIndicator()}
        {renderContent()}
        {isFlip ? renderCheckIndicator() : null}
    </TouchableOpacity>;
};
export default CheckBox;
