import { IKosModelContainer } from '../core/kos-container-model';
import { IKosContainerModel } from '../core/kosModel';
interface Identifiable {
    id: string;
}
/**
 * Function that transforms an entity's ID before container synchronization.
 *
 * The IdMapper pattern enables two critical capabilities:
 *
 * 1. **Compound Model IDs**: Transform simple backend IDs into compound IDs that include
 *    parent context (e.g., `"123"` → `"release-version-abc-123"`). This ensures unique
 *    model IDs even when backend IDs are only unique within their parent scope.
 *
 * 2. **Backend ID Preservation**: Add a `rawId` property to preserve the original backend ID
 *    for server communication while using compound IDs for model identity.
 *
 * @template D - Input entity type (data from backend)
 * @template M - Mapped entity type (data after transformation, defaults to D if no transformation)
 *
 * @example Simple ID prefix transformation
 * ```typescript
 * const idMapper: IdMapper<User, User & { rawId: string }> = (user) => ({
 *   ...user,
 *   rawId: user.id,
 *   id: `user-${user.id}`
 * });
 * ```
 *
 * @example Compound ID with parent context
 * ```typescript
 * type WithRawId<T> = T & { rawId: string };
 *
 * const idMapper: IdMapper<VersionResponse, WithRawId<VersionResponse>> = (version) => ({
 *   ...version,
 *   rawId: version.id,
 *   id: `release-version-${templateId}-${version.id}`
 * });
 * ```
 *
 * @example Multi-level compound ID
 * ```typescript
 * const idMapper: IdMapper<CandidateResponse, WithRawId<CandidateResponse>> = (candidate) => ({
 *   ...candidate,
 *   rawId: candidate.id,
 *   id: `release-candidate-${templateId}-${versionId}-${candidate.id}`
 * });
 * ```
 *
 * @kosService core.container-utils
 */
export type IdMapper<D extends Identifiable = Identifiable, M extends Identifiable = D> = (entity: D) => M;
type Container = IKosContainerModel<any, any> | IKosModelContainer<any>;
/**
 * Parameters for resolving container deltas.
 * @template T - The container type
 * @template D - The input entity type with an id property
 * @template M - The mapped entity type (after idMapper transformation)
 */
interface ResolveParams<T extends Container, D extends Identifiable, M extends Identifiable = D> {
    /** The container to synchronize */
    container: T;
    /** Callback to create a new item when an entity is added */
    onAddItem: (entity: M) => any;
    /** Optional callback when an item is removed, receives the id to remove */
    onRemoveItem?: (id: string) => any;
    /** Optional callback when an existing item needs updating */
    onUpdateItem?: (entity: M, existingModel: any) => any;
    /** Optional mapper to transform entity ids before processing */
    idMapper?: IdMapper<D, M>;
}
/**
 * Creates a function that synchronizes a container with a new list of entities.
 *
 * This is the primary utility for delta-based container synchronization. It compares incoming
 * data against the current container state and performs minimal operations (add/update/remove)
 * to achieve synchronization.
 *
 * Key features:
 * - **Delta resolution**: Only processes actual changes (add/update/remove)
 * - **ID transformation**: Optional `idMapper` transforms backend IDs to model IDs
 * - **Update-in-place**: `onUpdateItem` can update existing models without recreating
 * - **Type safety**: Generic type parameters ensure type consistency through transformation
 *
 * Workflow:
 * 1. Apply `idMapper` to transform entity IDs (if provided)
 * 2. Calculate deltas: which IDs are missing from new data (removals)
 * 3. Invoke `onRemoveItem` for each ID to remove
 * 4. For each entity in new data:
 *    - If model exists: invoke `onUpdateItem` (if provided) or `onAddItem`
 *    - If model doesn't exist: invoke `onAddItem`
 * 5. Add all new models to container in batch
 *
 * @template T - Container type implementing IKosModelContainer
 * @template D - Input entity type (data from backend)
 * @template M - Mapped entity type (after idMapper transformation, defaults to D)
 *
 * @param params - Configuration for resolving deltas
 * @param params.container - The container to synchronize
 * @param params.onAddItem - Callback to create a new model from entity data
 * @param params.onUpdateItem - Optional callback to update existing model (return null to skip adding)
 * @param params.onRemoveItem - Optional callback invoked with each ID to remove (default: identity function)
 * @param params.idMapper - Optional function to transform entity IDs before processing
 *
 * @returns A function that accepts entities and synchronizes the container
 *
 * @kosService core.container-utils
 *
 * @example Basic synchronization without ID transformation
 * ```typescript
 * const syncUsers = resolveContainerDeltas({
 *   container: userContainer,
 *   onAddItem: (user) => User.instance(user.id).options(user).build(),
 *   onUpdateItem: (user, existing) => {
 *     existing.updateModel(user);
 *     return null; // Don't add, just updated in place
 *   },
 *   onRemoveItem: (id) => id
 * });
 * syncUsers(newUserList);
 * ```
 *
 * @example ID transformation with compound IDs and rawId preservation
 * ```typescript
 * type WithRawId<T> = T & { rawId: string };
 *
 * const syncVersions = resolveContainerDeltas<
 *   typeof template.versions,
 *   VersionResponse,
 *   WithRawId<VersionResponse>
 * >({
 *   container: template.versions,
 *   idMapper: (versionData) => ({
 *     ...versionData,
 *     rawId: versionData.id,  // Preserve backend ID
 *     id: ReleaseIdFactory.version(templateId, versionData.id)  // Compound model ID
 *   }),
 *   onAddItem: (data) => {
 *     const model = ReleaseVersion.instance(data.id)
 *       .options({
 *         rawId: data.rawId,  // Store backend ID for server communication
 *         version: data.version,
 *         // ... other options
 *       })
 *       .build();
 *     // Recursively sync nested containers
 *     syncCandidates(model, data.candidates || []);
 *     return model;
 *   },
 *   onUpdateItem: (data, existingVersion) => {
 *     existingVersion.updateModel({
 *       rawId: data.rawId || existingVersion.rawId,
 *       version: data.version,
 *       // ... other updates
 *     });
 *     // Recursively sync nested containers
 *     syncCandidates(existingVersion, data.candidates || []);
 *     return null; // Don't add, just updated in place
 *   },
 *   onRemoveItem: (id) => id
 * })(versionsData);
 * ```
 *
 * @example Nested container synchronization
 * ```typescript
 * // Parent level
 * syncTemplates(containerModel, templatesData);
 *
 * // Within onAddItem and onUpdateItem, sync children
 * function syncTemplates(container, templates) {
 *   resolveContainerDeltas({
 *     container: container.container,
 *     idMapper: (template) => ({
 *       ...template,
 *       rawId: template.id,
 *       id: ReleaseIdFactory.template(template.id)
 *     }),
 *     onAddItem: (template) => {
 *       const model = createTemplateModel(template);
 *       syncQueues(model, template.queues);  // Nested sync
 *       syncVersions(model, template.versions);  // Nested sync
 *       return model;
 *     },
 *     onUpdateItem: (template, existing) => {
 *       existing.updateModel(template);
 *       syncQueues(existing, template.queues);  // Nested sync
 *       syncVersions(existing, template.versions);  // Nested sync
 *       return null;
 *     }
 *   })(templates);
 * }
 * ```
 * @kosApiLevel 2
 */
export declare const resolveContainerDeltas: <T extends IKosModelContainer<any>, D extends Identifiable, M extends Identifiable = D>({ container, onAddItem, onUpdateItem, onRemoveItem, idMapper, }: ResolveParams<T, D, M>) => (entities: D[]) => void;
/**
 * Creates a function that synchronizes a container model's list with new entities.
 * Simpler alternative to resolveContainerDeltas that directly invokes callbacks for each addition and removal.
 *
 * @template T - Container model type implementing IKosContainerModel
 * @template D - Input entity type with an id property
 * @template M - Mapped entity type (after idMapper transformation)
 * @param params - Configuration for resolving deltas
 * @returns A function that accepts entities and synchronizes by invoking callbacks
 *
 * @kosService core.container-utils
 *
 * @example
 * const syncLayers = resolveListDeltas({
 *   container: layerContainer,
 *   onAddItem: (layer) => addLayer(layer),
 *   onRemoveItem: (id) => removeLayer(id)
 * });
 * syncLayers(newLayerList);
 * @kosApiLevel 2
 */
export declare const resolveListDeltas: <T extends IKosContainerModel<any, any>, D extends Identifiable, M extends Identifiable = D>({ container, onAddItem, onRemoveItem, idMapper, }: ResolveParams<T, D, M>) => (entities: D[]) => void;
/**
 * Parameters for resolving deltas on plain item arrays (not container models).
 * @template T - Current item type with an id property
 * @template D - Input entity type with an id property
 * @template M - Mapped entity type (after idMapper transformation)
 */
interface ResolveItemsParams<T extends Identifiable, D extends Identifiable, M extends Identifiable = D> {
    /** The current array of items to synchronize */
    items: T[];
    /** Callback invoked for each entity to add */
    onAddItem: (entity: M) => void;
    /** Callback invoked for each id to remove */
    onRemoveItem: (id: string) => void;
    /** Optional mapper to transform entity ids before processing */
    idMapper?: IdMapper<D, M>;
}
/**
 * Creates a function that synchronizes a plain array of items with new entities.
 * Does not require a container model - works with any array of identifiable items.
 *
 * @template T - Current item type with an id property
 * @template D - Input entity type with an id property
 * @template M - Mapped entity type (after idMapper transformation)
 * @param params - Configuration including the items array and callbacks
 * @returns A function that accepts entities and synchronizes the array
 *
 * @kosService core.container-utils
 *
 * @example
 * const currentItems = [{ id: '1', name: 'Item 1' }];
 * const syncItems = resolveItemListDeltas({
 *   items: currentItems,
 *   onAddItem: (item) => currentItems.push(item),
 *   onRemoveItem: (id) => {
 *     const index = currentItems.findIndex(i => i.id === id);
 *     if (index >= 0) currentItems.splice(index, 1);
 *   }
 * });
 * syncItems(newItems);
 * @kosApiLevel 2
 */
export declare const resolveItemListDeltas: <T extends Identifiable, D extends Identifiable, M extends Identifiable = D>({ items, onAddItem, onRemoveItem, idMapper, }: ResolveItemsParams<T, D, M>) => (entities: D[]) => void;
/**
 * Removes a prefix from an id string if present.
 * Useful for normalizing ids that may have parent or namespace prefixes.
 *
 * @param id - The id string to process
 * @param prefix - The prefix to remove (defaults to "parent-")
 * @returns The id with the prefix removed, or the original id if prefix not found
 *
 * @example
 * processId("parent-123") // returns "123"
 * processId("parent-abc", "parent-") // returns "abc"
 * processId("child-456", "parent-") // returns "child-456"
 *
 * @kosService core.container-utils
 * @kosApiLevel 2
 */
export declare const processId: (id: string, prefix?: string) => string;
export {};
//# sourceMappingURL=container-utils.d.ts.map