import type { JSX } from "solid-js";
import { splitProps } from "solid-js";
import { createControllableSignal } from "../../primitives/create-controllable-signal";
import { SliderContextProvider, type SliderContextValue } from "./slider-context";

/** Props for the Slider root component. */
export interface SliderRootProps extends JSX.HTMLAttributes<HTMLDivElement> {
  /** Controlled value. */
  value?: number;
  /** Initial value (uncontrolled). Defaults to min. */
  defaultValue?: number;
  /** Called when the value changes. */
  onValueChange?: ((value: number) => void) | undefined;
  /** @default 0 */
  min?: number;
  /** @default 100 */
  max?: number;
  /** @default 1 */
  step?: number;
  /** @default "horizontal" */
  orientation?: "horizontal" | "vertical";
  disabled?: boolean;
  children: JSX.Element;
}

/**
 * Root container for the Slider component. Manages the current value.
 */
export function SliderRoot(props: SliderRootProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "value",
    "defaultValue",
    "onValueChange",
    "min",
    "max",
    "step",
    "orientation",
    "disabled",
    "children",
  ]);

  const min = () => local.min ?? 0;
  const max = () => local.max ?? 100;
  const step = () => local.step ?? 1;

  const [sliderValue, setSliderValue] = createControllableSignal<number>({
    value: () => local.value,
    defaultValue: () => local.defaultValue ?? min(),
    onChange: (v) => {
      if (v !== undefined) local.onValueChange?.(v);
    },
  });

  const clamp = (v: number) => Math.min(max(), Math.max(min(), v));

  const ctx: SliderContextValue = {
    value: sliderValue,
    setValue: (v) => setSliderValue(clamp(v)),
    min,
    max,
    step,
    orientation: () => local.orientation ?? "horizontal",
    disabled: () => local.disabled ?? false,
  };

  return (
    <SliderContextProvider value={ctx}>
      <div
        data-orientation={local.orientation ?? "horizontal"}
        data-disabled={local.disabled || undefined}
        {...rest}
      >
        {local.children}
      </div>
    </SliderContextProvider>
  );
}
