import {
    AnchorHTMLAttributes,
    ButtonHTMLAttributes,
    DetailedHTMLProps,
    HTMLAttributeAnchorTarget,
} from "react";
import { twMerge } from "tailwind-merge";
import Loading from "../elements/Loading";

/**
 * # Buttons
 * @className twui-button-general
 * @className twui-button-content-wrapper
 * @className twui-button-primary
 * @className twui-button-primary-outlined
 * @className twui-button-primary-ghost
 * @className twui-button-secondary
 * @className twui-button-secondary-outlined
 * @className twui-button-secondary-ghost
 * @className twui-button-accent
 * @className twui-button-accent-outlined
 * @className twui-button-accent-ghost
 * @className twui-button-gray
 * @className twui-button-gray-outlined
 * @className twui-button-gray-ghost
 */
export default function Button({
    href,
    target,
    variant,
    color,
    linkProps,
    loading,
    ...props
}: DetailedHTMLProps<
    ButtonHTMLAttributes<HTMLButtonElement>,
    HTMLButtonElement
> & {
    variant?: "normal" | "ghost" | "outlined";
    color?: "primary" | "secondary" | "accent" | "gray";
    href?: string;
    target?: HTMLAttributeAnchorTarget;
    loading?: boolean;
    linkProps?: DetailedHTMLProps<
        AnchorHTMLAttributes<HTMLAnchorElement>,
        HTMLAnchorElement
    >;
}) {
    const finalClassName: string = (() => {
        if (variant == "normal" || !variant) {
            if (color == "primary" || !color)
                return twMerge(
                    "bg-blue-500 hover:bg-blue-600 text-white",
                    "twui-button-primary"
                );
            if (color == "secondary")
                return twMerge(
                    "bg-emerald-500 hover:bg-emerald-600 text-white",
                    "twui-button-secondary"
                );
            if (color == "accent")
                return twMerge(
                    "bg-violet-500 hover:bg-violet-600 text-white",
                    "twui-button-accent"
                );
            if (color == "gray")
                return twMerge(
                    "bg-slate-300 hover:bg-slate-200 text-slate-800",
                    "twui-button-gray"
                );
        } else if (variant == "outlined") {
            if (color == "primary" || !color)
                return twMerge(
                    "bg-transparent outline outline-1 outline-blue-500",
                    "text-blue-500",
                    "twui-button-primary-outlined"
                );
            if (color == "secondary")
                return twMerge(
                    "bg-transparent outline outline-1 outline-emerald-500",
                    "text-emerald-500",
                    "twui-button-secondary-outlined"
                );
            if (color == "accent")
                return twMerge(
                    "bg-transparent outline outline-1 outline-violet-500",
                    "text-violet-500",
                    "twui-button-accent-outlined"
                );
            if (color == "gray")
                return twMerge(
                    "bg-transparent outline outline-1 outline-slate-300",
                    "text-slate-600",
                    "twui-button-gray-outlined"
                );
        } else if (variant == "ghost") {
            if (color == "primary" || !color)
                return twMerge(
                    "bg-transparent outline-none p-2",
                    "text-blue-500",
                    "twui-button-primary-ghost"
                );
            if (color == "secondary")
                return twMerge(
                    "bg-transparent outline-none p-2",
                    "text-emerald-500",
                    "twui-button-secondary-ghost"
                );
            if (color == "accent")
                return twMerge(
                    "bg-transparent outline-none p-2",
                    "text-violet-500",
                    "twui-button-accent-ghost"
                );
            if (color == "gray")
                return twMerge(
                    "bg-transparent outline-none p-2",
                    "text-slate-600",
                    "twui-button-gray-ghost"
                );
        }

        return "";
    })();

    const buttonComponent = (
        <button
            {...props}
            className={twMerge(
                "bg-blue-600 text-white text-base font-medium px-4 py-2 rounded",
                "flex items-center justify-center relative transition-all",
                "twui-button-general",
                finalClassName,
                props.className,
                loading ? "pointer-events-none opacity-80" : "l"
            )}
        >
            <div
                className={twMerge(
                    "flex items-center gap-2",
                    loading ? "opacity-0" : "",
                    "twui-button-content-wrapper"
                )}
            >
                {props.children}
            </div>
            {loading && <Loading className="absolute" />}
        </button>
    );

    if (href)
        return (
            <a {...linkProps} href={href} target={target}>
                {buttonComponent}
            </a>
        );
    return buttonComponent;
}
