import { ChangeEvent } from 'react';
import { default as default_2 } from 'react';
import { DragEndEvent } from '@dnd-kit/core';
import { MutableRefObject } from 'react';
import { RefObject } from 'react';

declare interface CheckboxOptions {
    label: string;
    value: string;
}

/**
 * Hook that manages column visibility state with localStorage persistence
 * and returns a pre-configured DataTableColumnFilterDropdown component.
 *
 * @example
 * ```tsx
 * const columns = [
 *   { label: 'Name', value: 'name' },
 *   { label: 'Email', value: 'email' },
 *   { label: 'Status', value: 'status' }
 * ]
 *
 * const { visibleColumns, toggleColumn, resetColumns } = useColumnFilter({
 *   storageKey: 'users-table-columns',
 *   columns,
 *   defaultVisibleColumns: ['name', 'email']
 * })
 *
 * return (
 *   <div>
 *      <DataTable.ColumnFilter
 *        columns={columns}
 *        visibleColumns={visibleColumns}
 *        onCheckedChange={toggleColumn}
 *        onReset={resetColumns}
 *       />
 *     <DataTable columns={columns} visibleColumns={visibleColumns} />
 *   </div>
 * )
 * ```
 */
export declare function useColumnFilter({ storageKey, columns, defaultVisibleColumns }: UseColumnFilterProps): UseColumnFilterReturn;

declare interface UseColumnFilterProps {
    /**
     * Unique key for localStorage persistence
     */
    storageKey: string;
    /**
     * Available columns configuration
     */
    columns: CheckboxOptions[];
    /**
     * Default visible columns (used when no localStorage value exists)
     */
    defaultVisibleColumns?: string[];
}

declare interface UseColumnFilterReturn {
    /**
     * Currently visible column identifiers
     */
    visibleColumns: string[];
    /**
     * Toggle visibility of a specific column
     */
    toggleColumn: (columnName: string, checked: boolean) => void;
    /**
     * Reset to default visible columns
     */
    resetColumns: () => void;
}

export declare function useCommonFilter(): {
    query: string | undefined;
    handleSearch: (event: React.ChangeEvent<HTMLInputElement>) => void;
};

export declare const useDebounceSearch: ({ handleChangeSearchValue, searchValue }: UseDebounceSearchProps) => {
    handleResetSearch: () => void;
    handleSearchChange: (e: ChangeEvent<HTMLInputElement>) => void;
    handleStringSearchChange: (value: string) => void;
    search: string;
};

export declare interface UseDebounceSearchProps {
    handleChangeSearchValue?: (data: string) => void;
    searchValue?: string;
}

/**
 * Accepts a function that contains imperative, possibly effectful code.
 *
 * This is the deepCompare version of the `React.useEffect` hooks (that is shallowed compare)
 *
 * @param effect Imperative function that can return a cleanup function
 * @param deps If present, effect will only activate if the values in the list change.
 *
 * @see https://gist.github.com/kentcdodds/fb8540a05c43faf636dd68647747b074#gistcomment-2830503
 */
export declare function useDeepCompareEffect(effect: default_2.EffectCallback, deps: default_2.DependencyList): void;

/**
 * Accepts a function that contains imperative, possibly effectful code.
 *
 * This is the deepCompare version of the `React.useMemo` hooks (that is shallowed compare)
 *
 * @param effect Imperative function that can return a useMemo value
 * @param deps If present, effect will only activate if the values in the list change.
 *
 * @see https://gist.github.com/kentcdodds/fb8540a05c43faf636dd68647747b074#gistcomment-2830503
 */
export declare function useDeepCompareMemo<T>(effect: () => T, deps: default_2.DependencyList): T;

export declare namespace useDragAndDrop {
    export {
        useDragAndDrop_2 as default
    }
}

/**
 * Hook for handling drag and drop functionality
 * Provides utilities for managing draggable items in a list
 *
 * @template T - Type of items being dragged
 * @param items - Array of draggable items
 * @param onReorder - Callback function to handle reordering of items
 *
 * @returns {Object} Object containing:
 *   - handleDragEnd: Function to handle the end of a drag operation
 *   - getItemId: Function to generate unique IDs for draggable items
 *
 * @example
 * ```tsx
 * const { handleDragEnd, getItemId } = useDragAndDrop({
 *   items: sortableItems,
 *   onReorder: handleReorder
 * })
 *
 * return (
 *   <DndContext onDragEnd={handleDragEnd}>
 *     <SortableContext items={items.map((_, index) => getItemId(index))}>
 *       {items.map((item, index) => (
 *         <SortableItem key={getItemId(index)} id={getItemId(index)} />
 *       ))}
 *     </SortableContext>
 *   </DndContext>
 * )
 * ```
 */
declare const useDragAndDrop_2: <T>({ items, onReorder }: UseDragAndDropProps<T>) => {
    handleDragEnd: (event: DragEndEvent) => void;
    getItemId: (index: number) => string;
};

declare interface UseDragAndDropProps<T> {
    items: T[];
    onReorder?: (items: T[]) => void;
}

/**
 * Hook for infinite scroll functionality using IntersectionObserver.
 * Triggers a callback when the sentinel element becomes visible in the viewport.
 *
 * @param options - Configuration options for infinite scroll behavior
 * @returns Object containing the sentinel ref to attach to a trigger element
 *
 * @example
 * ```tsx
 * function MyList() {
 *   const { data, fetchNextPage, hasNextPage, isFetching } = useInfiniteQuery(...)
 *
 *   const { sentinelRef } = useInfiniteScroll({
 *     onLoadMore: fetchNextPage,
 *     hasMore: hasNextPage ?? false,
 *     isLoading: isFetching,
 *     rootMargin: '200px'
 *   })
 *
 *   return (
 *     <ScrollArea>
 *       {data.pages.flat().map(item => <ListItem key={item.id} {...item} />)}
 *       <div ref={sentinelRef} />
 *     </ScrollArea>
 *   )
 * }
 * ```
 */
export declare function useInfiniteScroll({ onLoadMore, hasMore, isLoading, enabled, rootMargin, threshold }: UseInfiniteScrollOptions): UseInfiniteScrollReturn;

export declare interface UseInfiniteScrollOptions {
    /** Callback when sentinel becomes visible */
    onLoadMore: () => void | Promise<void>;
    /** Whether more items are available */
    hasMore: boolean;
    /** Prevents duplicate calls while loading */
    isLoading?: boolean;
    /** Enable/disable the hook */
    enabled?: boolean;
    /** Root margin for early triggering (default: "100px") */
    rootMargin?: string;
    /** Intersection threshold 0-1 (default: 0.1) */
    threshold?: number;
}

export declare interface UseInfiniteScrollReturn {
    /** Ref to attach to sentinel element at end of list */
    sentinelRef: React.RefObject<HTMLDivElement>;
}

export declare const useIsMounted: () => MutableRefObject<boolean>;

export declare function useLocalStorage<T>(key: UserPreference | string, initialValue: T): readonly [T, (value: T) => void];

/**
 * Hook to monitor memory usage and run cleanup when threshold is exceeded
 * Note: Memory monitoring only works in Chromium-based browsers
 * @param cleanupFn Function to run when memory threshold is exceeded
 * @param threshold Memory threshold in MB
 * @param interval Check interval in ms
 */
export declare const useMemoryCleanup: (cleanupFn: () => void, threshold?: number, interval?: number) => void;

/**
 * Hook for polling with smart tab visibility handling.
 * Automatically adjusts polling interval based on tab visibility and ensures
 * only one request is in flight at a time.
 *
 * @param callback - Promise-returning function to be called at each polling interval (e.g., refetch)
 * @param options - Polling configuration options
 * @returns boolean - true if currently polling, false otherwise
 *
 * @example
 * ```tsx
 * function MyComponent() {
 *   const { refetch } = useQuery(...)
 *
 *   const isPolling = usePolling(refetch, {
 *     startPolling: true,
 *     pollingInterval: 10000, // 10 seconds
 *     pollOnInactiveTab: false
 *   })
 *
 *   return <div>{isPolling ? 'Polling...' : 'Idle'}</div>
 * }
 * ```
 *
 * @remarks
 * - Remembers last call and re-polls only after it's resolved
 * - Automatically pauses polling when tab is inactive (unless pollOnInactiveTab is true)
 * - Uses longer interval for inactive tabs to reduce resource usage
 */
export declare function usePolling(callback: () => Promise<void> | undefined, { startPolling, pollingInterval, inactiveTabPollingInterval, pollOnInactiveTab }: UsePollingOptions): boolean;

export declare interface UsePollingOptions {
    /**
     * Polling interval in milliseconds when tab is active
     * @default 30000 (30 seconds)
     */
    pollingInterval?: number;
    /**
     * Start polling based on a condition
     * @example Poll only on first page
     * @default false
     */
    startPolling?: boolean;
    /**
     * Polling interval in milliseconds when tab is inactive
     * @default 60000 (60 seconds)
     */
    inactiveTabPollingInterval?: number;
    /**
     * Enable polling even on inactive tabs with inactiveTabPollingInterval
     * Use with caution - needs a stop condition from userland
     * @default false
     */
    pollOnInactiveTab?: boolean;
}

export declare function useResizeObserver<T extends Element>(ref: RefObject<T>, callback: (element: T) => void, throttleMs?: number): void;

export declare enum UserPreference {
    SPACE_ID = "spaceId",
    SIDEBAR_WIDTH = "sidebarWidth",
    CURRENT_USER = "currentUser",
    DIFF_VIEW_STYLE = "DIFF_VIEW_STYLE",
    PULL_REQUEST_CREATION_OPTION = "PULL_REQUEST_CREATION_OPTION",
    PULL_REQUEST_ACTIVITY_FILTER = "PULL_REQUEST_ACTIVITY_FILTER",
    PULL_REQUEST_ACTIVITY_ORDER = "PULL_REQUEST_ACTIVITY_ORDER"
}

/**
 * Hook to detect if the current browser tab is visible or hidden.
 * Uses the Page Visibility API to track tab visibility changes.
 *
 * @returns boolean - true if tab is visible, false if hidden
 *
 * @example
 * ```tsx
 * function MyComponent() {
 *   const isTabVisible = useTabVisible()
 *
 *   useEffect(() => {
 *     if (isTabVisible) {
 *       // Resume operations when tab becomes visible
 *     } else {
 *       // Pause operations when tab is hidden
 *     }
 *   }, [isTabVisible])
 * }
 * ```
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
 */
export declare function useTabVisible(): boolean;

export { }
