interface IApplication {
    bootstrap(): void;
}
interface IRouter {
    openPage(id: string): void;
    openModal(id: string): void;
    getRootContainer(): HTMLElement;
}
interface IComponent {
    template: string;
    render(): HTMLElement;
}
interface IPage extends IComponent {
    open(): void;
    close(): void;
}
interface IObserver {
    onDestroy(): void;
}
interface IStream<T> {
    value: T;
    subscribe(action: (value: T) => void): void;
    unsubscribe(action: (value: T) => void): void;
}

type PageClass<Context> = new (router: IRouter, context: Context) => IPage;

type HTMLTemplateVars = {
    [property: string]: string | number | boolean;
};
type CssVars = {
    [property: string]: string;
};
type Pages<Context> = {
    [property: string]: PageClass<Context>;
};
type AppConfig<Context> = {
    root: HTMLElement;
    entry: PageClass<Context>;
    pages: Pages<Context>;
    modals: Pages<Context>;
};
type ComponentParams = {
    template: string;
};
type Action<Payload> = (value: Payload) => void;

/**
 * Component decorator
 *
 * @param params {ComponentParams} component params
 */
declare const component: (params: ComponentParams) => <T extends new (...args: any[]) => IComponent>(Constructor: T) => {
    new (...args: any[]): {
        template: string;
        render(): HTMLElement;
    };
} & T;

/**
 * Log decorator
 *
 * @param message {string | undefined} output message
 */
declare const log: (message?: string) => (target: Object, propertyKey: string, descriptor: PropertyDescriptor) => void;

/**
 * Base application class
 */
declare abstract class Application<Context> implements IApplication {
    protected readonly context: Context;
    protected readonly rootContainer: HTMLElement;
    protected readonly pages: Pages<Context>;
    protected readonly modals: Pages<Context>;
    protected readonly router: IRouter;
    private currentPage;
    private prevPage;
    private currentModal;
    /**
     * Application class constructor
     *
     * @param appConfig app configuration object
     * @param context app context object
     */
    constructor(appConfig: AppConfig<Context>, context: Context);
    /**
     * Prebuilt method for add logic when app starts
     *
     * @protected
     */
    protected onInit(): void;
    /**
     * Prebuilt method for build component
     *
     * @param Component Component class
     * @protected
     */
    protected initComponent(Component: PageClass<Context>): IPage;
    /**
     * Method for show current page
     */
    bootstrap(): void;
    /**
     * Method for open page
     *
     * @param id {string} page id from app config
     * @protected
     */
    protected openPage(id: string): void;
    /**
     * Method for open modal
     *
     * @param id {string} modal id from app config
     * @protected
     */
    protected openModal(id: string): void;
}

/**
 * Base component class
 */
declare abstract class Component implements IComponent {
    template: string;
    protected node: HTMLElement;
    protected vars(): HTMLTemplateVars;
    /**
     * Method for compile component from template
     *
     * @protected
     */
    protected compile(): void;
    /**
     * Prebuilt method for init component (subscribe subjects, declare children, etc.)
     *
     * @protected
     */
    protected onInit(): void;
    /**
     * Prebuilt method for binding
     *
     * @protected
     */
    protected bindElements(): void;
    /**
     * Prebuilt method for add dynamic content to element
     *
     * @protected
     */
    protected inject(): void;
    /**
     * Prebuilt method for handle component events
     *
     * @protected
     */
    protected handleEvents(): void;
    /**
     * Prebuilt method for render component
     */
    render(): HTMLElement;
}

/**
 * Base page class
 */
declare abstract class Page<Context> extends Component implements IPage, IObserver {
    protected readonly router: IRouter;
    protected readonly context: Context;
    protected readonly activeClass = "active";
    protected readonly prevClass = "anim-prev";
    protected readonly nextClass = "anim-next";
    /**
     * Page constructor
     *
     * @param router app router
     * @param context app context
     * @protected
     */
    constructor(router: IRouter, context: Context);
    /**
     * Prebuilt method for open this page
     */
    open(): void;
    /**
     * Prebuilt method for close this page
     */
    close(): void;
    /**
     * Prebuilt method for handle destroy event
     */
    onDestroy(): void;
}

/**
 * Base modal class
 */
declare abstract class Modal<Context> extends Page<Context> {
    /**
     * Prebuilt method for open this modal
     */
    open(): void;
    /**
     * Prebuilt method for close this modal
     */
    close(): void;
}

/**
 * Base router class
 */
declare class Router implements IRouter {
    openPage: (id: string) => void;
    openModal: (id: string) => void;
    private readonly rootContainer;
    /**
     * Base router constructor
     *
     * @param openPage callback for open page
     * @param openModal callback for open modal
     * @param rootContainer {HTMLElement} app root element
     */
    constructor(openPage: (id: string) => void, openModal: (id: string) => void, rootContainer: HTMLElement);
    /**
     * Method for get app root element from component
     */
    getRootContainer(): HTMLElement;
}

/**
 * Base store class
 */
declare abstract class Store<S> {
    protected abstract defaultState: S;
    /**
     * Base store class constructor
     */
    constructor();
    /**
     * Prebuilt method for handle init event
     *
     * @protected
     */
    protected onInit(): void;
}

/**
 * Base stream class
 */
declare class Stream<T> implements IStream<T> {
    private _value;
    private readonly storeKey?;
    protected actions: Action<T>[];
    /**
     * Base stream constructor
     *
     * @param _value stream value
     * @param storeKey {string | undefined} local storage key (for auto save, optional)
     */
    constructor(_value: T, storeKey?: string | undefined);
    /**
     * Stream value getter
     */
    get value(): T;
    /**
     * Stream value setter
     *
     * @param val new value
     */
    set value(val: T);
    /**
     * Method for subscribe observer
     *
     * @param action action, which will triggered after change value
     */
    subscribe(action: Action<T>): void;
    /**
     * Method for unsubscribe subscribed action
     *
     * @param action action
     */
    unsubscribe(action: Action<T>): void;
    /**
     * Method for load saved in ls stream value
     *
     * @protected
     */
    protected load(): T | null;
}

/**
 * Hook for add lazy load backgroundImage to HTMLElement
 *
 * @param el {HTMLElement}
 * @param src {string}
 */
declare const useBackground: (el: HTMLElement, src: string) => void;

/**
 * Hook for generate HTMLElement from component template
 *
 * @param template {string} Component template
 * @param vars {HTMLTemplateVars} Component template vars object
 * @returns {HTMLElement} Generated HTMLElement
 */
declare const useHtml: (template: string, vars?: HTMLTemplateVars) => HTMLElement;

/**
 * Hook for apply css vars to root html element
 *
 * @param vars {CssVars} Css vars
 */
declare const useVars: (vars?: CssVars) => void;

/**
 * Helper for start application.
 * Launches app bootstrap method
 *
 * @param app { IApplication } instance of application class
 */
declare function bootstrap(app: IApplication): void;
/**
 * Helper for inject component into Node
 * Launches component render method and returns generated Node (HTMLElement)
 *
 * @param component {Component} instance of class Component or its child class
 * @returns {HTMLElement}
 */
declare function render(component: IComponent): HTMLElement;

export { type Action, type AppConfig, Application, Component, type ComponentParams, type CssVars, type HTMLTemplateVars, type IApplication, type IComponent, type IObserver, type IPage, type IRouter, type IStream, Modal, Page, type PageClass, type Pages, Router, Store, Stream, bootstrap, component, log, render, useBackground, useHtml, useVars };
