import { type ReactElement, useState, type ComponentProps } from "react";
import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
import { cn } from "@/lib/utils";

/**
 * Switch — shadcn/WealthX
 * Base: npx shadcn\@latest add switch (latest)
 * Figma: Design-System---shadcn?node-id=3041-6197
 *
 * WealthX additions: aria-invalid error state, SwitchCard with position variants.
 * Tokens: unchecked=input, checked=primary, error=destructive, thumb=background.
 */
export type SwitchProps = ComponentProps<typeof SwitchPrimitive.Root> & {
  size?: "sm" | "default";
};

function Switch({
  className,
  size = "default",
  ...props
}: SwitchProps): ReactElement {
  return (
    <SwitchPrimitive.Root
      className={cn(
        "peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none",
        "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
        "disabled:cursor-not-allowed disabled:opacity-50",
        "data-[size=default]:h-[1.15rem] data-[size=default]:w-8",
        "data-[size=sm]:h-3.5 data-[size=sm]:w-6",
        "data-checked:bg-primary data-unchecked:bg-input",
        "aria-invalid:data-checked:bg-destructive aria-invalid:border-destructive",
        "dark:data-unchecked:bg-input/80",
        className,
      )}
      data-size={size}
      data-slot="switch"
      {...props}
    >
      <SwitchPrimitive.Thumb
        className={cn(
          "pointer-events-none block rounded-full bg-background ring-0 transition-transform",
          "group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3",
          "data-checked:translate-x-[calc(100%-2px)] data-unchecked:translate-x-0",
          "dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground",
        )}
        data-slot="switch-thumb"
      />
    </SwitchPrimitive.Root>
  );
}

/**
 * SwitchCard -- card wrapper with label + description + switch toggle.
 * Figma: SwitchCard (3041:6237)
 */
export type SwitchCardProps = Omit<
  ComponentProps<typeof SwitchPrimitive.Root>,
  "children"
> & {
  label: string;
  description?: string;
  error?: boolean;
  switchPosition?: "left" | "right";
  size?: "sm" | "default";
};

function SwitchCard({
  className,
  checked,
  defaultChecked,
  onCheckedChange,
  disabled,
  error,
  label,
  description,
  switchPosition = "right",
  size,
  ...props
}: SwitchCardProps): ReactElement {
  const [internalChecked, setInternalChecked] = useState(
    defaultChecked ?? false,
  );
  const isChecked = checked ?? internalChecked;

  const switchElement = (
    <Switch
      aria-invalid={error || undefined}
      checked={isChecked as boolean}
      className="shrink-0"
      disabled={disabled}
      onCheckedChange={(value, event) => {
        setInternalChecked(value);
        onCheckedChange?.(value, event);
      }}
      size={size}
      {...props}
    />
  );

  const contentElement = (
    <div className="flex flex-col gap-1">
      <span className="text-sm font-medium leading-none">{label}</span>
      {description ? (
        <span className="text-body-small text-muted-foreground">
          {description}
        </span>
      ) : null}
    </div>
  );

  return (
    <label
      className={cn(
        "flex items-center gap-3 border border-border p-4 font-sans transition-colors cursor-pointer",
        switchPosition === "right" && "justify-between",
        disabled && "cursor-not-allowed opacity-50",
        error
          ? ["border-destructive", isChecked && "bg-destructive/5"]
          : isChecked && "border-primary bg-primary/5",
        className,
      )}
      data-slot="switch-card"
    >
      {switchPosition === "left" ? (
        <>
          {switchElement}
          {contentElement}
        </>
      ) : (
        <>
          {contentElement}
          {switchElement}
        </>
      )}
    </label>
  );
}

export { Switch, SwitchCard };
