/**
 * src/channels/whatsapp/baileys-adapter.ts
 *
 * Baileys-backed WhatsApp adapter for Phase 1.
 *
 * Why Baileys (vs Meta Cloud API):
 *   - Customer scans a QR from the WhatsApp Business mobile app on a fresh
 *     dedicated SIM and Muassis is connected. No Meta Business setup, no
 *     paperwork, no BSP fees.
 *   - The user has been running OpenClaw on this same pattern for 4 months on
 *     their own device with zero ban events, so the risk is empirically
 *     acceptable for low-volume B2B conversational AI on a dedicated number.
 *
 * Session credentials are persisted to the platform data dir:
 *   {MUASSIS_DATA_DIR}/whatsapp/<tenantId>/   (creds.json + key files)
 *
 * The dashboard polls/streams the QR code via /api/tenants/:id/whatsapp/qr.
 * Once paired, incoming messages route through the existing agent loop —
 * processMessage() doesn't care which channel a message came in on.
 *
 * Future: when the locked decision flips back to Meta Cloud API or BSP, swap
 * this adapter behind the WhatsAppAdapter interface and the agent path stays
 * unchanged. See al-moasis.md "WhatsApp" decision lock.
 */
import { type WASocket } from 'baileys';
interface SessionState {
    tenantId: string;
    /**
     * Per-account WhatsApp credential isolation. Default account is `'default'`
     * for backward compatibility with v1.0.x installs that have a single
     * paired number. SMBs running both a sales line and a support line pass
     * a stable accountId (e.g. 'sales' / 'support') and Baileys auth files
     * land under <dataDir>/whatsapp/<tenantId>/<accountId>/.
     */
    accountId: string;
    socket: WASocket | null;
    status: 'pending_qr' | 'connecting' | 'connected' | 'disconnected' | 'logged_out';
    lastQr: string | null;
    lastQrAt: number | null;
    authDir: string;
    reconnectTimer: NodeJS.Timeout | null;
    presenceTimer: NodeJS.Timeout | null;
    /**
     * Recent message cache — lets the Baileys getMessage callback satisfy
     * server-side retries for messages we've seen. Without this, certain
     * encrypted message types fail to decrypt and silently disappear.
     */
    recentMessages: Array<{
        msgId: string;
        jid: string;
        text: string;
    }>;
    jid: string | null;
    connectedSince: number | null;
    reconnectAttempts: number;
    lastReconnectAt: number | null;
    /**
     * (v2.5.5) Timestamp of the most recent FULLY-LOGGED-IN connection. Null
     * until the user has scanned the QR at least once. Used by the auto-
     * reconnect path to give up after N attempts when no QR has ever been
     * scanned — otherwise the adapter spins forever, floods the delivery
     * queue, and burns the rate-limit budget.
     */
    lastSuccessfulConnectAt: number | null;
    /**
     * (v2.5.5) "Reconnect circuit-breaker tripped" flag. When set, the auto-
     * reconnect loop is paused until the user explicitly calls
     * `startWhatsAppSession()` again (e.g. by re-opening the QR page in the
     * dashboard). Reset to false on any successful connect.
     */
    reconnectGivenUp: boolean;
    messagesToday: number;
    messagesTotal: number;
    lastMessagePreview: string | null;
    lastMessageAt: number | null;
    lastError: string | null;
}
export declare function startWhatsAppSession(tenantId: string, accountId?: string): Promise<SessionState>;
export interface WhatsAppSessionStatus {
    status: SessionState['status'];
    qr_ascii: string | null;
    qr_png: string | null;
    jid: string | null;
    last_qr_at: number | null;
    account_id: string;
    connected_since: number | null;
    reconnect_attempts: number;
    last_reconnect_at: number | null;
    messages_today: number;
    messages_total: number;
    last_message_preview: string | null;
    last_message_at: number | null;
    last_error: string | null;
    /** True when the dashboard should keep polling /qr because state hasn't settled. */
    needs_poll: boolean;
}
/**
 * READ-ONLY status peek. Does NOT call startWhatsAppSession, so dashboard
 * polling (GET /api/tenants/:id/whatsapp/status) cannot burn pair-attempt
 * budget. If no in-memory session exists, returns a synthetic
 * `disconnected` status with `needs_poll=false` so the dashboard knows to
 * stop polling until the user explicitly clicks "Generate QR" /
 * "Request code", which goes through getOrCreateSession.
 */
export declare function peekSession(tenantId: string, accountId?: string): Promise<WhatsAppSessionStatus>;
export declare function getOrCreateSession(tenantId: string, accountId?: string): Promise<WhatsAppSessionStatus>;
export declare function disconnectSession(tenantId: string, accountId?: string): Promise<void>;
/**
 * Hard-reset a WhatsApp session. Wipes Baileys auth files on disk, clears
 * in-memory session state, then returns. The next call to startWhatsAppSession()
 * will trigger a fresh QR pair.
 *
 * Used by:
 *   POST /api/tenants/:id/whatsapp/reset (dashboard "Re-pair" button)
 *   `moasis whatsapp reset` CLI command
 *
 * Why this exists: Baileys creds.json can land in a half-paired state when a
 * pairing is interrupted at the final handshake (very common: user closes the
 * QR page mid-scan, or the device is removed from WhatsApp's linked-devices
 * list later). The presence of stale `account` data without `registered:true`
 * makes the adapter refuse to generate a fresh QR. Wipe-and-retry is the
 * only reliable recovery.
 */
export declare function resetSession(tenantId: string, accountId?: string): Promise<void>;
/** List active WA sessions for a tenant — supports the multi-account UI. */
export declare function listSessionsForTenant(tenantId: string): Array<{
    accountId: string;
    status: string;
    jid: string | null;
}>;
/**
 * (v2.5.2) Is there a logged-in Baileys session for this tenant? Used by
 * delivery.ts to route around Cloud-API attempts when only Baileys is set up.
 */
export declare function isWhatsAppConnected(tenantId: string, accountId?: string): boolean;
/**
 * (v2.5.2) Send a text message via the tenant's Baileys session.
 * Throws if no session is connected. Returns the WA message id.
 */
/**
 * Request an 8-character pairing code for the given phone number. This is
 * the modern WhatsApp pairing flow that bypasses the QR scan entirely —
 * the user enters their phone in WA → "Link with phone number" → types
 * the 8-char code we return. Way more reliable than QR for fresh setups:
 *   • No camera / lighting / focus issues
 *   • No 20-second QR rotation race
 *   • Works on any device that can type
 *
 * Caller must have a Baileys session that's reached the QR/pending state
 * (not yet connected). The session keeps polling for the pair completion
 * the same way as the QR flow.
 */
export declare function requestPairingCode(tenantId: string, phoneNumber: string, accountId?: string): Promise<string>;
/**
 * Send a WA message to a raw JID (not a phone). Used by the approval-flow
 * endpoints — when an unknown sender hits the agent, we stash their
 * remoteJid (which may be @lid for unmapped 2025+ senders) and need to
 * reply to that exact JID, not via phone-based routing.
 */
export declare function sendBaileysMessageToJid(tenantId: string, remoteJid: string, text: string, accountId?: string): Promise<string>;
export declare function sendBaileysMessage(tenantId: string, to: string, text: string, accountId?: string): Promise<string>;
export {};
//# sourceMappingURL=baileys-adapter.d.ts.map