"use client";

import type { VariantProps } from "@karma/cva";
import { cva, cx } from "@karma/cva";
import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as React from "react";

const switchVariants = cva({
  base: "focus-visible:ring-ring peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
  variants: {
    variant: {
      accent:
        "data-[state=checked]:bg-accent data-[state=unchecked]:bg-accent-secondary",
      primary:
        "data-[state=checked]:bg-background-invert data-[state=unchecked]:bg-background",
      outline:
        "data-[state=unchecked]:bg-input border-2 border-accent data-[state=checked]:bg-accent",
      muted: "data-[state=unchecked]:bg-input data-[state=checked]:bg-muted",
    },
    size: {
      medium: "h-[1.5rem] w-[2.75rem]",
      small: "h-[1.25rem] w-[2.25rem]",
      large: "h-[1.75rem] w-[3.25rem]",
    },
  },
  defaultVariants: {
    variant: "primary",
    size: "medium",
  },
});

export type SwitchProps = React.ComponentPropsWithoutRef<
  typeof SwitchPrimitives.Root
> &
  VariantProps<typeof switchVariants> & {
    icon?: React.ReactNode;
    thumbClassName?: string;
  };

export const Switch = React.forwardRef<
  React.ElementRef<typeof SwitchPrimitives.Root>,
  SwitchProps
>(
  (
    { className, variant, icon, size = "medium", thumbClassName, ...props },
    ref,
  ) => (
    <SwitchPrimitives.Root
      className={cx(switchVariants({ variant, size }), className)}
      {...props}
      ref={ref}
    >
      <SwitchPrimitives.Thumb
        className={cx(
          "pointer-events-none flex items-center justify-center rounded-full bg-background-invert shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0 data-[state=checked]:bg-background data-[state=unchecked]:bg-background-invert",
          {
            "h-5 w-5 data-[state=checked]:translate-x-5": size === "medium",
            "h-4 w-4 data-[state=checked]:translate-x-4": size === "small",
            "h-6 w-6 data-[state=checked]:translate-x-6": size === "large",
          },
          thumbClassName,
        )}
      >
        {icon}
      </SwitchPrimitives.Thumb>
    </SwitchPrimitives.Root>
  ),
);

Switch.displayName = SwitchPrimitives.Root.displayName;
