use serde::{Deserialize, Serialize};

/// How Dirigent connects to Matrix.
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum MatrixConnectionMode {
    /// Dedicated bot user with username/password login (existing behavior).
    #[default]
    Bot,
    /// Appservice-provisioned virtual user with stored access token.
    Provisioned,
}

/// A persistent Matrix room defined in configuration.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PersistentRoom {
    /// Human-readable label for this room (shown in room picker).
    pub label: String,
    /// Matrix room ID (e.g. "!abc:matrix.org").
    pub room_id: String,
}

/// Matrix sharing behavior — separate from identity.
///
/// Identity and credentials come from an Account referenced by name.
/// This struct only defines sharing behavior.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatrixBehaviorConfig {
    /// Account name (key in [accounts.*]) for the Matrix connection.
    pub account: String,
    /// Connection mode: "bot" (default) or "provisioned".
    #[serde(default)]
    pub mode: MatrixConnectionMode,
    /// Matrix user IDs to invite to newly created share rooms.
    #[serde(default)]
    pub default_invite: Vec<String>,
    /// Directory for matrix-sdk SQLite store (relative to DIRIGENT_DATA_DIR).
    #[serde(default = "default_store_path")]
    pub store_path: String,
    /// Pre-defined rooms that always appear in the room selection UI.
    #[serde(default)]
    pub rooms: Vec<PersistentRoom>,
}

fn default_store_path() -> String {
    "matrix/bot/store".to_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_default_mode_is_bot() {
        let json = r#"{"account": "matrix-bot"}"#;
        let config: MatrixBehaviorConfig = serde_json::from_str(json).unwrap();
        assert_eq!(config.mode, MatrixConnectionMode::Bot);
    }

    #[test]
    fn test_provisioned_mode() {
        let json = r#"{"account": "matrix-virt", "mode": "provisioned"}"#;
        let config: MatrixBehaviorConfig = serde_json::from_str(json).unwrap();
        assert_eq!(config.mode, MatrixConnectionMode::Provisioned);
    }

    #[test]
    fn test_bot_mode_explicit() {
        let json = r#"{"account": "matrix-bot", "mode": "bot"}"#;
        let config: MatrixBehaviorConfig = serde_json::from_str(json).unwrap();
        assert_eq!(config.mode, MatrixConnectionMode::Bot);
    }
}
