import React, { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
import Card from "./Card";
import { X } from "lucide-react";
import ReactDOM from "react-dom";
import Span from "../layout/Span";

export const ToastStyles = ["normal", "success", "error"] as const;
export const ToastColors = ToastStyles;

export type TWUIToastProps = DetailedHTMLProps<
    HTMLAttributes<HTMLDivElement>,
    HTMLDivElement
> & {
    open?: boolean;
    setOpen?: React.Dispatch<React.SetStateAction<boolean>>;
    closeDispatch?: (open?: boolean) => void;
    closeDelay?: number;
    color?: (typeof ToastStyles)[number];
};

let interval: any;
let timeout: any;

/**
 * # Toast Component
 * @className twui-toast-root
 * @className twui-toast
 * @className twui-toast-success
 * @className twui-toast-error
 */
export default function Toast({
    open,
    setOpen,
    closeDelay = 4000,
    color,
    closeDispatch,
    ...props
}: TWUIToastProps) {
    const [ready, setReady] = React.useState(false);
    const IDName = "twui-toast-root";

    React.useEffect(() => {
        const toastRoot = document.getElementById(IDName);

        if (toastRoot) {
            setReady(true);
        } else {
            const newToastRootEl = document.createElement("div");
            newToastRootEl.id = IDName;
            document.body.appendChild(newToastRootEl);
            setReady(true);
        }
    }, []);

    React.useEffect(() => {
        if (!ready || !open) return;

        timeout = setTimeout(() => {
            setOpen?.(false);
            closeDispatch?.(open);
        }, closeDelay);

        return function () {
            setOpen?.(false);
            closeDispatch?.(open);
        };
    }, [ready, open]);

    if (!ready) return null;
    if (!open) return null;

    return ReactDOM.createPortal(
        <Card
            {...props}
            className={twMerge(
                "fixed bottom-4 right-4 z-[250] border-none",
                "pl-6 pr-8 py-4 bg-primary dark:bg-primary-dark",
                color == "success"
                    ? "bg-success-dark dark:bg-success-dark twui-toast-success"
                    : color == "error"
                      ? "bg-error dark:bg-error-dark twui-toast-error"
                      : "",
                props.className,
                "twui-toast",
            )}
            onMouseEnter={() => {
                window.clearTimeout(timeout);
            }}
            onMouseLeave={(e) => {
                timeout = setTimeout(() => {
                    setOpen?.(false);
                    closeDispatch?.(open);
                }, closeDelay);
            }}
        >
            <Span
                className={twMerge(
                    "absolute top-2 right-2 z-[100] cursor-pointer",
                    "text-white",
                )}
                onClick={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    setOpen?.(false);
                    closeDispatch?.(open);
                }}
            >
                <X size={15} />
            </Span>
            <Span className={twMerge("text-white! font-semibold")}>
                {props.children}
            </Span>
        </Card>,
        document.getElementById(IDName) as HTMLElement,
    );
}
