import type { JSX } from "solid-js";
import { createUniqueId, splitProps } from "solid-js";
import { createListNavigation } from "../../primitives/create-list-navigation";
import { ListboxContextProvider } from "./listbox-context";

export interface ListboxRootProps extends JSX.HTMLAttributes<HTMLDivElement> {
  /** Ordered list of active (non-disabled) item values. */
  items: string[];
  /** Controlled selected value (single selection). */
  value?: string;
  /** Initial selected value (uncontrolled). */
  defaultValue?: string;
  /** Called when selection changes (single). */
  onValueChange?: (value: string) => void;
  /** Selection mode. @default "single" */
  selectionMode?: "single" | "multiple";
  /** Controlled selected values (multiple selection). */
  values?: string[];
  /** Initial selected values (uncontrolled, multiple). */
  defaultValues?: string[];
  /** Called when selection changes (multiple). */
  onValuesChange?: (values: string[]) => void;
  /** @default "vertical" */
  orientation?: "vertical" | "horizontal";
  /** Wrap at boundaries. @default true */
  loop?: boolean;
  /** Resolve value to display label for typeahead. */
  getLabel?: (value: string) => string;
  /** Whether the listbox is disabled. */
  disabled?: boolean;
  children: JSX.Element;
}

/**
 * A list of selectable options. Supports single and multiple selection,
 * keyboard navigation, and typeahead search.
 */
export function ListboxRoot(props: ListboxRootProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "items",
    "value",
    "defaultValue",
    "onValueChange",
    "selectionMode",
    "values",
    "defaultValues",
    "onValuesChange",
    "orientation",
    "loop",
    "getLabel",
    "disabled",
    "children",
  ]);

  const baseId = createUniqueId();
  const isMultiple = () => local.selectionMode === "multiple";

  const navigation = createListNavigation({
    items: () => local.items,
    mode: "selection",
    orientation: local.orientation,
    loop: local.loop,
    value: local.value !== undefined ? () => local.value : undefined,
    defaultValue: local.defaultValue,
    onValueChange: local.onValueChange,
    multiple: isMultiple(),
    values: local.values !== undefined ? () => local.values ?? [] : undefined,
    defaultValues: local.defaultValues,
    onValuesChange: local.onValuesChange,
    getLabel: local.getLabel,
    baseId,
  });

  return (
    <ListboxContextProvider value={{ navigation }}>
      <div
        tabIndex={local.disabled ? -1 : 0}
        aria-disabled={local.disabled || undefined}
        aria-multiselectable={isMultiple() ? "true" : undefined}
        data-disabled={local.disabled || undefined}
        {...navigation.containerProps}
        {...rest}
      >
        {local.children}
      </div>
    </ListboxContextProvider>
  );
}
