import {
    type FC
} from "react";
import {
    TouchableOpacity,
    View
} from "react-native";
import type IHighlightButtonProps from "./type";
import stylesheet, {
    getHighlightButtonSize,
    getHighlightButtonType,
    useStyles
} from "./stylesheet";
import {
    NCoreUIKitTheme
} from "../../core/hooks";
import type ITextProps from "../text/type";
import Loading from "../loading";
import Text from "../text";

/**
 * A generic button
 * @param props {@link IHighlightButtonProps}
 * @returns Element
 */
const HighlightButton: FC<IHighlightButtonProps> = ({
    displayBehaviourWhileLoading = "disabled",
    verticalLocationForStretchFix = "start",
    spreadBehaviour = "baseline",
    icon: IconComponentProp,
    isCustomPadding = false,
    iconDirection = "left",
    isFixVerticalStretch,
    isDisabled = false,
    customBorderColor,
    customIconColor,
    customTextColor,
    glassEffect = 5,
    size = "medium",
    type = "glass",
    renderLoading,
    customColor,
    customTheme,
    titleStyle,
    isLoading,
    iconSize,
    onPress,
    style,
    title,
    ...props
}) => {
    const {
        typography,
        radiuses,
        borders,
        colors,
        spaces
    } = NCoreUIKitTheme.useContext(customTheme);

    const currentSize = getHighlightButtonSize({
        spaces,
        size
    });

    const currentType = getHighlightButtonType({
        type
    });

    const {
        container: containerDynamicStyle,
        loading: loadingDynamicStyle,
        overlay: overlayDynamicStyle,
        title: titleDynamicStyle
    } = useStyles({
        verticalLocationForStretchFix,
        displayBehaviourWhileLoading,
        icon: IconComponentProp,
        isFixVerticalStretch,
        customBorderColor,
        isCustomPadding,
        spreadBehaviour,
        iconDirection,
        currentSize,
        currentType,
        customColor,
        glassEffect,
        isDisabled,
        isLoading,
        radiuses,
        borders,
        colors,
        spaces,
        title,
        type
    });

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

    const iconProps: NCoreUIKit.IconCallbackProps = {
        size: iconSize ? iconSize : Number(typography[currentSize.fontSize].fontSize),
        color: currentType.iconColor
    };

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

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

    const renderIcon = (direction: "left" | "right") => {
        if(iconDirection !== direction) {
            return null;
        }

        if(!isDisabled && !isLoading) {
            if(customTextColor) {
                const _customTextColor = customTextColor as keyof NCoreUIKit.ProjectColorPalette;
                iconProps.customColor = colors.project[_customTextColor] ? colors.project[_customTextColor] : customTextColor;
            }

            if(customIconColor) {
                const _customIconColor = customIconColor as keyof NCoreUIKit.ProjectColorPalette;
                iconProps.customColor = colors.project[_customIconColor] ? colors.project[_customIconColor] : customIconColor;
            }
        }

        if (isLoading) {
            if(renderLoading) {
                return renderLoading();
            }

            return <Loading
                {...iconProps}
                style={{
                    ...loadingDynamicStyle
                }}
            />;
        }

        if (!IconComponentProp) {
            return null;
        }

        return <IconComponentProp
            {...iconProps}
        />;
    };

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

        if(!isDisabled && !isLoading) {
            if(customTextColor) {
                titleProps.customColor = customTextColor;
            }
        }

        return <Text
            variant={currentSize.fontSize}
            style={[
                titleStyle,
                stylesheet.title,
                titleDynamicStyle
            ]}
            {...titleProps}
        >
            {title}
        </Text>;
    };

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

    return <TouchableOpacity
        {...props}
        onPress={isDisabled || isLoading ? () => null : onPress}
        disabled={isDisabled || isLoading}
        style={[
            style,
            stylesheet.container,
            containerDynamicStyle
        ]}
    >
        {renderIcon("left")}
        {renderTitle()}
        {renderIcon("right")}
        {renderOverlay()}
    </TouchableOpacity>;
};
export default HighlightButton;
