/**
 * Shared types for the multi-channel messaging system.
 */

export type ChannelType = 'whatsapp' | 'telegram' | 'alexa';
export type SenderRole = 'admin' | 'customer' | 'assistant';

export interface ChannelConfig {
  enabled: boolean;
  /** 'channel' = just talk to me (self-chat only), 'business' = admin/customer mode, 'assistant' = personal assistant in conversations */
  mode: 'channel' | 'business' | 'assistant';
  /** Phone numbers with admin access (owner, secretary, etc.) — business mode only */
  admins?: string[];
  /** Active skill for customer-facing mode (folder name in workspace/skills/) */
  skill?: string;
  /** Opt-in: process messages in group chats (default false). Channel mode ignores this. */
  allowGroups?: boolean;
  /** Assistant mode only. When false (default) ONLY the account owner (fromMe) can trigger
   *  the agent with `@botname`. When true, ANYONE who tags the bot (DM or group) can drive it.
   *  DANGER: the triggerer gains full control of an agent that can run Bash, edit files, etc.
   *  Enable only for fully trusted shared use. See the WhatsApp SKILL.md disclaimer. */
  allowOthersToTrigger?: boolean;
}

export interface InboundMessageAttachment {
  type: 'image';
  mediaType: string;
  data: string; // base64
}

export interface InboundMessage {
  channel: ChannelType;
  /** Sender identifier (phone number) */
  sender: string;
  /** Sender display name if available */
  senderName?: string;
  /** Resolved role of the sender */
  role: SenderRole;
  /** Message text content (may include enriched context for assistant triggers) */
  text: string;
  /** Display-friendly text for DB/chat UI (when text contains enriched agent context) */
  displayText?: string;
  /** Raw sender JID (channel-specific format, used for replies) */
  rawSender: string;
  /** Image attachments */
  attachments?: InboundMessageAttachment[];
  /** Original channel-native message key (Baileys WAMessageKey for WhatsApp). Opaque here. */
  inboundKey?: unknown;
  /** True when the chat is a group (for assistant-mode group routing). */
  isGroup?: boolean;
}

export interface OutboundMessage {
  channel: ChannelType;
  to: string;
  text: string;
}

export interface ChannelStatus {
  channel: ChannelType;
  connected: boolean;
  /** Additional info like phone number, QR state, etc. */
  info?: Record<string, any>;
}

/**
 * Per-turn routing target.
 *
 * Every user message pushed into a live conversation carries one of these so the
 * agent's response goes back to the surface that triggered it — no FIFO ambiguity,
 * no channel-bleed across concurrent turns.
 *
 * Created by the surface that pushes the user message (chat-WS or channel handler),
 * consumed by the manager when the corresponding `bot:response` fires, discarded if
 * the turn ends without a response (error / empty turn).
 */
export interface RoutingTarget {
  /** Which surface triggered this turn. Drives whether the WA reply carries a "🤖 Bot:" prefix.
   *  'workspace' is a dashboard surface like 'chat' (broadcast-driven, optional WA self-chat mirror)
   *  but isolated for telemetry / future per-surface routing. */
  surface: 'chat' | 'whatsapp' | 'alexa' | 'telegram' | 'workspace';
  /** WhatsApp JID to deliver the reply to.
   *  - 'whatsapp' surface → the originating chat JID (group or peer).
   *  - 'chat' surface     → optionally the user's own number (self-chat mirror), or undefined.
   *  When undefined, no WhatsApp send happens — the reply only reaches the dashboard via broadcast.
   */
  waSendTo?: string;
  /** Telegram chat id to deliver the reply to ('telegram' surface). */
  telegramChatId?: string;
  /** Telegram message id of the inbound that triggered this turn (for reply-to / reactions). */
  telegramMessageId?: number;
  isGroup?: boolean;
  isSelfChat?: boolean;
  /** When set, the assistant's reply is appended to this customer buffer (assistant-mode context). */
  assistantBufferKey?: string;
  /** Original inbound WA message key — kept opaque here, used by the channel to react/quote. */
  inboundKey?: unknown;
  /** Unix ms when this target was pushed — used to detect stale queue entries. */
  pushedAt?: number;
}

export interface ChannelProvider {
  readonly type: ChannelType;
  /** Start the channel connection (may trigger QR flow) */
  connect(): Promise<void>;
  /** Disconnect and clean up */
  disconnect(): Promise<void>;
  /** Send a text message */
  sendMessage(to: string, text: string): Promise<void>;
  /** Get current connection status */
  getStatus(): ChannelStatus;
  /** Get current QR code data (base64 SVG) or null if not in QR state */
  getQrCode(): string | null;
  /** Whether auth credentials exist (previously connected) */
  hasCredentials(): boolean;
}
