import { IKosModelContainer } from '../kos-container-model';
import { IKosDataModel } from '../kosModel';
type MaybePromise<T> = T | Promise<T>;
/**
 * Configuration options for the @kosContainerAware decorator.
 *
 * @template T The type of models contained in the container (must extend IKosDataModel)
 *
 * @kosService core.container-aware
 * @kosApiLevel 13
 */
export interface KosContainerAwareOptions<T extends IKosDataModel = IKosDataModel> {
    /**
     * Container property name on the model instance.
     *
     * @default "container"
     * @example
     * ```typescript
     * @kosContainerAware({ containerProperty: "devices" })
     * class DeviceContainer {
     *   // Access via: this.devices.addModel(...)
     * }
     * ```
     */
    containerProperty?: string;
    /**
     * Whether to include convenience methods (getModel, addModel, removeModel, addAll, removeAll,
     * removeAndDestroy, removeAndDestroyAll).
     *
     * @default true
     * @example
     * ```typescript
     * @kosContainerAware({ includeMethods: false })
     * class Container {
     *   // Only this.container property available, no convenience methods
     * }
     * ```
     */
    includeMethods?: boolean;
    /**
     * Whether to include reactive getters (models, data).
     *
     * @default true
     * @example
     * ```typescript
     * @kosContainerAware({ includeGetters: false })
     * class Container {
     *   // No this.models or this.data getters, use this.container.data directly
     * }
     * ```
     */
    includeGetters?: boolean;
    /**
     * Container-specific configuration options passed to KosModelContainer constructor.
     *
     * @example
     * ```typescript
     * @kosContainerAware({
     *   containerOptions: {
     *     sortKey: "name",
     *     indexMap: {
     *       byType: "deviceType",
     *       active: (device) => device.isOnline
     *     },
     *     parentId: "custom-parent", // Overrides automatic inference
     *     extensionId: "device-manager",
     *     maxCapacity: 1000,  // Safety net for unbounded growth
     *     evictionStrategy: "fifo"
     *   }
     * })
     * ```
     */
    containerOptions?: {
        /** Default property to sort models by */
        sortKey?: keyof T;
        /**
         * Index mapping for efficient queries. Keys are index names, values are either:
         * - Property names (string keys) for simple property-based indexing
         * - Functions that return index keys for complex logic
         *
         * @example
         * ```typescript
         * indexMap: {
         *   byStatus: "connectionStatus",                    // Property-based
         *   byType: (device) => device.type.toLowerCase(),  // Function-based
         *   needsUpdate: (device) => device.version < "2.0" // Boolean logic
         * }
         * ```
         */
        indexMap?: Record<string, keyof T | ((model: T) => MaybePromise<string | string[] | undefined>)>;
        /**
         * Parent model ID for the container. If not provided, automatically uses
         * the modelId parameter from the model's constructor.
         *
         * @default Inferred from constructor modelId parameter
         */
        parentId?: string;
        /** Extension identifier for the container */
        extensionId?: string;
        /**
         * SAFETY NET: Maximum number of models this container can hold.
         * When exceeded, models are automatically evicted and destroyed based on evictionStrategy.
         *
         * **Primary use case**: Prevent memory overflow when cleanup handlers are missing or
         * data becomes inconsistent. Set higher than normal usage to catch edge cases.
         *
         * @example
         * ```typescript
         * containerOptions: {
         *   maxCapacity: 10000,  // Safety net: expect ~100-1000 normally
         *   evictionStrategy: 'fifo'
         * }
         * ```
         */
        maxCapacity?: number;
        /**
         * Strategy for selecting which models to evict when maxCapacity is exceeded.
         *
         * - **fifo** (default): Remove oldest models first - best for event streams, logs
         * - **lru**: Remove least recently accessed models - best for caches
         * - **custom**: Use customEvictionFilter to determine eviction candidates
         *
         * @default 'fifo'
         */
        evictionStrategy?: "fifo" | "lru" | "custom";
        /**
         * Number of models to evict when maxCapacity is exceeded.
         * @default Math.max(10, Math.ceil(maxCapacity * 0.1))
         */
        evictionBatchSize?: number;
        /**
         * Custom filter function for 'custom' eviction strategy.
         * Should return models that are candidates for eviction.
         *
         * @example
         * ```typescript
         * customEvictionFilter: (models) => {
         *   return models.filter(m =>
         *     m.status === 'resolved' &&
         *     Date.now() - m.resolvedAt > 3600000
         *   );
         * }
         * ```
         */
        customEvictionFilter?: (models: T[]) => T[];
    };
    /**
     * Custom name for the reactive models array getter.
     *
     * @default "models"
     * @example
     * ```typescript
     * @kosContainerAware({ modelsProperty: "items" })
     * class Container {
     *   get items() { return this.container.data; } // Instead of 'models'
     * }
     * ```
     */
    modelsProperty?: string;
    /**
     * Legacy compatibility mode. Uses '_models' as the container property name
     * instead of 'container' for backward compatibility with existing code.
     *
     * @default false
     * @deprecated Use containerProperty instead for new code
     */
    legacy?: boolean;
}
/**
 * Interface for models using @kosContainerAware decorator.
 *
 * **IMPORTANT**: Use TypeScript interface merging to add container management properties to your model class.
 * This provides full type safety and IntelliSense support for all injected container functionality.
 *
 * ## Interface Merging Pattern
 *
 * ```typescript
 * // 1. Declare interface merging BEFORE the class
 * interface MyContainerModelImpl extends KosContainerAware<ItemModel> {}
 *
 * // 2. Apply decorator and implement the class
 * @kosModel("my-container-model")
 * @kosContainerAware<ItemModel>()
 * export class MyContainerModelImpl implements IKosDataModel {
 *   // All container properties are now available with full type safety
 * }
 * ```
 *
 * ## Custom Container Property Name
 *
 * When using a custom `containerProperty` name, use `KosContainerAwareWithProp`:
 *
 * ```typescript
 * // For custom container property name
 * interface DeviceManagerImpl extends KosContainerAwareWithProp<DeviceModel, "devices"> {}
 *
 * @kosContainerAware<DeviceModel>({ containerProperty: "devices" })
 * class DeviceManagerImpl implements IKosDataModel {
 *   // Access via: this.devices instead of this.container
 * }
 * ```
 *
 * ## Injected Properties and Methods
 *
 * The decorator automatically injects the following members (configurable via options):
 *
 * - **`container`**: Core KosModelContainer instance for direct access (or custom name via `containerProperty`)
 * - **`getModel(id)`**: Retrieve a model by ID from the container
 * - **`addModel(model)`**: Add a model to the container
 * - **`removeModel(id)`**: Remove a model from the container by ID (does not destroy)
 * - **`addAll(models)`**: Add multiple models to the container at once
 * - **`removeAll(ids)`**: Remove multiple models from the container by IDs (does not destroy)
 * - **`removeAndDestroy(id)`**: Remove a model from the container and destroy it
 * - **`removeAndDestroyAll(ids)`**: Remove multiple models from the container and destroy them
 * - **`models`**: Readonly KosModelContainer instance (compatible with IKosModelHolder)
 * - **`data`**: Reactive array of all model instances (compatible with IKosModelHolder)
 *
 * All injected getters are reactive and will automatically update UI components when container contents change.
 *
 * @template T The type of models contained in the container (must extend IKosDataModel)
 *
 * @example
 * ```typescript
 * // Basic usage with minimal configuration
 * interface DeviceContainerModelImpl extends KosContainerAware<DeviceModel> {}
 *
 * @kosModel("device-container-model")
 * @kosContainerAware<DeviceModel>()
 * class DeviceContainerModelImpl implements IKosDataModel {
 *   constructor(modelId: string, options: ContainerOptions, context: KosCreationContext) {
 *     this.id = modelId;
 *     // Container automatically injected with parentId: modelId
 *   }
 *
 *   // Use injected methods
 *   addDevice(device: DeviceModel): void {
 *     this.addModel(device); // Method injected by decorator
 *   }
 *
 *   // Use injected reactive getters
 *   get deviceCount(): number {
 *     return this.data.length; // Reactive array getter injected by decorator
 *   }
 * }
 * ```
 *
 * @example
 * ```typescript
 * // Advanced usage with indexing and custom configuration
 * interface UserContainerModelImpl extends KosContainerAware<UserModel> {}
 *
 * @kosModel("user-container-model")
 * @kosContainerAware<UserModel>({
 *   containerOptions: {
 *     indexMap: {
 *       byRole: "role",
 *       byDepartment: "department",
 *       active: (user) => user.status === "active"
 *     },
 *     sortKey: "lastName"
 *   }
 * })
 * class UserContainerModelImpl implements IKosDataModel {
 *   // Access indexed data via injected container
 *   getActiveUsers(): UserModel[] {
 *     return this.container.getIndexByKey("active", true);
 *   }
 *
 *   getUsersByRole(role: string): UserModel[] {
 *     return this.container.getIndexByKey("byRole", role);
 *   }
 * }
 * ```
 *
 * @see {@link kosContainerAware} - The decorator function
 * @see {@link KosContainerAwareOptions} - Configuration options
 *
 * @kosService core.container-aware
 * @kosApiLevel 13
 */
export interface KosContainerAware<T extends IKosDataModel = IKosDataModel> {
    /**
     * Core container that manages the collection of models.
     * Provides methods to add, remove, and query model instances.
     * Automatically injected by @kosContainerAware decorator.
     */
    container: IKosModelContainer<T>;
    /**
     * Retrieves a model from the container by its ID.
     * @param id - The unique identifier of the model to retrieve
     * @returns The model instance if found, undefined otherwise
     */
    getModel(id: string): T | undefined;
    /**
     * Adds a model to the container.
     * @param model - The model instance to add
     */
    addModel(model: T): void;
    /**
     * Removes a model from the container by its ID.
     * @param id - The unique identifier of the model to remove
     */
    removeModel(id: string): void;
    /**
     * Adds multiple models to the container at once.
     * @param models - Array of model instances to add
     * @kosApiLevel 19
     */
    addAll(models: T[]): void;
    /**
     * Removes multiple models from the container by their IDs.
     * @param ids - Array of unique identifiers of the models to remove
     * @kosApiLevel 19
     */
    removeAll(ids: string[]): void;
    /**
     * Removes a model from the container and destroys it.
     * Convenience method that combines removeModel() and destroyKosModel().
     * @param id - The unique identifier of the model to remove and destroy
     * @kosApiLevel 19
     */
    removeAndDestroy(id: string): Promise<void>;
    /**
     * Removes multiple models from the container and destroys them.
     * Convenience method that combines removeAll() and destroyKosModel().
     * @param ids - Array of unique identifiers of the models to remove and destroy
     * @kosApiLevel 19
     */
    removeAndDestroyAll(ids: string[]): Promise<void>;
    /**
     * The container instance managing the models.
     * Readonly property that provides access to the KosModelContainer.
     * Compatible with IKosModelHolder interface.
     * Updates automatically when models are added or removed.
     */
    readonly models: IKosModelContainer<T>;
    /**
     * Reactive array of all model instances in the container.
     * This is the actual array of models, compatible with IKosModelHolder interface.
     * Updates automatically when models are added or removed.
     */
    data: T[];
}
/**
 * Base interface providing common container-aware methods and properties.
 * Used internally by both KosContainerAware and KosContainerAwareWithProp.
 *
 * @template T The type of models contained in the container
 *
 * @kosService core.container-aware
 * @kosApiLevel 13
 */
export interface KosContainerAwareBase<T extends IKosDataModel = IKosDataModel> {
    /**
     * Retrieves a model from the container by its ID.
     * @param id - The unique identifier of the model to retrieve
     * @returns The model instance if found, undefined otherwise
     */
    getModel(id: string): T | undefined;
    /**
     * Adds a model to the container.
     * @param model - The model instance to add
     */
    addModel(model: T): void;
    /**
     * Removes a model from the container by its ID.
     * @param id - The unique identifier of the model to remove
     */
    removeModel(id: string): void;
    /**
     * Adds multiple models to the container at once.
     * @param models - Array of model instances to add
     * @kosApiLevel 19
     */
    addAll(models: T[]): void;
    /**
     * Removes multiple models from the container by their IDs.
     * @param ids - Array of unique identifiers of the models to remove
     * @kosApiLevel 19
     */
    removeAll(ids: string[]): void;
    /**
     * Removes a model from the container and destroys it.
     * Convenience method that combines removeModel() and destroyKosModel().
     * @param id - The unique identifier of the model to remove and destroy
     * @kosApiLevel 19
     */
    removeAndDestroy(id: string): Promise<void>;
    /**
     * Removes multiple models from the container and destroys them.
     * Convenience method that combines removeAll() and destroyKosModel().
     * @param ids - Array of unique identifiers of the models to remove and destroy
     * @kosApiLevel 19
     */
    removeAndDestroyAll(ids: string[]): Promise<void>;
    /**
     * The container instance managing the models.
     * Readonly property that provides access to the KosModelContainer.
     * Compatible with IKosModelHolder interface.
     * Updates automatically when models are added or removed.
     */
    readonly models: IKosModelContainer<T>;
    /**
     * Reactive array of all model instances in the container.
     * This is the actual array of models, compatible with IKosModelHolder interface.
     * Updates automatically when models are added or removed.
     */
    data: T[];
}
/**
 * Interface for models using @kosContainerAware decorator with a custom container property name.
 *
 * Use this interface when you specify a custom `containerProperty` in the decorator options
 * to get proper type safety for the custom property name.
 *
 * @template T The type of models contained in the container
 * @template P The custom property name for the container (string literal type)
 *
 * @example
 * ```typescript
 * // Specify the custom property name "devices" in both the interface and decorator
 * interface DeviceManagerImpl extends KosContainerAwareWithProp<DeviceModel, "devices"> {}
 *
 * @kosModel("device-manager")
 * @kosContainerAware<DeviceModel>({ containerProperty: "devices" })
 * class DeviceManagerImpl implements IKosDataModel {
 *   constructor(modelId: string, options: ContainerOptions, context: KosCreationContext) {
 *     this.id = modelId;
 *   }
 *
 *   addDevice(device: DeviceModel): void {
 *     // Access container via custom property name
 *     this.devices.addModel(device);
 *   }
 *
 *   getDeviceCount(): number {
 *     // The 'data' property is still available
 *     return this.data.length;
 *   }
 * }
 * ```
 *
 * @example
 * ```typescript
 * // Custom property for user management
 * interface UserManagerImpl extends KosContainerAwareWithProp<UserModel, "users"> {}
 *
 * @kosContainerAware<UserModel>({
 *   containerProperty: "users",
 *   containerOptions: {
 *     indexMap: {
 *       byRole: "role"
 *     }
 *   }
 * })
 * class UserManagerImpl implements IKosDataModel {
 *   getUsersByRole(role: string): UserModel[] {
 *     // Access via this.users instead of this.container
 *     return this.users.getIndexByKey("byRole", role);
 *   }
 * }
 * ```
 *
 * @kosService core.container-aware
 */
export type KosContainerAwareWithProp<T extends IKosDataModel = IKosDataModel, P extends string = "container"> = KosContainerAwareBase<T> & {
    [K in P]: IKosModelContainer<T>;
};
/**
 * Class decorator that automatically adds container management capabilities to a KOS model.
 *
 * This decorator eliminates the need for manual container setup by:
 * - **Adding a container property** (default: `container`) for managing model collections
 * - **Adding convenience methods** (`getModel`, `addModel`, `removeModel`, `addAll`, `removeAll`, `removeAndDestroy`, `removeAndDestroyAll`) if `includeMethods` is true (default)
 * - **Adding reactive getters** (`models`, `data`) if `includeGetters` is true (default)
 * - **Automatically inferring parentId** from the model's constructor `modelId` parameter
 * - **Registering container as @kosChild** for proper lifecycle management and cleanup
 * - **Supporting custom indexing** via `containerOptions.indexMap` for efficient queries
 *
 * ## Automatic Hierarchy Integration
 *
 * The decorator automatically registers the container as a `@kosChild`, ensuring:
 * - Proper lifecycle management (init, load, destroy)
 * - Automatic cleanup when parent model is destroyed
 * - Participation in the KOS reactive system
 * - Memory management and observer disposal
 *
 * ## TypeScript Usage
 *
 * **IMPORTANT**: Use TypeScript interface merging to get proper type information:
 *
 * ```typescript
 * interface MyContainerModelImpl extends KosContainerAware<MyItemModel> {}
 *
 * @kosContainerAware<MyItemModel>()
 * class MyContainerModelImpl implements IKosDataModel {
 *   // All container properties are now available with full type safety
 * }
 * ```
 *
 * ## Model Lifecycle: removeModel vs removeAndDestroy
 *
 * The decorator provides both removal and destruction methods with different purposes:
 *
 * **removeModel(id) / removeAll(ids)** - Removes from container WITHOUT destroying:
 * - Use when moving models between containers
 * - Use when temporarily hiding models that may be re-added
 * - Use when model lifecycle is managed elsewhere
 * - Container handles cleanup of observers and metadata
 * - Model remains in memory and can be used elsewhere
 *
 * **removeAndDestroy(id) / removeAndDestroyAll(ids)** - Removes AND destroys:
 * - Use when permanently removing models from the system
 * - Use when models should be fully cleaned up and disposed
 * - Calls destroyKosModel() automatically after removal
 * - Ensures proper cleanup of all model resources
 * - Model is removed from framework and memory
 *
 * ```typescript
 * // Example: Explicit lifecycle control
 * @kosTopicHandler({ topic: "/device/sensor/removed" })
 * handleSensorRemoved(id: string) {
 *   // Permanently remove - sensor is gone from system
 *   await this.removeAndDestroy(id);
 * }
 *
 * // Example: Reorganization without destruction
 * moveSensorToArchive(id: string) {
 *   const sensor = this.getModel(id);
 *   if (sensor) {
 *     this.removeModel(id);           // Remove from active container
 *     this.archive.addModel(sensor);  // Add to archive container
 *   }
 * }
 * ```
 *
 * ## Configuration Options
 *
 * ```typescript
 * @kosContainerAware<UserModel>({
 *   containerProperty: "users",        // Custom property name (default: "container")
 *   includeMethods: true,              // Include convenience methods (default: true)
 *   includeGetters: true,              // Include reactive getters (default: true)
 *   modelsProperty: "userList",        // Custom models getter name (default: "models")
 *   legacy: false,                     // Use "_models" property name (default: false)
 *   containerOptions: {
 *     parentId: "custom-parent",       // Override automatic parentId inference
 *     sortKey: "name",                 // Default sorting key
 *     extensionId: "my-extension",     // Extension identifier
 *     indexMap: {                      // Automatic indexing for efficient queries
 *       byRole: "role",                // Property-based index
 *       byStatus: (user) => user.active ? "active" : "inactive", // Function-based index
 *       admins: (user) => user.role === "admin" // Boolean index
 *     }
 *   }
 * })
 * ```
 *
 * @param options Configuration options for the decorator
 * @returns A class decorator that modifies the target class prototype
 *
 * @see {@link KosContainerAware} - Interface for TypeScript merging
 * @see {@link KosContainerAwareOptions} - Configuration options interface
 *
 * @example
 * ```typescript
 * // Minimal configuration - parentId automatically inferred
 * interface ItemContainerModelImpl extends KosContainerAware<ItemModel> {}
 *
 * @kosContainerAware<ItemModel>()
 * class ItemContainerModelImpl implements IKosDataModel {
 *   id: string;
 *
 *   constructor(modelId: string, options: ContainerOptions, context: KosCreationContext) {
 *     this.id = modelId;
 *     // Container automatically created with parentId: modelId
 *   }
 * }
 *
 * // With index configuration
 * interface UserContainerModelImpl extends KosContainerAware<UserModel> {}
 *
 * @kosContainerAware<UserModel>({
 *   containerOptions: {
 *     indexMap: {
 *       byRole: "role",
 *       byStatus: (user) => user.status
 *     }
 *   }
 * })
 * class UserContainerModelImpl implements IKosDataModel {
 *   constructor(modelId: string, options: ContainerOptions, context: KosCreationContext) {
 *     this.id = modelId;
 *   }
 * }
 *
 * // Legacy mode for backward compatibility
 * interface LegacyContainerModelImpl extends KosContainerAware<LegacyModel> {}
 *
 * @kosContainerAware<LegacyModel>({
 *   legacy: true,  // Uses '_models' as property name
 *   containerOptions: {
 *     sortKey: "name"
 *   }
 * })
 * class LegacyContainerModelImpl implements IKosDataModel {
 *   // Container available as this._models for backward compatibility
 * }
 * ```
 *
 * @category KOS Model Decorator
 * @since 2.1.0
 * @kosService core.container-aware
 * @kosApiLevel 13
 */
export declare function kosContainerAware<T extends IKosDataModel = IKosDataModel>(options?: KosContainerAwareOptions<T>): ClassDecorator;
export {};
//# sourceMappingURL=kos-container-aware.d.ts.map