import React from "react";
import { Text, TouchableOpacity, View } from "react-native";
import ReactNativeModal from "react-native-modal";
import { StyleSheet } from "react-native";
import CircleClose from "../assets/ReactSVG/CircleClose";
import CircleTick from "../assets/ReactSVG/CircleTick";
import CircleExclamation from "../assets/ReactSVG/CircleExclamation";
import CircleQuestion from "../assets/ReactSVG/CircleQuestion";
import CircleI from "../assets/ReactSVG/CircleI";

interface IQuestNotificationState {
    isVisible: boolean;
    title: string;
    notificationType: INotificationType;
    duration: number;
}

interface IQuestNotificationProps {
    duration?: number;
}

type INotificationType = "warning" | "error" | "success" | "info";

export default class QuestNotification extends React.Component<IQuestNotificationProps, IQuestNotificationState> {
    private static __singletonRef: QuestNotification | null;

    constructor(props: IQuestNotificationProps) {
        super(props);
        QuestNotification.__singletonRef = this;

        const duration = props.duration ?? 3000;

        this.state = {
            isVisible: false,
            notificationType: "info",
            title: "",
            duration: duration,
        };
    }

    state: Readonly<IQuestNotificationState> = {
        isVisible: false,
        notificationType: "info",
        title: "",
        duration: 3000,
    }

    private timeoutRef: NodeJS.Timeout;

    private getPrevAlertIcon() {
        switch (this.state.notificationType) {
            case "success": {
                return <CircleTick fill={this.getColorForAlertType()} />;
            }
            case "error": {
                return <CircleExclamation fill={this.getColorForAlertType()} />;
            }
            case "warning": {
                return <CircleQuestion fill={this.getColorForAlertType()} />;
            }
            default: {
                return <CircleI fill={this.getColorForAlertType()} />;
            }
        }
    };

    private getColorForAlertType() {
        switch (this.state.notificationType) {
            case "success": {
                return "#098849";
            }
            case "error": {
                return "#ED0A34";
            }
            case "warning": {
                return "#FF8744";
            }
            default: {
                return "#0065FF";
            }
        }
    };

    private getBgColorForAlertType() {
        switch (this.state.notificationType) {
            case "success": {
                return "#EBFFF7";
            }
            case "error": {
                return "#FFECF1";
            }
            case "warning": {
                return "#FFFBEC";
            }
            default: {
                return "#E6F0FF";
            }
        }
    };

    private hideNotification = () => {
        this.setState(prev => ({
            ...prev,
            isVisible: false,
        }))
    }

    private showNotification = (title: string, notificationType: INotificationType) => {
        this.setState(prev => ({
            ...prev,
            isVisible: true,
            notificationType,
            title,
        }));
    }

    private fireTimeout = () => {
        if (this.timeoutRef) {
            clearTimeout(this.timeoutRef);
        }

        this.timeoutRef = setTimeout(this.hideNotification, this.state.duration);
    }

    static success = (title: string) => {
        QuestNotification.__singletonRef?.showNotification(title, "success");
        QuestNotification.__singletonRef?.fireTimeout();
    }

    static error = (title: string) => {
        QuestNotification.__singletonRef?.showNotification(title, "error");
        QuestNotification.__singletonRef?.fireTimeout();
    }

    static info = (title: string) => {
        QuestNotification.__singletonRef?.showNotification(title, "info");
        QuestNotification.__singletonRef?.fireTimeout();
    }

    static warning = (title: string) => {
        QuestNotification.__singletonRef?.showNotification(title, "warning");
        QuestNotification.__singletonRef?.fireTimeout();
    }

    static setDuration = (duration: number) => {
        QuestNotification.__singletonRef?.setState(prev => ({
            ...prev,
            duration,
        }));
    }

    render(): React.ReactNode {
        return (
            <>
                <ReactNativeModal
                    isVisible={this.state.isVisible}
                    animationIn="slideInDown"
                    animationOut="slideOutUp"
                    animationInTiming={500}
                    animationOutTiming={900}
                    backdropTransitionInTiming={500}
                    backdropTransitionOutTiming={900}
                    hasBackdrop={false}
                    backdropColor="black"
                    backdropOpacity={0.2}
                    swipeDirection={["left", "right"]}
                    onSwipeComplete={this.hideNotification}
                >
                    <View
                        style={styles.modalMainView}
                    >
                        <View
                            style={[styles.alertContainer, { backgroundColor: this.getBgColorForAlertType() }]}
                        >
                            <View>{this.getPrevAlertIcon()}</View>
                            <Text style={{ flex: 1, color: this.getColorForAlertType() }}>
                                {this.state.title}
                            </Text>
                            <TouchableOpacity onPress={this.hideNotification}>
                                <CircleClose fill={this.getColorForAlertType()} />
                            </TouchableOpacity>
                        </View>
                    </View>
                </ReactNativeModal>
            </>
        )
    }
}

const styles = StyleSheet.create({
    modalMainView: {
        borderRadius: 12,
        position: "absolute",
        shadowColor: "#000",
        shadowOffset: {
            width: 0,
            height: 2,
        },
        shadowOpacity: 0.25,
        shadowRadius: 3.84,
        elevation: 5,
        top: 10,
        width: "100%",
        backgroundColor: "white",
    },
    alertContainer: {
        borderRadius: 12,
        paddingHorizontal: 15,
        paddingVertical: 10,
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        gap: 5,
    },
});