import { forwardRef } from "react";

import { cn } from "../lib/cn";
import { cva, type VariantProps } from "../lib/cva";
import { createDataAttributes, createSlot } from "../lib/contracts";

const spinnerVariants = cva(
  [
    "inline-block rounded-full border-current border-r-transparent align-middle",
    "animate-spin motion-reduce:animate-none"
  ],
  {
    variants: {
      size: {
        sm: "size-3 border-[1.5px]",
        md: "size-4 border-2",
        lg: "size-5 border-2"
      },
      tone: {
        default: "text-[var(--color-muted-foreground)]",
        current: "text-current",
        primary: "text-[var(--color-primary)]"
      }
    },
    defaultVariants: {
      size: "md",
      tone: "current"
    }
  }
);

export type SpinnerProps = React.ComponentPropsWithoutRef<"span"> &
  VariantProps<typeof spinnerVariants>;

export const Spinner = forwardRef<HTMLSpanElement, SpinnerProps>(function Spinner(
  {
    className,
    size = "md",
    tone = "current",
    ...props
  },
  ref
) {
  return (
    <span
      {...props}
      {...createSlot("icon")}
      {...createDataAttributes({
        size,
        tone
      })}
      aria-hidden={props["aria-label"] ? undefined : true}
      className={cn(spinnerVariants({ size, tone }), className)}
      ref={ref}
    />
  );
});
