//! Matrix room creation and management helpers.

use matrix_sdk::{
    ruma::{
        api::client::room::create_room::v3::{
            CreationContent, Request as CreateRoomRequest, RoomPreset,
        },
        OwnedRoomId, OwnedUserId,
    },
    Client,
};
use tracing::debug;

/// Options for creating a new Matrix room for session sharing.
pub struct CreateRoomOptions {
    /// Human-readable room name.
    pub name: String,
    /// Optional room topic.
    pub topic: Option<String>,
    /// Matrix user IDs (as strings, e.g. "@user:example.com") to invite at
    /// creation time.  Invalid IDs are silently skipped.
    pub invite: Vec<String>,
}

/// Create a private, non-federated Matrix room for bridging a Dirigent session.
///
/// The room is configured as a `PrivateChat` (invite-only, shared history) and
/// the `m.federate` flag is disabled so the room does not appear on remote
/// homeservers.
///
/// # Errors
///
/// Returns [`crate::MatrixError::NotLoggedIn`] if the client is not authenticated.
/// Other errors propagate from the Matrix SDK.
pub async fn create_share_room(
    client: &Client,
    options: CreateRoomOptions,
) -> crate::Result<OwnedRoomId> {
    if !client.logged_in() {
        return Err(crate::MatrixError::NotLoggedIn);
    }

    let invite: Vec<OwnedUserId> = options
        .invite
        .iter()
        .filter_map(|id| id.parse::<OwnedUserId>().ok())
        .collect();

    let mut request = CreateRoomRequest::new();
    request.name = Some(options.name.clone());
    request.topic = options.topic.clone();
    request.invite = invite;
    request.preset = Some(RoomPreset::PrivateChat);

    // Disable federation so the room stays on the local homeserver.
    let mut creation_content = CreationContent::new();
    creation_content.federate = false;
    request.creation_content =
        Some(matrix_sdk::ruma::serde::Raw::new(&creation_content).map_err(|e| {
            crate::MatrixError::Config(format!(
                "Failed to serialize creation content: {}",
                e
            ))
        })?);

    debug!(room_name = %options.name, "Creating Matrix share room");

    let room = client.create_room(request).await?;
    Ok(room.room_id().to_owned())
}

/// Generate a human-readable Matrix room name for a session.
///
/// Format: `"Dirigent: <session_title>"` or `"Dirigent: <connector_id>"` when
/// no title is available.
pub fn room_name_for_session(connector_id: &str, session_title: Option<&str>) -> String {
    match session_title.filter(|t| !t.is_empty()) {
        Some(title) => format!("Dirigent: {}", title),
        None => format!("Dirigent: {}", connector_id),
    }
}
