import { getErrorMeta, getLogger } from "../../util/logger.js";
export class FSM {
    _state;
    get state() {
        return this._state;
    }
    _context;
    get context() {
        return this._context;
    }
    transitions;
    onTransition;
    metadata;
    initialMetadata = {};
    constructor(config) {
        this.transitions = config.transitions;
        this.metadata = config.metadata ?? {};
        this.initialMetadata = config.metadata ?? {};
        this._state = config.initialState;
        this._context = config.initialContext;
        this.onTransition = config.createTransitionHandler(this);
    }
    updateContext(update) {
        this._context =
            typeof update === "function"
                ? update(this.context)
                : { ...this.context, ...update };
    }
    getMetadata() {
        return this.metadata[this.state];
    }
    updateMetadata(update) {
        this.metadata[this.state] =
            typeof update === "function"
                ? update(this.metadata[this.state])
                : { ...this.metadata[this.state], ...update };
    }
    resetAllMetadata() {
        this.metadata = this.initialMetadata;
    }
    async send(event) {
        const fromState = this.state;
        const toState = this.transitions[fromState]?.[event.type];
        const logger = getLogger();
        if (!toState) {
            logger.warn(`[ai-service] No transition for event '${event.type}' from state '${fromState}'`);
            return;
        }
        logger.info(`[ai-service] State transition: ${fromState} -> ${toState} (event: ${event.type})`);
        this._state = toState;
        try {
            await this.onTransition?.({
                from: fromState,
                to: toState,
                event,
            });
        }
        catch (error) {
            logger.error(`[ai-service] Transition handler threw an error for ${toState} on event ${event.type}:`, getErrorMeta(error));
            // Re-throw to allow state machine to handle appropriately
            throw error;
        }
    }
}
//# sourceMappingURL=fsm.js.map