import type { Entity, FilteredEntity } from "./types";
import type EntityManager from "./entity-manager";
/**
 * Definition for a reactive query with enter/exit callbacks
 */
export interface ReactiveQueryDefinition<ComponentTypes extends Record<string, any>, WithComponents extends keyof ComponentTypes = keyof ComponentTypes, WithoutComponents extends keyof ComponentTypes = never, OptionalComponents extends keyof ComponentTypes = never> {
    /** Components the entity must have */
    with: ReadonlyArray<WithComponents>;
    /** Components the entity must not have */
    without?: ReadonlyArray<WithoutComponents>;
    /** Components to include in the entity type but not require for matching */
    optional?: ReadonlyArray<OptionalComponents>;
    /** Components the entity's direct parent must have */
    parentHas?: ReadonlyArray<keyof ComponentTypes>;
    /** Called when an entity starts matching the query */
    onEnter?: (entity: FilteredEntity<ComponentTypes, WithComponents, WithoutComponents, OptionalComponents>) => void;
    /** Called when an entity stops matching the query (receives just the ID since entity may be gone) */
    onExit?: (entityId: number) => void;
}
/**
 * Manages reactive queries that trigger callbacks when entities enter/exit query matches
 */
export default class ReactiveQueryManager<ComponentTypes extends Record<string, any>, QueryNames extends string = string> {
    private queries;
    private entityManager;
    /** Whether any registered query uses parentHas */
    private _hasParentHasQueries;
    constructor(entityManager: EntityManager<ComponentTypes>);
    /**
     * Whether any registered reactive query uses parentHas filters
     */
    get hasParentHasQueries(): boolean;
    /**
     * Add a reactive query
     * @param name Unique name for the query
     * @param definition Query definition with callbacks
     */
    addQuery<WithComponents extends keyof ComponentTypes, WithoutComponents extends keyof ComponentTypes = never, OptionalComponents extends keyof ComponentTypes = never>(name: QueryNames, definition: ReactiveQueryDefinition<ComponentTypes, WithComponents, WithoutComponents, OptionalComponents>): void;
    /**
     * Remove a reactive query
     * @param name Name of the query to remove
     * @returns true if the query existed and was removed
     */
    removeQuery(name: QueryNames): boolean;
    private entityMatchesQuery;
    /**
     * Apply enter/exit transitions for a single query against an entity.
     * Fires onEnter when entity starts matching, onExit when it stops.
     */
    private _applyQueryTransition;
    /**
     * Called when a component is added to an entity
     * Checks all queries for potential enter/exit events
     */
    onComponentAdded(entity: Entity<ComponentTypes>, _componentName: keyof ComponentTypes): void;
    /**
     * Called when a component is removed from an entity
     * Checks all queries for potential enter/exit events
     */
    onComponentRemoved(entity: Entity<ComponentTypes>, _componentName: keyof ComponentTypes): void;
    /**
     * Called when an entity is removed
     * Triggers onExit for all queries the entity was matching
     */
    onEntityRemoved(entityId: number): void;
    /**
     * Recheck an entity against all queries (used after batch component additions)
     * Fires enter/exit callbacks as appropriate based on current state vs tracked state
     */
    recheckEntity(entity: Entity<ComponentTypes>): void;
    /**
     * Recheck an entity and its children against all queries.
     * Used after component mutations to handle both the entity's own queries
     * and parentHas queries on its children.
     */
    recheckEntityAndChildren(entity: Entity<ComponentTypes>): void;
    /**
     * Recheck all children of a parent entity against parentHas queries.
     * Called when a component is added/removed from a parent entity.
     */
    private _recheckChildren;
    /**
     * Recalculate the _hasParentHasQueries flag from all registered queries
     */
    private _recalcParentHasFlag;
}
