import { ReactNode, ComponentType } from 'react';

type TreeItemId = string;
/** A single node in the consumer's tree data. Generic over your payload. */
interface TreeNode<T = unknown> {
    id: TreeItemId;
    data: T;
    /** Inline children. Omit (and provide a `loadChildren`) for async loading. */
    children?: TreeNode<T>[];
    /**
     * Set to `true` to mark a node as a folder even when its `children` array
     * is empty (e.g. an unloaded async folder). Default: derived from
     * `Array.isArray(children)`.
     */
    isFolder?: boolean;
    /** Disable interaction. */
    disabled?: boolean;
}
/**
 * Internal flat-row representation used by the renderer + keyboard nav.
 * Produced by `flattenTree`; consumed by `TreeRow`, the keyboard hook,
 * and the type-ahead hook.
 */
interface FlatRow<T> {
    node: TreeNode<T>;
    level: number;
    parentId: TreeItemId | null;
    isFolder: boolean;
    isExpanded: boolean;
    isLoading: boolean;
    hasError: boolean;
    /** 1-based position among visible siblings (for `aria-posinset`). */
    posInSet: number;
    /** Count of visible siblings sharing this row's parent (for `aria-setsize`). */
    setSize: number;
}

interface TreeRowRenderProps<T> {
    node: TreeNode<T>;
    level: number;
    isSelected: boolean;
    isExpanded: boolean;
    isFocused: boolean;
    isFolder: boolean;
    isLoading: boolean;
    isMatchingSearch: boolean;
}
type TreeRowSlot<T> = (props: TreeRowRenderProps<T>) => ReactNode;
type TreeContextMenuSlot<T> = (props: TreeRowRenderProps<T>, trigger: ReactNode) => ReactNode;
/**
 * Declarative context-menu item. Pass `'separator'` (string) in place of an
 * object to insert a `<ContextMenuSeparator />` between groups.
 *
 * For more advanced needs (submenus, checkbox items, custom JSX), drop down
 * to `renderContextMenu` instead.
 */
interface TreeContextMenuAction<T> {
    /** Stable React key. */
    id: string;
    label: ReactNode;
    /** Lucide-style icon component. Rendered as `<icon className="size-4" />`. */
    icon?: ComponentType<{
        className?: string;
    }>;
    /** Right-aligned keyboard hint (e.g. `'⌘C'`, `'↵'`). Cosmetic. */
    shortcut?: ReactNode;
    /** Disable the item — still rendered, not selectable. */
    disabled?: boolean;
    /** Style as destructive (red). */
    destructive?: boolean;
    /** Click / Enter handler. Receives the row meta. */
    onSelect: (props: TreeRowRenderProps<T>) => void;
}
type TreeContextMenuItem<T> = TreeContextMenuAction<T> | 'separator';
/**
 * Context passed to a `contextMenuActions` resolver. `row` is the row the
 * user right-clicked. `selectedNodes` is the multi-selection at the
 * moment the menu opens — when the right-clicked row was not in the
 * selection, Tree first switches selection to that single row, so
 * `selectedNodes` always contains the right-clicked node.
 */
interface TreeContextMenuActionsContext<T> extends TreeRowRenderProps<T> {
    /** Multi-selection at the moment the menu opens. Always non-empty. */
    selectedNodes: TreeNode<T>[];
}
type TreeContextMenuActionsResolver<T> = (ctx: TreeContextMenuActionsContext<T>) => TreeContextMenuItem<T>[] | null | undefined;

export type { FlatRow as F, TreeNode as T, TreeItemId as a, TreeRowSlot as b, TreeContextMenuSlot as c, TreeContextMenuActionsResolver as d, TreeRowRenderProps as e, TreeContextMenuItem as f, TreeContextMenuAction as g, TreeContextMenuActionsContext as h };
