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

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

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

/**
 * # 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,
    ...props
}: Props) {
    if (!open) return null;

    const toastEl = (
        <Card
            {...props}
            className={twMerge(
                "pl-6 pr-8 py-4 bg-blue-700 dark:bg-blue-800",
                color == "success"
                    ? "bg-emerald-600 dark:bg-emerald-700 twui-toast-success"
                    : color == "error"
                    ? "bg-orange-600 dark:bg-orange-700 twui-toast-error"
                    : "",
                props.className,
                "twui-toast"
            )}
        >
            <Span
                className={twMerge(
                    "absolute top-2 right-2 z-[100] cursor-pointer"
                )}
                onClick={(e) => {
                    const targetEl = e.target as HTMLElement;
                    const rootWrapperEl = targetEl.closest(".twui-toast-root");

                    if (rootWrapperEl) {
                        rootWrapperEl.parentElement?.removeChild(rootWrapperEl);
                        setOpen?.(false);
                    }
                }}
            >
                <X size={15} />
            </Span>
            {props.children}
        </Card>
    );

    React.useEffect(() => {
        const wrapperEl = document.createElement("div");

        wrapperEl.className = twMerge(
            "fixed z-[200000] bottom-10 right-10",
            "flex flex-col items-center justify-center",
            "twui-toast-root"
        );

        document.body.appendChild(wrapperEl);
        const root = createRoot(wrapperEl);
        root.render(toastEl);

        setTimeout(() => {
            closeToast({ wrapperEl });
            setOpen?.(false);
        }, closeDelay);

        return function () {
            closeToast({ wrapperEl });
        };
    }, []);

    return null;
}

function closeToast({ wrapperEl }: { wrapperEl: HTMLDivElement | null }) {
    if (!wrapperEl) return;
    wrapperEl.parentElement?.removeChild(wrapperEl);
}
