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

const badgeVariants = cva(
  "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
  {
    variants: {
      variant: {
        default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
        secondary:
          "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
        destructive:
          "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
        outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
);

const colorClassNames: Record<string, string> = {
  zinc: "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-100 border-transparent",
  red: "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400 border-transparent",
  orange:
    "bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-400 border-transparent",
  amber: "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400 border-transparent",
  yellow:
    "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400 border-transparent",
  lime: "bg-lime-100 text-lime-800 dark:bg-lime-900/30 dark:text-lime-400 border-transparent",
  green: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400 border-transparent",
  emerald:
    "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400 border-transparent",
  teal: "bg-teal-100 text-teal-800 dark:bg-teal-900/30 dark:text-teal-400 border-transparent",
  cyan: "bg-cyan-100 text-cyan-800 dark:bg-cyan-900/30 dark:text-cyan-400 border-transparent",
  sky: "bg-sky-100 text-sky-800 dark:bg-sky-900/30 dark:text-sky-400 border-transparent",
  blue: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400 border-transparent",
  indigo:
    "bg-indigo-100 text-indigo-800 dark:bg-indigo-900/30 dark:text-indigo-400 border-transparent",
  violet:
    "bg-violet-100 text-violet-800 dark:bg-violet-900/30 dark:text-violet-400 border-transparent",
  purple:
    "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400 border-transparent",
  fuchsia:
    "bg-fuchsia-100 text-fuchsia-800 dark:bg-fuchsia-900/30 dark:text-fuchsia-400 border-transparent",
  pink: "bg-pink-100 text-pink-800 dark:bg-pink-900/30 dark:text-pink-400 border-transparent",
  rose: "bg-rose-100 text-rose-800 dark:bg-rose-900/30 dark:text-rose-400 border-transparent",
  black: "bg-zinc-900 text-white dark:bg-white dark:text-zinc-900 border-transparent",
  white:
    "bg-white text-zinc-900 dark:bg-zinc-900 dark:text-white border-zinc-200 dark:border-zinc-700",
};

// Solid variant for colors
const solidColorClassNames: Record<string, string> = {
  zinc: "bg-zinc-700 text-white dark:bg-zinc-600 dark:text-white border-transparent",
  red: "bg-red-600 text-white dark:bg-red-700 dark:text-white border-transparent",
  orange: "bg-orange-600 text-white dark:bg-orange-700 dark:text-white border-transparent",
  amber: "bg-amber-600 text-white dark:bg-amber-700 dark:text-white border-transparent",
  yellow: "bg-yellow-600 text-white dark:bg-yellow-700 dark:text-white border-transparent",
  lime: "bg-lime-600 text-white dark:bg-lime-700 dark:text-white border-transparent",
  green: "bg-green-600 text-white dark:bg-green-700 dark:text-white border-transparent",
  emerald: "bg-emerald-600 text-white dark:bg-emerald-700 dark:text-white border-transparent",
  teal: "bg-teal-600 text-white dark:bg-teal-700 dark:text-white border-transparent",
  cyan: "bg-cyan-600 text-white dark:bg-cyan-700 dark:text-white border-transparent",
  sky: "bg-sky-600 text-white dark:bg-sky-700 dark:text-white border-transparent",
  blue: "bg-blue-600 text-white dark:bg-blue-700 dark:text-white border-transparent",
  indigo: "bg-indigo-600 text-white dark:bg-indigo-700 dark:text-white border-transparent",
  violet: "bg-violet-600 text-white dark:bg-violet-700 dark:text-white border-transparent",
  purple: "bg-purple-600 text-white dark:bg-purple-700 dark:text-white border-transparent",
  fuchsia: "bg-fuchsia-600 text-white dark:bg-fuchsia-700 dark:text-white border-transparent",
  pink: "bg-pink-600 text-white dark:bg-pink-700 dark:text-white border-transparent",
  rose: "bg-rose-600 text-white dark:bg-rose-700 dark:text-white border-transparent",
  black: "bg-zinc-950 text-white dark:bg-white dark:text-zinc-950 border-transparent",
  white: "bg-white text-zinc-950 dark:bg-zinc-100 dark:text-zinc-950 border-transparent",
};

export type BadgeColor = keyof typeof colorClassNames;

type BadgeVariantProp = "default" | "secondary" | "destructive" | "outline" | "solid";

function Badge({
  className,
  variant: variantProp,
  color,
  asChild = false,
  ...props
}: React.ComponentProps<"span"> & {
  variant?: BadgeVariantProp;
  color?: BadgeColor | string;
  asChild?: boolean;
}) {
  const Comp = asChild ? Slot : "span";

  // If color is provided, use color-based styling instead of variant
  if (color) {
    const isSolid = variantProp === "solid";
    const colorClass = isSolid
      ? solidColorClassNames[color] || colorClassNames[color]
      : colorClassNames[color];

    return (
      <Comp
        data-slot="badge"
        className={cn(
          "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none transition-colors overflow-hidden",
          colorClass,
          className
        )}
        {...props}
      />
    );
  }

  // Use the variant from badgeVariants (exclude "solid" which is only used with color)
  const badgeVariant =
    variantProp === "solid"
      ? "default"
      : (variantProp as "default" | "secondary" | "destructive" | "outline");

  return (
    <Comp
      data-slot="badge"
      className={cn(badgeVariants({ variant: badgeVariant }), className)}
      {...props}
    />
  );
}

export { Badge, badgeVariants };
