import * as React from 'react';
import * as SliderPrimitive from '@radix-ui/react-slider';

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

/**
 * The reward editor's control (spec §9). Track 6px on surface-3, range in the
 * text green (`accent-fg` equals `accent` in dark and is the only green that
 * reads on paper), a 20px square-ish thumb with a 2px green edge and no
 * shadow. The thumb element itself is a 44px square around the 20px knob, so
 * the slider handle a phone measures is fingertip-sized and not the knob; the
 * root's `py-3` keeps the row the same 44px band either side of it.
 *
 * "Physical" is the hover/active pair: the thumb tints on hover, grows a
 * little under the pointer, and swaps to a grabbing cursor. Nothing here
 * animates layout — `transform` only, clamped by the reduced-motion block.
 *
 * One thumb per value, not one hard-coded thumb: the editor drives this with
 * a single weight today and a range tomorrow, and a single-thumb slider fed a
 * two-value array silently drops the second value.
 */
function Slider({
  className,
  value,
  defaultValue,
  ...props
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
  const thumbCount = (value ?? defaultValue ?? [0]).length;
  return (
    <SliderPrimitive.Root
      className={cn(
        'group relative flex w-full cursor-pointer touch-none select-none items-center py-3 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',
        className,
      )}
      {...(value === undefined ? {} : { value })}
      {...(defaultValue === undefined ? {} : { defaultValue })}
      {...props}
    >
      <SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-surface-3">
        <SliderPrimitive.Range className="absolute h-full bg-accent-fg" />
      </SliderPrimitive.Track>
      {Array.from({ length: thumbCount }, (_, i) => (
        // The focusable thumb is a 44px square (the `role="slider"` element a
        // finger actually lands on); the visible 20px knob is a child. Radix
        // centres the thumb with a -50% translate, so the larger box changes
        // nothing about where the knob sits. The hover/active growth and the
        // focus ring are drawn on the knob, not on the invisible square.
        <SliderPrimitive.Thumb
          key={i}
          className="group/thumb flex size-11 cursor-grab items-center justify-center focus-visible:outline-none active:cursor-grabbing disabled:pointer-events-none"
        >
          <span
            aria-hidden="true"
            className="block size-5 rounded-md border-2 border-accent-fg bg-surface transition-[transform,background-color] duration-1 ease-enter group-hover/thumb:scale-110 group-hover/thumb:bg-accent-subtle group-focus-visible/thumb:ring-2 group-focus-visible/thumb:ring-ring group-focus-visible/thumb:ring-offset-2 group-focus-visible/thumb:ring-offset-bg group-active/thumb:scale-110 group-active/thumb:bg-accent-subtle"
          />
        </SliderPrimitive.Thumb>
      ))}
    </SliderPrimitive.Root>
  );
}

export { Slider };
