// src/core/actor/IActorBehavior.ts

import type { AcceptsDefinition } from './AcceptsDefinition';
import type { IMessageMeta } from './IMessageMeta';
import type { IDispatchStrategy } from './IDispatchStrategy';

/** @deprecated Use IMessageMeta instead */
type MessageMeta = IMessageMeta;

/**
 * Actor behavior interface.
 *
 * This is the composed behavior pattern - components don't extend ActorBehavior,
 * they compose it via enableActorMode().
 */
export interface IActorBehavior<TAccepts extends AcceptsDefinition = AcceptsDefinition> {
  /**
   * Register a typed handler for a command.
   */
  registerHandler<K extends keyof TAccepts & string>(
    command: K,
    handler: (payload: TAccepts[K], meta: MessageMeta) => Promise<unknown>
  ): void;

  /**
   * Change all handlers atomically (Erlang's become).
   *
   * This replaces ALL handlers at once, enabling state machine patterns
   * where the actor's entire behavior changes based on state.
   */
  become(handlers: Partial<{
    [K in keyof TAccepts]: (payload: TAccepts[K], meta: MessageMeta) => Promise<unknown>
  }>): void;

  /**
   * Start processing messages from the mailbox.
   */
  start(): void;

  /**
   * Stop processing and close the mailbox.
   */
  stop(): void;

  /**
   * Add a dispatch strategy for pluggable message routing.
   */
  addDispatchStrategy(strategy: IDispatchStrategy): void;

  /**
   * Remove a dispatch strategy by name.
   */
  removeDispatchStrategy(name: string): void;

  /**
   * Whether the actor is currently running.
   */
  readonly isRunning: boolean;

  /**
   * The actor's mailbox address.
   */
  readonly address: string;
}
