//! Matrix bot integration for Story Kit.
//!
//! When a `.storkit/bot.toml` file is present with `enabled = true`, the
//! server spawns a Matrix bot that:
//!
//! 1. Connects to the configured homeserver and joins the configured room.
//! 2. Listens for messages from other users in the room.
//! 3. Passes each message to Claude Code (the same provider as the web UI),
//!    which has native access to Story Kit MCP tools.
//! 4. Posts Claude Code's response back to the room.
//!
//! The bot is optional — if `bot.toml` is missing or `enabled = false`, the
//! server starts normally with no Matrix connection.
//!
//! Multi-room support: configure `room_ids = ["!room1:…", "!room2:…"]` in
//! `bot.toml`. Each room maintains its own independent conversation history.

pub mod assign;
mod bot;
pub mod commands;
pub(crate) mod config;
pub mod delete;
pub mod htop;
pub mod rebuild;
pub mod reset;
pub mod rmtree;
pub mod start;
pub mod notifications;
pub mod transport_impl;

pub use bot::{ConversationEntry, ConversationRole, RoomConversation};
pub use config::BotConfig;

use crate::agents::AgentPool;
use crate::http::context::PermissionForward;
use crate::io::watcher::WatcherEvent;
use crate::rebuild::ShutdownReason;
use std::path::Path;
use std::sync::Arc;
use tokio::sync::{Mutex as TokioMutex, broadcast, mpsc, watch};

/// Attempt to start the Matrix bot.
///
/// Reads the bot configuration from `.storkit/bot.toml`. If the file is
/// absent or `enabled = false`, this function returns immediately without
/// spawning anything — the server continues normally.
///
/// When the bot is enabled, a notification listener is also spawned that
/// posts stage-transition messages to all configured rooms whenever a work
/// item moves between pipeline stages.
///
/// `perm_rx` is the permission-request receiver shared with the MCP
/// `prompt_permission` tool. The bot locks it during active chat sessions
/// to surface permission prompts to the Matrix room and relay user decisions.
///
/// `shutdown_rx` is a watch channel that delivers a `ShutdownReason` when the
/// server is about to stop (SIGINT/SIGTERM or rebuild).  The bot uses this to
/// announce the shutdown to all configured rooms before the process exits.
///
/// Must be called from within a Tokio runtime context (e.g., from `main`).
pub fn spawn_bot(
    project_root: &Path,
    watcher_tx: broadcast::Sender<WatcherEvent>,
    perm_rx: Arc<TokioMutex<mpsc::UnboundedReceiver<PermissionForward>>>,
    agents: Arc<AgentPool>,
    shutdown_rx: watch::Receiver<Option<ShutdownReason>>,
) {
    let config = match BotConfig::load(project_root) {
        Some(c) => c,
        None => {
            crate::slog!("[matrix-bot] bot.toml absent or disabled; Matrix integration skipped");
            return;
        }
    };

    // WhatsApp and Slack transports are handled via HTTP webhooks, not the Matrix sync loop.
    if config.transport == "whatsapp" || config.transport == "slack" {
        crate::slog!(
            "[bot] transport={} — skipping Matrix bot; webhooks handle this transport",
            config.transport
        );
        return;
    }

    crate::slog!(
        "[matrix-bot] Starting Matrix bot → homeserver={} rooms={:?}",
        config.homeserver.as_deref().unwrap_or("(none)"),
        config.effective_room_ids()
    );

    let root = project_root.to_path_buf();
    let watcher_rx = watcher_tx.subscribe();
    let watcher_rx_auto = watcher_tx.subscribe();
    tokio::spawn(async move {
        if let Err(e) =
            bot::run_bot(config, root, watcher_rx, watcher_rx_auto, perm_rx, agents, shutdown_rx)
                .await
        {
            crate::slog!("[matrix-bot] Fatal error: {e}");
        }
    });
}
