// packages/core/src/components/number-field/number-field-root.tsx
import type { JSX } from "solid-js";
import { createUniqueId, splitProps } from "solid-js";
import { createControllableSignal } from "../../primitives/create-controllable-signal";
import { createRegisterId } from "../../primitives/create-register-id";
import {
  NumberFieldContextProvider,
  type NumberFieldContextValue,
} from "./number-field-context";

export interface NumberFieldRootProps extends JSX.HTMLAttributes<HTMLDivElement> {
  /** Controlled value. */
  value?: number | undefined;
  /** Default value when uncontrolled. @default 0 */
  defaultValue?: number | undefined;
  /** Called when the value changes. */
  onValueChange?: ((value: number) => void) | undefined;
  /** Minimum allowed value. */
  min?: number | undefined;
  /** Maximum allowed value. */
  max?: number | undefined;
  /** Step amount for increment/decrement. @default 1 */
  step?: number | undefined;
  /** Whether the field is disabled. */
  disabled?: boolean | undefined;
  /** Child elements. */
  children: JSX.Element;
}

/**
 * Root container for NumberField. Provides context with value, min/max/step, and increment/decrement.
 */
export function NumberFieldRoot(props: NumberFieldRootProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "value",
    "defaultValue",
    "onValueChange",
    "min",
    "max",
    "step",
    "disabled",
    "children",
  ]);

  const inputId = createUniqueId();
  const [descriptionId, setDescriptionId] = createRegisterId();
  const [errorMessageId, setErrorMessageId] = createRegisterId();

  const [value, setValue] = createControllableSignal<number>({
    value: () => local.value,
    defaultValue: () => local.defaultValue ?? 0,
    onChange: local.onValueChange,
  });

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

  const increment = () => {
    const next = value() + step();
    const maxVal = max();
    if (maxVal !== undefined && next > maxVal) return;
    setValue(next);
  };

  const decrement = () => {
    const next = value() - step();
    const minVal = min();
    if (minVal !== undefined && next < minVal) return;
    setValue(next);
  };

  const ctx: NumberFieldContextValue = {
    value,
    setValue,
    inputId: () => inputId,
    descriptionId,
    errorMessageId,
    min,
    max,
    step,
    disabled: () => local.disabled ?? false,
    increment,
    decrement,
    setDescriptionId,
    setErrorMessageId,
  };

  return (
    <NumberFieldContextProvider value={ctx}>
      <div
        data-disabled={local.disabled || undefined}
        {...rest}
      >
        {local.children}
      </div>
    </NumberFieldContextProvider>
  );
}
