use anyhow::Result;

// -- JetStream stream name constants --

/// Stream for wipe lifecycle events (scheduled, started, completed, failed, rolled_back).
pub const STREAM_WIPE_EVENTS: &str = "CORROSION_WIPE";

/// Stream for server telemetry (stats, status changes, crash events).
pub const STREAM_SERVER_TELEMETRY: &str = "CORROSION_TELEMETRY";

/// Stream for agent commands and responses (start, stop, file ops).
pub const STREAM_AGENT_COMMANDS: &str = "CORROSION_AGENT";

/// Stream for Steam update detection events.
pub const STREAM_STEAM_UPDATES: &str = "CORROSION_STEAM";

/// Stream for notification delivery (Discord, Pushbullet, email).
pub const STREAM_NOTIFICATIONS: &str = "CORROSION_NOTIFY";

/// Stream for license lifecycle events (activated, expired, check-in).
pub const STREAM_LICENSE_EVENTS: &str = "CORROSION_LICENSE";

/// NATS JetStream pub/sub bridge.
///
/// Centralizes all NATS interactions: stream/consumer setup, publishing
/// events, and subscribing to subjects. All services go through the
/// bridge rather than holding their own NATS client references, ensuring
/// consistent subject naming and stream configuration.
pub struct NatsBridge {
    pub client: async_nats::Client,
}

impl NatsBridge {
    pub fn new(client: async_nats::Client) -> Self {
        Self { client }
    }

    /// Publish a message to a NATS subject.
    pub async fn publish(&self, _subject: &str, _payload: &[u8]) -> Result<()> {
        // TODO: Publish via self.client.publish(subject, payload)
        // TODO: Optionally publish to JetStream if subject belongs to a stream
        todo!()
    }

    /// Subscribe to a NATS subject and return a message stream.
    pub async fn subscribe(
        &self,
        _subject: &str,
    ) -> Result<async_nats::Subscriber> {
        // TODO: Subscribe via self.client.subscribe(subject)
        // TODO: For durable consumers, use JetStream consumer API
        todo!()
    }

    /// Initialize all JetStream streams and consumers.
    ///
    /// Called once at application startup. Creates streams if they don't
    /// exist, updates configuration if streams already exist.
    pub async fn setup_streams(&self) -> Result<()> {
        // TODO: Get JetStream context from client
        // TODO: Create/update CORROSION_WIPE stream
        //   subjects: ["corrosion.*.wipe.>"]
        //   retention: WorkQueue, max_age: 7 days
        // TODO: Create/update CORROSION_TELEMETRY stream
        //   subjects: ["corrosion.*.telemetry.>"]
        //   retention: Limits, max_age: 24 hours
        // TODO: Create/update CORROSION_AGENT stream
        //   subjects: ["corrosion.*.agent.>"]
        //   retention: WorkQueue, max_age: 1 hour
        // TODO: Create/update CORROSION_STEAM stream
        //   subjects: ["corrosion.steam.>"]
        //   retention: Limits, max_age: 30 days
        // TODO: Create/update CORROSION_NOTIFY stream
        //   subjects: ["corrosion.*.notify.>"]
        //   retention: WorkQueue, max_age: 1 day
        // TODO: Create/update CORROSION_LICENSE stream
        //   subjects: ["corrosion.license.>"]
        //   retention: Limits, max_age: 90 days
        todo!()
    }
}
