import { AnchorState } from "store/anchor/Anchor";
import { TAnchor, TAnchorId } from "../../components/canvas/anchors";
import { Block, TBlock } from "../../components/canvas/blocks/Block";
import { Graph } from "../../graph";
import { MultipleSelectionBucket } from "../../services/selection/MultipleSelectionBucket";
import { SingleSelectionBucket } from "../../services/selection/SingleSelectionBucket";
import { ESelectionStrategy } from "../../services/selection/types";
import { RootStore } from "../index";
import { BlockState, TBlockId } from "./Block";
/** Lightweight block bounds for the `blocks-geometry-change` event. */
export type TBlockGeometrySnapshot = {
    id: TBlockId;
    x: number;
    y: number;
    width: number;
    height: number;
};
declare module "../../graphEvents" {
    interface GraphEventsDefinitions {
        /**
         *
         * Emitted when selection of blocks changes.
         * Preventing the event will prevent selection change.
         *
         */
        "blocks-selection-change": (event: SelectionEvent<TBlockId>) => void;
        /**
         * Emitted when selection of block's anchor changes.
         * Preventing the event will prevent selection change.
         *
         */
        "block-anchor-selection-change": (event: CustomEvent<{
            /** Block anchor */
            anchor: TAnchor;
            /** Is anchor selected */
            selected: boolean;
        }>) => void;
        /**
         * Emitted when block position is about to update via {@link BlockListStore.updatePosition}.
         *
         * `detail.block` is a shallow snapshot (see {@link BlockState.asTBlockShallow}); do not mutate nested fields.
         * Preventing the event skips the store update and excludes the block from the next `blocks-geometry-change` batch.
         */
        "block-change": (event: CustomEvent<{
            /** Shallow snapshot; nested fields are shared with the store — read-only. */
            block: Readonly<TBlock>;
        }>) => void;
        /**
         * Coalesced geometry updates after {@link BlockListStore.updatePosition} (at most once per animation frame).
         * Payload is `{ id, x, y, width, height }` per block only.
         */
        "blocks-geometry-change": (event: CustomEvent<{
            blocks: TBlockGeometrySnapshot[];
        }>) => void;
    }
}
/**
 * Storage for managing blocks state
 */
export declare class BlockListStore {
    rootStore: RootStore;
    protected graph: Graph;
    $blocksMap: import("@preact/signals-core").Signal<Map<TBlockId, BlockState<TBlock>>>;
    $blocks: import("@preact/signals-core").Signal<BlockState<TBlock>[]>;
    private batchedGeometryPending;
    private batchedGeometryRaf;
    /**
     * This signal is used to store blocks in reactive state.
     * this signal fired for each change of the block state.
     *
     * NOTE: Please do not use it before you know what you are doing.
     */
    $blocksReactiveState: import("@preact/signals-core").ReadonlySignal<BlockState<TBlock>[]>;
    /**
     * Bucket for managing block selection state
     * Resolves IDs to BlockState instances (not GraphComponent)
     */
    readonly blockSelectionBucket: MultipleSelectionBucket<TBlockId, BlockState>;
    /**
     * Computed signal that returns selected blocks as Block GraphComponent instances
     * Automatically resolves BlockState to Block components via getViewComponent()
     * Use this when you need to work with rendered Block components
     */
    $selectedBlockComponents: import("@preact/signals-core").ReadonlySignal<Block<TBlock<{}>, import("../../components/canvas/blocks/Block").TBlockProps>[]>;
    readonly anchorSelectionBucket: SingleSelectionBucket<TAnchorId, AnchorState>;
    /**
     * @deprecated Use blockSelectionBucket.$selectedEntities instead
     * Computed signal that returns the currently selected blocks
     */
    $selectedBlocks: import("@preact/signals-core").ReadonlySignal<BlockState<TBlock>[]>;
    /**
     * @deprecated Use anchorSelectionBucket.$selectedEntities instead
     * Computed signal that returns the currently selected anchor
     */
    $selectedAnchor: import("@preact/signals-core").ReadonlySignal<AnchorState>;
    constructor(rootStore: RootStore, graph: Graph);
    /**
     * Sets anchor selection
     *
     * @param blockId {BlockState["id"]} Block id
     * @param anchorId {AnchorState["id"]} Anchor id
     * @param selected {boolean} Selected
     * @returns void
     */
    setAnchorSelection(blockId: BlockState["id"], anchorId: AnchorState["id"], selected: boolean): void;
    /**
     * Checks if a block is selected
     *
     * @param blockId {BlockState["id"]} Block id
     * @returns {boolean} Is selected
     */
    isSelectedBlock(blockId: BlockState["id"]): boolean;
    protected unsetAnchorsSelection(): void;
    /**
     * Updates block position
     *
     * @event block-change
     * @param id {BlockState["id"]} Block id
     * @param nextState {{x: number, y: number}} Next state
     * @returns void
     */
    updatePosition(id: BlockState["id"], nextState: Pick<TBlock, "x" | "y">): void;
    /**
     * Flushes pending `blocks-geometry-change` immediately (cancels a scheduled rAF if any).
     * Called when a graph drag ends so the last frame is not lost.
     */
    flushBatchedBlocksGeometryEmit(): void;
    private scheduleBatchedBlocksGeometryFlush;
    private clearGeometryRaf;
    private emitPendingBlocksGeometry;
    private cancelBatchedBlocksGeometry;
    protected updateBlocksMap(blocks: Map<BlockState["id"], BlockState> | [BlockState["id"], BlockState][]): void;
    /**
     * Adds block
     *
     * If a block with this id already exists, it will be updated.
     * If id is not provided, a random id will be generated.
     *
     * @param block {Omit<TBlock, "id"> & { id?: TBlockId }} Block to add
     * @returns void
     */
    addBlock(block: Omit<TBlock, "id"> & {
        id?: TBlockId;
    }): TBlockId;
    /**
     * Deletes blocks
     *
     * @param blocks {TBlock["id"] | TBlock} Blocks to delete
     * @returns void
     */
    deleteBlocks(blocks: (TBlock["id"] | TBlock)[]): void;
    /**
     * Updates blocks state
     *
     * If block with this id already exists, it will be updated.
     * Otherwise, a new block will be created.
     *
     * @param blocks {TBlock[]} Blocks to update
     * @returns void
     */
    updateBlocks(blocks: TBlock[]): void;
    /**
     * Sets blocks state
     *
     * @param blocks {TBlock[]} Blocks to set
     * @returns void
     */
    setBlocks(blocks: TBlock[]): void;
    protected getOrCraeateBlockState(block: TBlock): BlockState<TBlock>;
    protected applyBlocksState(blocks: BlockState[]): void;
    /**
     * Updates block selection using the SelectionService
     *
     * @param ids Block IDs to update selection for
     * @param selected Whether to select or deselect
     * @param strategy The selection strategy to apply
     *
     * @returns void
     */
    updateBlocksSelection(ids: TBlockId[], selected: boolean, strategy?: ESelectionStrategy): void;
    /**
     * Gets connections of a block
     *
     * Method search connection with source/target block id.
     * If you connect blocks via custom ports, this method will not work.
     *
     * @param blockId {TBlockId} Block id
     * @returns {ConnectionState[]} Connections
     */
    getBlockConnections(blockId: TBlockId): import("../..").ConnectionState<{
        id?: import("../..").TConnectionId;
        sourceBlockId?: TBlockId;
        targetBlockId?: TBlockId;
        sourceAnchorId?: string;
        targetAnchorId?: string;
        sourcePortId?: import("../..").TPortId;
        targetPortId?: import("../..").TPortId;
        label?: string;
        styles?: Partial<import("../../graphConfig").TConnectionColors> & {
            dashes?: number[];
        };
        dashed?: boolean;
        selected?: boolean;
    }>[];
    /**
     * Resets block selection
     *
     * @returns void
     */
    resetSelection(): void;
    /**
     * Deletes selected blocks
     *
     * @returns void
     */
    deleteSelectedBlocks(): void;
    /**
     * Deletes all connections of a block
     *
     * Method search connection with source/target block id.
     * If you connect blocks via custom ports, this method will not work.
     *
     * @param blockId {TBlockId} Block id
     * @returns void
     */
    deleteAllBlockConnections(blockId: TBlockId): void;
    reset(): void;
    /**
     * Gets blocks as JSON
     *
     * @returns {TBlock[]} Blocks
     */
    toJSON(): TBlock[];
    /**
     * Gets block state by id
     *
     * @param id {TBlockId} Block id
     * @returns {BlockState | undefined} Block state
     */
    getBlockState(id: TBlockId): BlockState<TBlock>;
    /**
     * Gets block by id
     *
     * @param id {TBlockId} Block id
     * @returns {TBlock | undefined} Block
     */
    getBlock(id: TBlockId): TBlock | undefined;
    /**
     * Gets blocks by ids
     *
     * If block with this id does not exist, it will filtered out.
     *
     * @param ids {BlockState["id"][]} Block ids
     * @returns {TBlock[]} Blocks
     */
    getBlocks(ids: BlockState["id"][]): TBlock[];
    /**
     * Gets block states by ids
     *
     * If block with this id does not exist, it will filtered out.
     *
     * @param ids {BlockState["id"][]} Block ids
     * @returns {BlockState[]} Block states
     */
    getBlockStates(ids: BlockState["id"][]): BlockState<TBlock>[];
}
