import EntityManager from "./entity-manager";
import EventBus from "./event-bus";
import ResourceManager from "./resource-manager";
import type { FilteredEntity } from "./types";
import type Bundle from "./bundle";
/**
    * Type helper to detect conflicting types between two record types.
    * Returns a union of keys that exist in both T and U but have incompatible types.
*/
type GetConflictingKeys<T, U> = {
    [K in keyof T & keyof U]: T[K] extends U[K] ? U[K] extends T[K] ? never : K : K;
}[keyof T & keyof U];
/**
    * Simplified type helper to check bundle type compatibility.
    * Returns true if bundles can be merged without type conflicts.
*/
type BundlesAreCompatible<C1 extends Record<string, any>, C2 extends Record<string, any>, E1 extends Record<string, any>, E2 extends Record<string, any>, R1 extends Record<string, any>, R2 extends Record<string, any>> = [
    keyof C1
] extends [never] ? [keyof E1] extends [never] ? [keyof R1] extends [never] ? true : GetConflictingKeys<R1, R2> extends never ? true : false : GetConflictingKeys<E1, E2> extends never ? GetConflictingKeys<R1, R2> extends never ? true : false : false : GetConflictingKeys<C1, C2> extends never ? GetConflictingKeys<E1, E2> extends never ? GetConflictingKeys<R1, R2> extends never ? true : false : false : false;
/**
    * Interface declaration for ECSpresso constructor to ensure type augmentation works properly.
    * This merges with the class declaration below.
*/
export default interface ECSpresso<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}> {
    /**
        * Default constructor
    */
    new (): ECSpresso<ComponentTypes, EventTypes, ResourceTypes>;
}
/**
    * ECSpresso is the central ECS framework class that connects all features.
    * It handles creation and management of entities, components, and systems, and provides lifecycle hooks.
*/
export default class ECSpresso<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}> {
    /** Library version*/
    static readonly VERSION: string;
    /** Access/modify stored components and entities*/
    private _entityManager;
    /** Publish/subscribe to events*/
    private _eventBus;
    /** Access/modify registered resources*/
    private _resourceManager;
    /** Registered systems that will be updated in order*/
    private _systems;
    /** Cached sorted systems for efficient updates */
    private _sortedSystems;
    /** Track installed bundles to prevent duplicates*/
    private _installedBundles;
    /**
        * Creates a new ECSpresso instance.
    */
    constructor();
    /**
        * Creates a new ECSpresso builder for type-safe bundle installation.
        * This is the preferred way to create an ECSpresso instance with bundles.
     *
        * @returns A builder instance for fluent method chaining
     *
        * @example
        * ```typescript
        * const ecs = ECSpresso.create<BaseComponents, BaseEvents, BaseResources>()
     *	 .withBundle(bundle1)
     *	 .withBundle(bundle2)
     *	 .build();
        * ```
    */
    static create<C extends Record<string, any> = {}, E extends Record<string, any> = {}, R extends Record<string, any> = {}>(): ECSpressoBuilder<C, E, R>;
    /**
        * Adds a system directly to this ECSpresso instance
        * @param label Unique name to identify the system
        * @returns A SystemBuilder instance for method chaining
    */
    addSystem(label: string): import("./system-builder").SystemBuilderWithEcspresso<ComponentTypes, EventTypes, ResourceTypes, {}>;
    /**
        * Update all systems, passing deltaTime and query results to each system's process function
        * @param deltaTime Time elapsed since the last update (in seconds)
    */
    update(deltaTime: number): void;
    /**
     * Initialize all resources and systems
     * This method:
     * 1. Initializes all resources that were added as factory functions
     * 2. Calls the onInitialize lifecycle hook on all systems
     *
     * This is useful for game startup to ensure all resources are ready
     * and systems are properly initialized before the game loop begins.
     *
     * @param resourceKeys Optional array of specific resource keys to initialize
     * @returns Promise that resolves when everything is initialized
     */
    initialize(): Promise<void>;
    /**
     * Initialize specific resources or all resources that were added as factory functions but haven't been initialized yet.
     * This is useful when you need to ensure resources are ready before proceeding.
     * @param keys Optional array of resource keys to initialize. If not provided, all pending resources will be initialized.
     * @returns Promise that resolves when the specified resources are initialized
     */
    initializeResources<K extends keyof ResourceTypes>(...keys: K[]): Promise<void>;
    /**
        * Sort the systems array by priority (higher priority first)
        * Called internally when system list changes
        * @private
    */
    private _sortSystems;
    /**
        * Update the priority of a system
        * @param label The unique label of the system to update
        * @param priority The new priority value (higher values execute first)
        * @returns true if the system was found and updated, false otherwise
    */
    updateSystemPriority(label: string, priority: number): boolean;
    /**
        * Remove a system by its label
        * Calls the system's onDetach method with this ECSpresso instance if defined
        * @param label The unique label of the system to remove
        * @returns true if the system was found and removed, false otherwise
    */
    removeSystem(label: string): boolean;
    /**
        * Check if a resource exists
    */
    hasResource<K extends keyof ResourceTypes>(key: K): boolean;
    /**
        * Get a resource if it exists, or undefined if not
    */
    getResource<K extends keyof ResourceTypes>(key: K): ResourceTypes[K];
    /**
        * Add a resource to the ECS instance
    */
    addResource<K extends keyof ResourceTypes>(key: K, resource: ResourceTypes[K] | ((ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes>) => ResourceTypes[K] | Promise<ResourceTypes[K]>)): this;
    /**
        * Check if an entity has a component
    */
    hasComponent<K extends keyof ComponentTypes>(entityId: number, componentName: K): boolean;
    /**
        * Get all entities with specific components
    */
    getEntitiesWithComponents<WithComponents extends keyof ComponentTypes, WithoutComponents extends keyof ComponentTypes = never>(withComponents: ReadonlyArray<WithComponents>, withoutComponents?: ReadonlyArray<WithoutComponents>): Array<FilteredEntity<ComponentTypes, WithComponents, WithoutComponents>>;
    /**
        * Get all installed bundle IDs
    */
    get installedBundles(): string[];
    get entityManager(): EntityManager<ComponentTypes>;
    get eventBus(): EventBus<EventTypes>;
    get resourceManager(): ResourceManager<ResourceTypes>;
    /**
        * Internal method to install a bundle into this ECSpresso instance.
        * Called by the ECSpressoBuilder during the build process.
        * The type safety is guaranteed by the builder's type system.
    */
    _installBundle<C extends Record<string, any>, E extends Record<string, any>, R extends Record<string, any>>(bundle: Bundle<C, E, R>): this;
}
/**
    * Builder class for ECSpresso that provides fluent type-safe bundle installation.
    * Handles type checking during build process to ensure type safety.
*/
export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E extends Record<string, any> = {}, R extends Record<string, any> = {}> {
    /** The ECSpresso instance being built*/
    private ecspresso;
    constructor();
    /**
        * Add the first bundle when starting with empty types.
        * This overload allows any bundle to be added to an empty ECSpresso instance.
    */
    withBundle<BC extends Record<string, any>, BE extends Record<string, any>, BR extends Record<string, any>>(this: ECSpressoBuilder<{}, {}, {}>, bundle: Bundle<BC, BE, BR>): ECSpressoBuilder<BC, BE, BR>;
    /**
        * Add a subsequent bundle with type checking.
        * This overload enforces bundle type compatibility.
    */
    withBundle<BC extends Record<string, any>, BE extends Record<string, any>, BR extends Record<string, any>>(bundle: BundlesAreCompatible<C, BC, E, BE, R, BR> extends true ? Bundle<BC, BE, BR> : never): ECSpressoBuilder<C & BC, E & BE, R & BR>;
    /**
        * Complete the build process and return the built ECSpresso instance
    */
    build(): ECSpresso<C, E, R>;
}
export {};
