import { Type } from '@angular/core';
import { StateContext } from '@ngxs/store';
import { EntityAddAction, EntityCreateOrReplaceAction, EntityGoToPageAction, EntityRemoveAction, EntitySetActiveAction, EntitySetErrorAction, EntitySetLoadingAction, EntitySetPageSizeAction, EntityUpdateAction, EntityUpdateActiveAction } from './actions';
import { IdStrategy } from './id-strategy';
import { HashMap } from './internal';
import { EntityStateModel, StateSelector } from './models';
import IdGenerator = IdStrategy.IdGenerator;
/**
 * Returns a new object which serves as the default state.
 * No entities, loading is false, error is undefined, active is undefined.
 * pageSize is 10 and pageIndex is 0.
 */
export declare function defaultEntityState<T>(defaults?: Partial<EntityStateModel<T>>): EntityStateModel<T>;
export declare abstract class EntityState<T extends {}> {
    private readonly idKey;
    private readonly storePath;
    protected readonly idGenerator: IdGenerator<T>;
    protected constructor(storeClass: Type<EntityState<T>>, _idKey: keyof T, idStrategy: Type<IdGenerator<T>>);
    private static readonly staticStorePath;
    /**
     * This function is called every time an entity is updated.
     * It receives the current entity and a partial entity that was either passed directly or generated with a function.
     * The default implementation uses the spread operator to create a new entity.
     * You must override this method if your entity type does not support the spread operator.
     * @see Updater
     * @param current The current entity, readonly
     * @param updated The new data as a partial entity
     * @example
     * // default behavior
     * onUpdate(current: Readonly<T updated: Partial<T>): T {
    return {...current, ...updated};
   }
     */
    onUpdate(current: Readonly<T>, updated: Partial<T>): T;
    /**
     * Returns a selector for the activeId
     */
    static readonly activeId: StateSelector<string>;
    /**
     * Returns a selector for the active entity
     */
    static readonly active: StateSelector<any>;
    /**
     * Returns a selector for the keys of all entities
     */
    static readonly keys: StateSelector<string[]>;
    /**
     * Returns a selector for all entities, sorted by insertion order
     */
    static readonly entities: StateSelector<any[]>;
    /**
     * Returns a selector for the nth entity, sorted by insertion order
     */
    static nthEntity(index: number): StateSelector<any>;
    /**
     * Returns a selector for paginated entities, sorted by insertion order
     */
    static readonly paginatedEntities: StateSelector<any[]>;
    /**
     * Returns a selector for the map of entities
     */
    static readonly entitiesMap: StateSelector<HashMap<any>>;
    /**
     * Returns a selector for the size of the entity map
     */
    static readonly size: StateSelector<number>;
    /**
     * Returns a selector for the error
     */
    static readonly error: StateSelector<Error | undefined>;
    /**
     * Returns a selector for the loading state
     */
    static readonly loading: StateSelector<boolean>;
    /**
     * Returns a selector for the latest added entity
     */
    static readonly latest: StateSelector<any>;
    /**
     * Returns a selector for the latest added entity id
     */
    static readonly latestId: StateSelector<string | undefined>;
    /**
     * Returns a selector for the update timestamp
     */
    static readonly lastUpdated: StateSelector<Date>;
    /**
     * Returns a selector for age, based on the update timestamp
     */
    static readonly age: StateSelector<number>;
    /**
     * The entities given by the payload will be added.
     * For certain ID strategies this might fail, if it provides an existing ID.
     * In all cases it will overwrite the ID value in the entity with the calculated ID.
     */
    add({ getState, patchState }: StateContext<EntityStateModel<T>>, { payload }: EntityAddAction<T>): void;
    /**
     * The entities given by the payload will be added.
     * It first checks if the ID provided by each entity does exist.
     * If it does the current entity will be replaced.
     * In all cases it will overwrite the ID value in the entity with the calculated ID.
     */
    createOrReplace({ getState, patchState }: StateContext<EntityStateModel<T>>, { payload }: EntityCreateOrReplaceAction<T>): void;
    update({ getState, patchState }: StateContext<EntityStateModel<T>>, { payload }: EntityUpdateAction<T>): void;
    updateActive({ getState, patchState }: StateContext<EntityStateModel<T>>, { payload }: EntityUpdateActiveAction<T>): void;
    removeActive({ getState, patchState }: StateContext<EntityStateModel<T>>): void;
    remove({ getState, patchState }: StateContext<EntityStateModel<T>>, { payload }: EntityRemoveAction<T>): void;
    reset({ setState }: StateContext<EntityStateModel<T>>): void;
    setLoading({ patchState }: StateContext<EntityStateModel<T>>, { payload }: EntitySetLoadingAction): void;
    setActive({ patchState }: StateContext<EntityStateModel<T>>, { payload }: EntitySetActiveAction): void;
    clearActive({ patchState }: StateContext<EntityStateModel<T>>): void;
    setError({ patchState }: StateContext<EntityStateModel<T>>, { payload }: EntitySetErrorAction): void;
    goToPage({ getState, patchState }: StateContext<EntityStateModel<T>>, { payload }: EntityGoToPageAction): void;
    setPageSize({ patchState }: StateContext<EntityStateModel<T>>, { payload }: EntitySetPageSizeAction): void;
    /**
     * A utility function to update the given state with the given entities.
     * It returns a state model with the new entities map and IDs.
     * For each given entity an ID will be generated. The generated ID will overwrite the current value:
     * <code>entity[this.idKey] = generatedId(entity, state);</code>
     * If the ID wasn't present, it will be added to the state's IDs array.
     * @param state The current state to act on
     * @param payload One or multiple partial entities
     * @param generateId A function to generate an ID for each given entity
     */
    private _addOrReplace;
    /**
     * A utility function to update the given entities map with the provided partial entity.
     * After checking if an entity with the given ID is present, the #onUpdate method is called.
     * @param entities The current entity map
     * @param entity The partial entity to update with
     * @param id The ID to find the current entity in the map
     */
    private _update;
    private setup;
    /**
     * Returns the id of the given entity, based on the defined idKey.
     * This methods allows Partial entities and thus might return undefined.
     * Other methods calling this one have to handle this case themselves.
     * @param data a partial entity
     */
    protected idOf(data: Partial<T>): string | undefined;
}
