import type { Vec2 } from '../core/types';
import { EventBus } from '../core/EventBus';
import React from 'react';
/** Dialogue node types */
export type DialogueNodeType = 'start' | 'text' | 'choice' | 'branch' | 'set_variable' | 'check_variable' | 'event' | 'random' | 'end';
/** Variable types supported in dialogues */
export type DialogueVarType = 'boolean' | 'number' | 'string';
/** Comparison operators for conditions */
export type ComparisonOp = 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'contains' | 'startsWith' | 'endsWith';
/** Character emotion types */
export type EmotionType = 'neutral' | 'happy' | 'sad' | 'angry' | 'surprised' | 'scared' | 'disgusted' | 'confused' | 'thoughtful' | 'excited' | 'tired' | 'love' | 'custom';
/** Text effect types */
export type TextEffectType = 'none' | 'typewriter' | 'shake' | 'wave' | 'rainbow' | 'fade';
export interface DialogueVariable {
    id: string;
    name: string;
    type: DialogueVarType;
    defaultValue: boolean | number | string;
    description?: string;
    persistent?: boolean;
    scope: 'conversation' | 'global';
}
export interface VariableCondition {
    variableId: string;
    operator: ComparisonOp;
    value: boolean | number | string;
}
export interface DialogueCharacter {
    id: string;
    name: string;
    displayName: string;
    /** Portrait images per emotion */
    portraits: Record<EmotionType, string>;
    voiceId?: string;
    defaultEmotion: EmotionType;
    textColor?: string;
    nameColor?: string;
    textSpeed?: number;
}
export interface DialogueNodeBase {
    id: string;
    type: DialogueNodeType;
    position: Vec2;
    comment?: string;
    tags?: string[];
}
export interface StartNode extends DialogueNodeBase {
    type: 'start';
    label: string;
    nextNode: string | null;
}
export interface TextNode extends DialogueNodeBase {
    type: 'text';
    characterId: string;
    text: string;
    emotion?: EmotionType;
    textEffect?: TextEffectType;
    audioClip?: string;
    duration?: number;
    nextNode: string | null;
}
export interface ChoiceOption {
    id: string;
    text: string;
    nextNode: string | null;
    conditions?: VariableCondition[];
    /** Variables to set when this choice is selected */
    setVariables?: {
        variableId: string;
        value: boolean | number | string;
    }[];
    disabled?: boolean;
    tooltip?: string;
}
export interface ChoiceNode extends DialogueNodeBase {
    type: 'choice';
    characterId?: string;
    prompt?: string;
    options: ChoiceOption[];
    timeout?: number;
    defaultOption?: string;
}
export interface BranchNode extends DialogueNodeBase {
    type: 'branch';
    conditions: VariableCondition[];
    /** AND or OR logic for multiple conditions */
    logic: 'and' | 'or';
    trueNode: string | null;
    falseNode: string | null;
}
export interface SetVariableNode extends DialogueNodeBase {
    type: 'set_variable';
    variableId: string;
    operation: 'set' | 'add' | 'subtract' | 'multiply' | 'toggle' | 'append';
    value: boolean | number | string;
    nextNode: string | null;
}
export interface CheckVariableNode extends DialogueNodeBase {
    type: 'check_variable';
    conditions: VariableCondition[];
    logic: 'and' | 'or';
    trueNode: string | null;
    falseNode: string | null;
}
export interface EventNode extends DialogueNodeBase {
    type: 'event';
    eventType: string;
    eventData: Record<string, unknown>;
    nextNode: string | null;
}
export interface RandomNode extends DialogueNodeBase {
    type: 'random';
    outputs: {
        id: string;
        weight: number;
        nextNode: string | null;
    }[];
}
export interface EndNode extends DialogueNodeBase {
    type: 'end';
    result?: 'success' | 'failure' | 'neutral';
    setVariables?: {
        variableId: string;
        value: boolean | number | string;
    }[];
}
export type DialogueNode = StartNode | TextNode | ChoiceNode | BranchNode | SetVariableNode | CheckVariableNode | EventNode | RandomNode | EndNode;
export interface DialogueTree {
    id: string;
    name: string;
    description?: string;
    version: string;
    characters: DialogueCharacter[];
    variables: DialogueVariable[];
    nodes: DialogueNode[];
    startNodeId: string;
    metadata: {
        author?: string;
        created: string;
        modified: string;
        tags?: string[];
        locale: string;
    };
}
export interface DialogueState {
    treeId: string;
    currentNodeId: string | null;
    variables: Record<string, boolean | number | string>;
    history: string[];
    choicesMade: {
        nodeId: string;
        optionId: string;
        timestamp: number;
    }[];
    startTime: number;
    isActive: boolean;
    isPaused: boolean;
}
export type DialogueEventType = 'dialogue:started' | 'dialogue:ended' | 'dialogue:node-entered' | 'dialogue:text-displayed' | 'dialogue:choice-selected' | 'dialogue:variable-changed' | 'dialogue:event-triggered' | 'dialogue:paused' | 'dialogue:resumed';
export interface DialogueEvent {
    type: DialogueEventType;
    treeId: string;
    nodeId?: string;
    data?: unknown;
    timestamp: number;
}
export declare class DialogueEngine {
    private trees;
    private globalVariables;
    private currentState;
    private events;
    private onTextCallback?;
    private onChoiceCallback?;
    private onEndCallback?;
    constructor(events?: EventBus);
    registerTree(tree: DialogueTree): void;
    unregisterTree(treeId: string): void;
    getTree(treeId: string): DialogueTree | undefined;
    getAllTrees(): DialogueTree[];
    setGlobalVariable(name: string, value: boolean | number | string): void;
    getGlobalVariable(name: string): boolean | number | string | undefined;
    getVariable(variableId: string): boolean | number | string | undefined;
    private setVariable;
    startDialogue(treeId: string, startLabel?: string): boolean;
    endDialogue(): void;
    pauseDialogue(): void;
    resumeDialogue(): void;
    getState(): DialogueState | null;
    isActive(): boolean;
    private goToNode;
    private processNode;
    private processTextNode;
    private processChoiceNode;
    private processBranchNode;
    private processSetVariableNode;
    private processEventNode;
    private processRandomNode;
    private processEndNode;
    selectChoice(optionId: string): boolean;
    /** Advance to next node (for text nodes) */
    advance(): boolean;
    private evaluateConditions;
    private evaluateCondition;
    onText(callback: (node: TextNode, character: DialogueCharacter) => void): void;
    onChoice(callback: (node: ChoiceNode, options: ChoiceOption[]) => void): void;
    onEnd(callback: (node: EndNode, state: DialogueState) => void): void;
    private emitEvent;
    subscribe(eventType: DialogueEventType, handler: (event: DialogueEvent) => void): () => void;
}
export declare class DialogueTreeBuilder {
    private tree;
    private nodeCounter;
    constructor(id: string, name: string);
    private generateId;
    description(desc: string): this;
    author(author: string): this;
    locale(locale: string): this;
    tags(tags: string[]): this;
    addCharacter(character: DialogueCharacter): this;
    addVariable(variable: DialogueVariable): this;
    boolVar(id: string, name: string, defaultValue?: boolean, scope?: 'conversation' | 'global'): this;
    numVar(id: string, name: string, defaultValue?: number, scope?: 'conversation' | 'global'): this;
    strVar(id: string, name: string, defaultValue?: string, scope?: 'conversation' | 'global'): this;
    addStart(label: string, nextNode?: string | null, position?: Vec2): this;
    addText(characterId: string, text: string, nextNode?: string | null, options?: Partial<Omit<TextNode, 'id' | 'type' | 'characterId' | 'text' | 'nextNode'>>): this;
    addChoice(options: ChoiceOption[], settings?: Partial<Omit<ChoiceNode, 'id' | 'type' | 'options'>>): this;
    addBranch(conditions: VariableCondition[], trueNode: string | null, falseNode: string | null, logic?: 'and' | 'or', position?: Vec2): this;
    addSetVariable(variableId: string, operation: SetVariableNode['operation'], value: boolean | number | string, nextNode?: string | null, position?: Vec2): this;
    addEvent(eventType: string, eventData: Record<string, unknown>, nextNode?: string | null, position?: Vec2): this;
    addRandom(outputs: {
        weight: number;
        nextNode: string | null;
    }[], position?: Vec2): this;
    addEnd(result?: EndNode['result'], setVariables?: EndNode['setVariables'], position?: Vec2): this;
    build(): DialogueTree;
    /** Get the ID of the last added node */
    lastNodeId(): string;
    /** Get node by index (1-based for readability) */
    nodeId(index: number): string;
}
export interface DialogueBoxProps {
    /** The text to display */
    text: string;
    /** Character name */
    characterName?: string;
    /** Character portrait URL */
    portrait?: string;
    /** Emotion for styling */
    emotion?: EmotionType;
    /** Text effect */
    textEffect?: TextEffectType;
    /** Characters per second for typewriter effect */
    textSpeed?: number;
    /** Called when text fully displayed */
    onComplete?: () => void;
    /** Called when user clicks to advance */
    onAdvance?: () => void;
    /** Custom styles */
    className?: string;
    style?: React.CSSProperties;
}
/**
 * React hook for typewriter text effect
 */
export declare function useTypewriter(text: string, speed?: number, enabled?: boolean): {
    displayedText: string;
    isComplete: boolean;
    skip: () => void;
};
/**
 * DialogueBox component for displaying dialogue text
 */
export declare const DialogueBox: React.FC<DialogueBoxProps>;
export interface ChoiceListProps {
    /** Available choices */
    options: ChoiceOption[];
    /** Prompt text */
    prompt?: string;
    /** Called when a choice is selected */
    onSelect: (optionId: string) => void;
    /** Timeout in ms (optional) */
    timeout?: number;
    /** Custom styles */
    className?: string;
    style?: React.CSSProperties;
}
/**
 * ChoiceList component for displaying dialogue choices
 */
export declare const ChoiceList: React.FC<ChoiceListProps>;
/**
 * Serialize dialogue tree to JSON string
 */
export declare function serializeDialogueTree(tree: DialogueTree): string;
/**
 * Deserialize dialogue tree from JSON string
 */
export declare function deserializeDialogueTree(json: string): DialogueTree;
/**
 * Validate dialogue tree structure
 */
export declare function validateDialogueTree(tree: unknown): DialogueTree;
/**
 * Find unreachable nodes in dialogue tree
 */
export declare function findUnreachableNodes(tree: DialogueTree): string[];
export interface DialogueLocalization {
    treeId: string;
    locale: string;
    texts: Record<string, string>;
    characterNames: Record<string, string>;
}
/**
 * Extract all translatable strings from a dialogue tree
 */
export declare function extractTranslatableStrings(tree: DialogueTree): {
    nodeTexts: Record<string, string>;
    characterNames: Record<string, string>;
};
/**
 * Apply localization to a dialogue tree (creates a copy)
 */
export declare function applyLocalization(tree: DialogueTree, localization: DialogueLocalization): DialogueTree;
export declare const DEFAULT_TEXT_SPEED = 50;
export declare const EMOTION_COLORS: Record<EmotionType, string>;
export declare function createEmptyDialogueTree(id: string, name: string): DialogueTree;
