import { BITree } from '../../common/utils/src';
import { ComponentPublicInstance } from 'vue';
import { ComputedRef } from 'vue';
import { MaybeRef } from 'vue';
import { noop } from '../../common/utils/src';
import { OffsetOptions } from '@floating-ui/dom';
import { Placement } from '@floating-ui/dom';
import { Ref } from 'vue';
import { RendererElement } from 'vue';
import { RendererNode } from 'vue';
import { ShiftOptions } from '@floating-ui/dom';
import { Slots } from 'vue';
import { VirtualElement } from '@floating-ui/dom';
import { VNode } from 'vue';
import { VNodeChild } from 'vue';
import { VNodeNormalizedChildren } from 'vue';
import { watch } from 'vue';
import { WatchHandle } from 'vue';

export declare function addActiveThemes(themes: (string | InitThemeOptions)[]): void;

declare type Behavior = ScrollToOptions['behavior'];

export declare const CLICK_OUTSIDE = "clickoutside";

export declare function createSlotRender(slots: Slots, names: string[]): ((params?: any) => VNodeChild) | null;

export declare function createSlotRender(slots: Slots, names: string[], fallback: (params?: any) => VNodeChild): (params?: any) => VNodeChild;

declare type Data = Record<string, any>;

export declare function flatVNodes(children: VNodeNormalizedChildren): VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>[];

export declare interface InitThemeOptions {
    name: string;
    rootClass?: string;
    varsClass?: string;
}

export declare type IntersectionHandler = (entry: IntersectionObserverEntry) => any;

export declare function isHiddenElement(el?: HTMLElement | null): boolean;

declare type Key = number | string | symbol;

export declare type MaybeElement = HTMLElement | SVGElement | undefined | null;

export declare type MaybeInstance = MaybeElement | ComponentPublicInstance;

export { MaybeRef }

export declare type MaybeRefRecord<T> = {
    [K in keyof T]: MaybeRef<T[K]>;
};

export declare type ModifierState = Readonly<Omit<Record<string, boolean>, 'activeKeys'> & {
    activeKeys: Set<string>;
    resetAll: () => void;
}>;

export declare interface MovingState {
    xStart: number;
    yStart: number;
    xEnd: number;
    yEnd: number;
    clientX: number;
    clientY: number;
    deltaX: number;
    deltaY: number;
    lazy: boolean;
    [custom: string]: unknown;
}

export declare function observeResize(el: Element, handler: ResizeHandler): void;

export declare function pickToRefs<T extends Record<any, any>, K extends keyof T>(reactive: T, keys: K[]): { [P in K]: Ref<T[P]>; };

export { Placement }

export declare const placementWhileList: readonly Placement[];

export declare function proxyExposed<T>(vnode: VNode): T;

export declare function queryOutsideHiddenElement(el?: Element | null): HTMLElement | null;

export declare type ResizeHandler = (entry: ResizeInfo) => any;

export declare interface ResizeInfo extends ResizeObserverEntry {
    offsetWidth: number;
    offsetHeight: number;
    width: number;
    height: number;
}

export declare function setActiveThemes(themes: (string | InitThemeOptions)[]): void;

export declare function unobserveResize(el: Element): void;

export declare function unrefElement<T extends string | MaybeInstance = string | MaybeInstance>(ref: MaybeRef<T>): T extends string | ComponentPublicInstance ? MaybeElement : T;

/**
 * 创建一个可以添加 clickoutside 事件的元素 Ref
 *
 * @param handler 事件的回调方法
 * @param target 需要处理的元素 ref，可不传
 */
export declare function useClickOutside(handler: () => void, target?: Ref<HTMLElement | null | undefined>): Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;

/**
 * 创建一个观察了最近的上级元素 display 变化的元素 Ref
 *
 * @param displayInit 元素初次显示后执行的回调
 * @returns 观察了 display 变化的元素 Ref
 */
export declare function useDisplay(displayInit?: typeof noop, element?: Ref<HTMLElement | null | undefined>): Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;

export declare function useFullScreen(target?: MaybeRef<MaybeInstance>): UseFullScreenResult;

export declare interface UseFullScreenResult {
    target: Ref<MaybeInstance>;
    supported: boolean;
    full: ComputedRef<boolean>;
    enter: (force?: boolean) => Promise<boolean>;
    exit: (force?: boolean) => Promise<boolean>;
    toggle: (force?: boolean) => Promise<boolean>;
}

export declare function useHover(wrapper?: Ref<HTMLElement | null | undefined>): {
    wrapper: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
    isHover: Ref<boolean, boolean>;
};

export declare function useIntersection(options: UseIntersectionOptions): {
    target: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
    disconnect: typeof noop;
};

export declare type UseIntersectionOptions = IntersectionObserverInit & {
    /**
     * 元素交叉状态变化时的回调方法
     */
    handler: IntersectionHandler;
    /**
     * 作用的目标元素的 Ref
     */
    target?: Ref<HTMLElement | null | undefined>;
};

export declare function useListener<E = Event>(target: MaybeRef<EventTarget | null | undefined>, event: string, listener: (event: E) => any, options?: UseListenerOptions | boolean): typeof noop;

export declare interface UseListenerOptions extends AddEventListenerOptions {
    /**
     * 是否禁用整个 hook 的事件处理
     */
    disabled?: MaybeRef<boolean>;
}

export declare function useManualRef(): {
    updateSet: Set<() => void>;
    manualRef: <T>(value: T) => Ref<T, T>;
    triggerUpdate: () => void;
};

export declare function useModifier(options?: UseModifierOptions): {
    target: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
    modifier: ModifierState;
};

export declare interface UseModifierOptions {
    /**
     * 作用的目标元素的 Ref
     */
    target?: Ref<HTMLElement | null | undefined>;
    /**
     * 是否禁用整个 hook 的事件处理
     */
    disabled?: MaybeRef<boolean>;
    /**
     * 配置键名的别名，会与默认别名动态合并
     */
    aliasMap?: Record<string, string>;
    /**
     * 是否在目标元素失去焦点时重置修饰符
     *
     * @default true
     */
    autoReset?: boolean;
    /**
     * 事件的 capture 选项
     *
     * @default false
     */
    capture?: boolean;
    /**
     * 事件的 passive 选项
     *
     * @default true
     */
    passive?: boolean;
    /**
     * 是否严格匹配目标元素
     */
    strictTarget?: boolean;
    /**
     * 键按下的事件回调函数
     */
    onKeyDown?: (event: KeyboardEvent, modifier: ModifierState) => void;
    /**
     * 键抬起的时间回调函数
     */
    onKeyUp?: (event: KeyboardEvent, modifier: ModifierState) => void;
}

export declare function useMounted(wait?: 'tick' | 'frame'): {
    isMounted: Readonly<Ref<boolean, boolean>>;
};

export declare function useMoving(options: UseMovingOptions): {
    target: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
    moving: ComputedRef<boolean>;
    x: Ref<number, number>;
    y: Ref<number, number>;
    lazy: Ref<boolean, boolean>;
    disabled: Ref<boolean, boolean>;
};

export declare interface UseMovingOptions {
    /**
     * 作用的目标元素的 Ref
     */
    target?: Ref<HTMLElement | null | undefined>;
    /**
     * 横向位置的初始值
     */
    x?: MaybeRef<number>;
    /**
     * 纵向位置的初始值
     */
    y?: MaybeRef<number>;
    /**
     * 为否为懒加载，开启后会在 End 事件再更新位置状态
     */
    lazy?: MaybeRef<boolean>;
    /**
     * 是否禁用整个 hook 的事件处理
     */
    disabled?: MaybeRef<boolean>;
    /**
     * 事件的 capture 选项
     *
     * @default true
     */
    capture?: boolean;
    /**
     * 是否阻止 MouseDown 事件冒泡和默认行为
     *
     * @default true
     */
    stopMouse?: boolean;
    /**
     * 是否阻止 TouchStart 事件冒泡和默认行为
     *
     * @default true
     */
    stopTouch?: boolean;
    /**
     * 移动开始时的回调函数，返回 false 可以阻止本次移动
     */
    onStart?: (state: MovingState, event: PointerEvent) => any;
    /**
     * 移动中的回调函数
     */
    onMove?: (state: MovingState, event: PointerEvent) => void;
    /**
     * 移动结束时的回调函数
     */
    onEnd?: (state: MovingState, event: PointerEvent) => void;
}

export declare function usePointer(options?: UsePointerOption): {
    unregister: () => void;
    x: Ref<number, number>;
    y: Ref<number, number>;
};

export declare interface UsePointerOption {
    /**
     * 横向位置的初始值
     */
    x?: number;
    /**
     * 纵向位置的初始值
     */
    y?: number;
    /**
     * 是否手动停止，默认情况下会在组件的 BeforeUnmount 生命周期注销
     *
     * @default false
     */
    manualStop?: boolean;
}

export declare function usePopper(initOptions: UsePopperOptions): {
    wrapper: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined> | undefined;
    reference: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
    popper: Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
    placement: Ref<Placement, Placement>;
    transferTo: Ref<string, string>;
    updatePopper: () => Promise<void>;
};

export declare interface UsePopperOptions {
    /**
     * popper 元素出现的位置
     */
    placement: MaybeRef<Placement>;
    /**
     * popper 元素需要迁移至的目标选择器，为 true 时会迁移至 body
     */
    transfer?: MaybeRef<boolean | string>;
    /**
     * 设置是否为从右向左的阅读方向
     */
    isRtl?: MaybeRef<boolean>;
    /**
     * 包围元素，用于判断 clickoutside 事件
     *
     * 即使 popper 元素迁移至 wrapper 元素外部，点击 popper 元素时仍认为处于 wrapper 元素内部
     */
    wrapper?: Ref<HTMLElement | null | undefined>;
    /**
     * 设置 popper 元素为否需要 drop，此时 transform-origin 会自动调整
     */
    isDrop?: MaybeRef<boolean>;
    /**
     * 参考元素，popper 元素的位置计算依据
     */
    reference?: Ref<HTMLElement | VirtualElement | null | undefined>;
    /**
     * popper 元素
     */
    popper?: Ref<HTMLElement | null | undefined>;
    /**
     * arrow 元素
     */
    arrow?: Ref<HTMLElement | null | undefined>;
    /**
     * popper 元素的偏移量，可传入一个回调函数
     */
    offset?: MaybeRef<number[] | OffsetOptions>;
    /**
     * popper 元素是否限制在窗口内
     */
    shift?: MaybeRef<boolean | ShiftOptions>;
    /**
     * 设置是否自动更新 popper 元素
     *
     * @default false
     */
    autoUpdate?: boolean;
}

/**
 * 获取用于记录 `requestAnimationFrame` 返回值的对象，记录的定时器会在作用域消除时自动清理
 */
export declare function useRaf(): {
    timer: Record<string, any>;
};

export declare function useResize(options?: UseResizeOptions): {
    /**
     * @deprecated Will be removed in next major version, please directly use `observeResize` from imports.
     */
    observeResize: typeof observeResize;
    /**
     * @deprecated Will be removed in next major version, please directly use `unobserveResize` from imports.
     */
    unobserveResize: typeof unobserveResize;
    unobserve: () => void;
};

export declare interface UseResizeOptions {
    /**
     * 作用的目标元素的 Ref
     */
    target?: MaybeRef<HTMLElement | null | undefined>;
    onResize?: ResizeHandler;
}

export declare function useRtl(): {
    isRtl: Ref<boolean, boolean>;
};

/**
 * 获取用于记录 `setInterval` 返回值的对象，记录的定时器会在作用域消除时自动清理
 */
export declare function useSetInterval(): {
    timer: Record<string, any>;
};

/**
 * 获取用于记录 `setTimeout` 返回值的对象，记录的定时器会在作用域消除时自动清理
 */
export declare function useSetTimeout(): {
    timer: Record<string, any>;
};

export declare function useTheme(wrapper?: MaybeElement): {
    theme: Ref<string | undefined, string | undefined>;
};

/**
 * 获取三个分别用于记录 `setTimeout`、`setInterval` 和 `requestAnimationFrame` 返回值的对象
 *
 * 记录在这些对象上的定时器将会在作用域消除时自动清理
 */
export declare function useTimerRecord(): {
    timeout: Record<string, any>;
    interval: Record<string, any>;
    raf: Record<string, any>;
};

export declare function useTriggerHandler(trigger: Ref<string>, currentVisible: Ref<boolean>, delay?: number): {
    handleTriggerEnter: () => void;
    handleTriggerLeave: () => void;
    handleTriggerClick: () => void;
};

export declare function useVirtual<T extends Data = Data>(options: VirtualOptions<T>): {
    wrapper: HTMLElement | Ref<HTMLElement | null | undefined, HTMLElement | null | undefined> | null;
    indexMap: ComputedRef<Map<Key, number>>;
    heightTree: ComputedRef<BITree>;
    startIndex: ComputedRef<number>;
    scrollOffset: Ref<number, number>;
    visibleItems: ComputedRef<T[]>;
    listStyle: ComputedRef<    {
    readonly height: string | undefined;
    readonly minHeight: string | undefined;
    readonly boxSizing: "content-box";
    }>;
    itemsStyle: ComputedRef<    {
    transform: string;
    }>;
    handleScroll: () => void;
    handleResize: (entry: ResizeObserverEntry) => void;
    handleItemResize: (key: Key, entry: ResizeObserverEntry) => void;
    scrollTo: (top: number, behavior?: Behavior) => void;
    scrollBy: (delta: number, behavior?: Behavior) => void;
    scrollToKey: (key: Key, behavior?: Behavior) => void;
    scrollToIndex: (index: number, behavior?: Behavior) => void;
    ensureIndexInView: (index: number, behavior?: Behavior) => void;
    ensureKeyInView: (key: Key, behavior?: Behavior) => void;
};

export { VirtualElement }

export declare interface VirtualOptions<T extends Data> {
    /**
     * 虚拟滚动的元素
     */
    items: MaybeRef<T[]>;
    /**
     * 设置元素的最小高度
     */
    itemSize: MaybeRef<number>;
    /**
     * 设置元素是否为固定高度，固定高度时不处理 resize
     */
    itemFixed: MaybeRef<boolean>;
    /**
     * 元素的主键
     */
    idKey: MaybeRef<keyof T>;
    /**
     * 默认停留在的元素的主键，未实现
     */
    defaultKeyAt?: Key;
    /**
     * 设置前后的缓冲元素的个数
     */
    bufferSize?: MaybeRef<number>;
    /**
     * 虚拟滚动的包围元素
     */
    wrapper?: MaybeRef<HTMLElement | null | undefined>;
    /**
     * 是否自动观察 wrapper 缩放
     *
     * @default true
     */
    autoResize?: boolean;
}

export declare function watchPauseable(...args: Parameters<typeof watch>): {
    active: Readonly<Ref<boolean, boolean>>;
    pause: () => void;
    resume: () => void;
    stop: WatchHandle;
};

export { }
