import { CalledActionResult } from "../nlcore/gameTypes";
import { Awaitable, EventDispatcher, IdManager, Lock, Values } from "../../util/data";
import { MenuData } from "../nlcore/elements/menu";
import { Scene } from "../nlcore/elements/scene";
import { Sound } from "../nlcore/elements/sound";
import * as Howler from "howler";
import { SrcManager } from "../nlcore/action/srcManager";
import { LogicAction } from "../nlcore/action/logicAction";
import { Storable } from "../nlcore/elements/persistent/storable";
import { Game } from "../nlcore/game";
import { Clickable, MenuElement, TextElement } from "./gameState.type";
import { Sentence } from "../nlcore/elements/character/sentence";
import { Logger } from "../../util/logger";
import { Story } from "../nlcore/elements/story";
import { LiveGame } from "../nlcore/game/liveGame";
import { Chosen, ExposedKeys, ExposedState, ExposedStateType } from "./type";
import { AudioManager, AudioManagerDataRaw } from "./lib/AudioManager";
import { Layer } from "../nlcore/elements/layer";
import { GameStateGuard } from "./guard";
import { LiveGameEventToken } from "../nlcore/types";
import * as htmlToImage from "html-to-image";
import { Video, VideoStateRaw } from "../nlcore/elements/video";
import { Timelines } from "./Tasks";
import { Notification, NotificationManager } from "./lib/notification";
import { ActionHistoryManager } from "../../game/nlcore/action/actionHistory";
import { GameHistoryManager } from "../../game/nlcore/action/gameHistory";
import { Router } from "./lib/PageRouter/router";
type Legacy_PlayerStateElement = {
    texts: Clickable<TextElement>[];
    menus: Clickable<MenuElement, Chosen>[];
    displayable: LogicAction.DisplayableElements[];
};
type ScheduleHandle = {
    retry: () => void;
    onCleanup: (fn: VoidFunction) => void;
};
export type PlayerState = {
    sounds: Sound[];
    videos: Video[];
    srcManagers: SrcManager[];
    elements: PlayerStateElement[];
};
export type PlayerStateElement = {
    scene: Scene;
    /**@deprecated */
    ele?: Legacy_PlayerStateElement;
    layers: Map<Layer, LogicAction.DisplayableElements[]>;
    texts: Clickable<TextElement>[];
    menus: Clickable<MenuElement, Chosen>[];
};
export type PlayerStateData = {
    scenes: {
        sceneId: string;
        elements: {
            /**@deprecated */
            displayable?: string[];
            /**
             * { [layerName]: [displayableId][] }
             */
            layers: Record<string, string[]>;
        };
    }[];
    audio: AudioManagerDataRaw;
    videos: [videoId: string, videoState: VideoStateRaw][];
};
interface StageUtils {
    update: () => void;
    forceUpdate: () => void;
    forceRemount: () => void;
    next: () => void;
}
type GameStateEvents = {
    "event:state.end": [];
    "event:state.player.skip": [force?: boolean];
    "event:state.player.requestFlush": [];
    "event.state.onExpose": [unknown, ExposedState[ExposedStateType]];
    "event:state.onRender": [];
    "event:state:flushPreloadedScenes": [];
};
/**
 * Core game state management class
 * Manages all game-related states including sounds, videos, elements and their lifecycle
 */
export declare class GameState {
    static EventTypes: {
        [K in keyof GameStateEvents]: K;
    };
    private state;
    currentHandling: CalledActionResult | null;
    stage: StageUtils;
    game: Game;
    playerCurrent: HTMLDivElement | null;
    mainContentNode: HTMLDivElement | null;
    exposedState: Map<Values<ExposedKeys>, object>;
    guard: GameStateGuard;
    timelines: Timelines;
    preloadingScene: Scene | null;
    flushDep: number;
    rollLock: Lock;
    readonly notificationMgr: NotificationManager;
    readonly events: EventDispatcher<GameStateEvents>;
    readonly logger: Logger;
    readonly audioManager: AudioManager;
    readonly htmlToImage: typeof htmlToImage;
    readonly idManager: IdManager;
    readonly actionHistory: ActionHistoryManager;
    readonly gameHistory: GameHistoryManager;
    pageRouter: Router | null;
    constructor(game: Game, stage: StageUtils);
    get deps(): number;
    addVideo(video: Video): this;
    removeVideo(video: Video): this;
    isVideoAdded(video: Video): boolean;
    getVideos(): Video[];
    findElementByScene(scene: Scene): PlayerStateElement | null;
    findElementByDisplayable(displayable: LogicAction.DisplayableElements, layer?: Layer | null): PlayerStateElement | null;
    getLiveGame(): LiveGame;
    removeElement(element: PlayerStateElement): this;
    preloadScene(arg: Scene | Story): this;
    getPreloadingScene(): Scene | null;
    addElement(element: PlayerStateElement): this;
    addScene(scene: Scene): this;
    flush(): this;
    popScene(): this;
    removeScene(scene: Scene): this;
    getSceneElements(): PlayerStateElement[];
    getLastScene(): Scene | null;
    sceneExists(scene?: Scene): boolean;
    isSceneActive(scene: Scene): boolean;
    wait(ms: number): Promise<void>;
    schedule(callback: (scheduleHandle: ScheduleHandle) => void, ms: number): () => void;
    notify(notification: Notification): void;
    handle(action: PlayerAction): this;
    createDialog(id: string, sentence: Sentence, afterClick?: () => void, scene?: Scene): LiveGameEventToken & {
        text: string;
    };
    createMenu(menu: MenuData, afterChoose?: (choice: Chosen) => void, scene?: Scene): LiveGameEventToken & {
        prompt: null | string;
    };
    createDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
    disposeDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
    forceReset(): void;
    getHowl(): typeof Howler.Howl;
    registerSrcManager(srcManager: SrcManager): this;
    offSrcManager(srcManager: SrcManager): this;
    getStorable(): Storable;
    getSceneByName(name: string): Scene | null;
    getStory(): Story;
    setInterval(callback: () => void, delay: number): NodeJS.Timeout;
    clearInterval(interval: NodeJS.Timeout): void;
    setTimeout(callback: () => void, delay: number): NodeJS.Timeout;
    clearTimeout(timeout: NodeJS.Timeout): void;
    forceAnimation(): Awaitable;
    /**
     * Mounts a new state to the game state manager
     * @param key - Unique identifier for the state
     * @param state - State object to be mounted
     * @returns Object containing unmount function
     */
    mountState<T extends ExposedStateType>(key: ExposedKeys[T], state: ExposedState[T]): {
        unMount: () => void;
    };
    unMountState(key: Values<ExposedKeys>): this;
    initVideo(video: Video): this;
    isStateMounted(key: Values<ExposedKeys>): boolean;
    getExposedState<T extends ExposedStateType>(key: ExposedKeys[T]): ExposedState[T] | null;
    getExposedStateForce<T extends ExposedStateType>(key: ExposedKeys[T]): ExposedState[T];
    getExposedStateAsync<T extends ExposedStateType>(key: ExposedKeys[T], onExpose: (state: ExposedState[T]) => void): LiveGameEventToken;
    /**
     * Dispose of the game state
     *
     * This is an irreversible action; once disposed of, the game state can't be used again.
     *
     * Don't call this method directly
     */
    dispose(): void;
    /**
     * Converts current game state to serializable data format
     * @returns PlayerStateData object containing all state information
     */
    toData(): PlayerStateData;
    loadData(data: PlayerStateData, elementMap: Map<string, LogicAction.GameElement>): void;
    getLastSceneIfNot(scene: Scene | null | void): Scene;
    createElementSnapshot(element: PlayerStateElement): PlayerStateElementSnapshot;
    fromElementSnapshot(snapshot: PlayerStateElementSnapshot): PlayerStateElement;
    private removeElements;
    private resetLayers;
    private createWaitableAction;
    private sceneNotFound;
    private layerNotFound;
    private constructLayerMap;
}
export {};
