import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";

import { cn } from "@/lib/utils";

const badgeVariants = cva(
  [
    "inline-flex items-center justify-center gap-1.5",
    "rounded-full border font-medium",
    "px-2.5 py-0.5 text-xs",
    "whitespace-nowrap shrink-0",
    "transition-all duration-200 ease-in-out",
    "select-none",
    "[&>svg]:size-3 [&>svg]:pointer-events-none",
  ].join(" "),
  {
    variants: {
      variant: {
        default:
          "border-transparent bg-primary text-primary-foreground hover:bg-primary/90",

        secondary:
          "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",

        destructive:
          "border-transparent bg-red-500 text-white hover:bg-red-600",

        outline: "border-border bg-transparent text-foreground hover:bg-accent",

        success:
          "border-transparent bg-green-500 text-white hover:bg-green-600",

        warning:
          "border-transparent bg-yellow-500 text-white hover:bg-yellow-600",

        info: "border-transparent bg-blue-500 text-white hover:bg-blue-600",

        softSuccess:
          "border-transparent bg-green-100 text-green-700 hover:bg-green-200",

        softWarning:
          "border-transparent bg-yellow-100 text-yellow-700 hover:bg-yellow-200",

        softDestructive:
          "border-transparent bg-red-100 text-red-700 hover:bg-red-200",

        softInfo:
          "border-transparent bg-blue-100 text-blue-700 hover:bg-blue-200",
      },

      size: {
        sm: "px-2 py-0.5 text-xs",
        md: "px-2.5 py-0.5 text-xs",
        lg: "px-3 py-1 text-sm",
      },
    },

    defaultVariants: {
      variant: "default",
      size: "md",
    },
  }
);

export interface BadgeProps
  extends React.ComponentProps<"span">, VariantProps<typeof badgeVariants> {
  asChild?: boolean;
  dot?: boolean;
}

function Badge({
  className,
  variant,
  size,
  asChild = false,
  dot = false,
  children,
  ...props
}: BadgeProps) {
  const Comp = asChild ? Slot : "span";

  return (
    <Comp
      className={cn(badgeVariants({ variant, size }), className)}
      {...props}
    >
      {dot && (
        <span
          className={cn("w-1.5 h-1.5 rounded-full", {
            "bg-green-500": variant?.includes("success"),
            "bg-red-500": variant?.includes("destructive"),
            "bg-yellow-500": variant?.includes("warning"),
            "bg-blue-500": variant?.includes("info"),
            "bg-gray-400": !variant,
          })}
        />
      )}

      {children}
    </Comp>
  );
}

export { Badge, badgeVariants };
