// packages/core/src/components/command-palette/command-palette-root.tsx
import type { JSX } from "solid-js";
import { createMemo, createSignal, splitProps } from "solid-js";
import { createControllableSignal } from "../../primitives/create-controllable-signal";
import { createListNavigation } from "../../primitives/create-list-navigation";
import { CommandPaletteContextProvider } from "./command-palette-context";
import type { RegisteredItem } from "./command-palette-context";
import type { CommandPaletteRootProps } from "./command-palette.props";

/**
 * Root component for CommandPalette. Manages search state, item registration,
 * filtering, and keyboard navigation via context.
 */
export function CommandPaletteRoot(props: CommandPaletteRootProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "value",
    "defaultValue",
    "search",
    "defaultSearch",
    "loop",
    "filter",
    "onValueChange",
    "onSearchChange",
    "onSelect",
    "children",
  ]);

  void rest;

  const [allItems, setAllItems] = createSignal<RegisteredItem[]>([]);

  const [searchValue, setSearchInternal] = createControllableSignal<string>({
    value: () => local.search,
    defaultValue: () => local.defaultSearch ?? "",
    onChange: (v) => local.onSearchChange?.(v),
  });

  const filterEnabled = () => local.filter !== false;

  const filteredItems = createMemo<RegisteredItem[]>(() => {
    if (!filterEnabled()) return allItems();
    const query = searchValue().toLowerCase();
    if (!query) return allItems();
    return allItems().filter((item) => {
      const text = item.value.toLowerCase();
      const keywords = item.keywords?.join(" ").toLowerCase() ?? "";
      return text.includes(query) || keywords.includes(query);
    });
  });

  const navigation = createListNavigation({
    items: () => filteredItems().map((i) => i.value),
    mode: "activation",
    loop: local.loop !== false,
    onActivate: (value) => {
      local.onSelect?.(value);
      local.onValueChange?.(value);
    },
  });

  /** Register an item into the root's collection. */
  function registerItem(item: RegisteredItem): void {
    setAllItems((prev) => {
      if (prev.some((i) => i.value === item.value)) return prev;
      return [...prev, item];
    });
  }

  /** Unregister an item from the root's collection. */
  function unregisterItem(value: string): void {
    setAllItems((prev) => prev.filter((i) => i.value !== value));
  }

  /** Handle activation from item click or keyboard Enter. */
  function onActivate(value: string): void {
    local.onSelect?.(value);
    local.onValueChange?.(value);
  }

  /** Update the search string. */
  function setSearch(value: string): void {
    setSearchInternal(value);
  }

  return (
    <CommandPaletteContextProvider
      value={{
        searchValue,
        setSearch,
        filteredItems,
        registerItem,
        unregisterItem,
        onActivate,
        navigation,
      }}
    >
      {local.children}
    </CommandPaletteContextProvider>
  );
}
