"use client"

import * as React from 'react';

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

import { useStoredValue, type StorageType, type UseStoredValueOptions } from '../../../hooks';
import { cn } from '../../../lib/utils';

export interface SliderProps extends React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> {
  /**
   * When provided, the slider value is persisted under this key.
   * Works with both controlled (`value`) and uncontrolled (`defaultValue`) modes.
   * @example storageKey="volume-level"
   */
  storageKey?: string
  /** @default 'local' */
  storageType?: StorageType
  /** TTL in ms */
  storageTtl?: number
}

const Slider = React.forwardRef<
  React.ElementRef<typeof SliderPrimitive.Root>,
  SliderProps
>(({ className, orientation = 'horizontal', storageKey, storageType, storageTtl, onValueChange, ...props }, ref) => {
  const isVertical = orientation === 'vertical';

  const storageOptions: UseStoredValueOptions | undefined =
    storageKey ? { storage: storageType ?? 'local', ttl: storageTtl } : undefined;

  const [storedValue, setStoredValue] = useStoredValue<number[]>(
    storageKey,
    (props.defaultValue as number[] | undefined) ?? (props.value as number[] | undefined) ?? [],
    storageOptions,
  );

  const handleValueChange = React.useCallback(
    (newValue: number[]) => {
      if (storageKey) setStoredValue(newValue);
      onValueChange?.(newValue);
    },
    [storageKey, setStoredValue, onValueChange],
  );

  const sliderProps = {
    ...props,
    onValueChange: storageKey ? handleValueChange : onValueChange,
    // Inject stored defaultValue only in uncontrolled mode
    ...(storageKey && props.value === undefined && storedValue.length > 0
      ? { defaultValue: storedValue }
      : {}),
  };

  return (
    <SliderPrimitive.Root
      ref={ref}
      orientation={orientation}
      className={cn(
        "relative flex touch-none select-none",
        isVertical
          ? "flex-col items-center"
          : "flex-row items-center w-full",
        className
      )}
      {...sliderProps}
    >
      <SliderPrimitive.Track
        className={cn(
          "relative overflow-hidden rounded-full bg-primary/20",
          isVertical ? "w-1.5 h-full grow" : "h-1.5 w-full grow"
        )}
      >
        <SliderPrimitive.Range
          className={cn(
            "absolute bg-primary",
            isVertical ? "w-full bottom-0" : "h-full left-0"
          )}
        />
      </SliderPrimitive.Track>
      <SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
    </SliderPrimitive.Root>
  );
})
Slider.displayName = SliderPrimitive.Root.displayName

export { Slider }
