use crate::events::{ChatMessageEvent, ChatRequestEvent, DeliveryStatusEvent};

/// Callback type for statement subscriptions.
///
/// Using a named type alias avoids the `type_complexity` clippy lint on the
/// `subscribe` method and makes the intent clearer at call sites.
pub type StatementCallback = Box<dyn Fn(&[u8]) + Send>;

/// Transport adapter: statement submission and subscription.
///
/// Hosts implement this to connect the session manager to a Substrate
/// statement-store pallet (via RPC, light client, or test stub).
pub trait ChatTransport: Send + Sync {
    /// Submit a SCALE-encoded statement to the statement store.
    fn submit_statement(&self, encoded: &[u8]) -> Result<(), String>;

    /// Subscribe to one or more 32-byte topics.
    ///
    /// The `callback` is informational in v1 — the host must call
    /// `ChatManager::handle_incoming_statement` directly when statements
    /// arrive from the transport layer. A future version may use the
    /// callback for automatic delivery.
    ///
    /// The transport owns the subscription lifetime; call `unsubscribe` to cancel.
    fn subscribe(&self, topics: &[[u8; 32]], callback: StatementCallback) -> Result<(), String>;

    /// Cancel a previous subscription for the given topics.
    fn unsubscribe(&self, topics: &[[u8; 32]]) -> Result<(), String>;
}

/// Key-resolution adapter: peer P-256 public key lookup.
///
/// Hosts implement this to retrieve a peer's uncompressed P-256 identity
/// public key (65 bytes, 0x04 prefix) from the on-chain identity registry.
pub trait ChatKeyResolver: Send + Sync {
    /// Look up the uncompressed P-256 public key for an account.
    ///
    /// Returns an error string if the account has no registered key or if the
    /// lookup fails (network error, invalid encoding, etc.).
    fn resolve_p256_pubkey(&self, account_id: &[u8; 32]) -> Result<[u8; 65], String>;
}

/// Event-sink adapter: push decoded chat events to the SPA.
///
/// Hosts implement this to forward events to the UI layer (e.g., via a
/// channel, WebSocket, UniFFI callback, or test recorder).
pub trait ChatEventSink: Send + Sync {
    fn push_message(&self, event: ChatMessageEvent);
    fn push_delivery_status(&self, event: DeliveryStatusEvent);
    fn push_chat_request(&self, event: ChatRequestEvent);
}
