use std::sync::Arc;

use chrono::Utc;
use db::cache::AppCache;
use db::database::AppDatabase;
use queue::MessageProducer;
use uuid::Uuid;

use super::sequence::next_room_message_seq_internal;
use crate::connection::RoomConnectionManager;
use crate::error::RoomError;

pub async fn create_and_publish_ai_message(
    db: &AppDatabase,
    cache: &AppCache,
    queue: &MessageProducer,
    room_manager: &Arc<RoomConnectionManager>,
    room_id: Uuid,
    project_id: Uuid,
    _reply_to: Uuid,
    content: String,
    model_id: Uuid,
    model_display_name: Option<String>,
) -> Result<Uuid, RoomError> {
    let now = Utc::now();
    let seq = next_room_message_seq_internal(room_id, db, cache).await?;
    let id = Uuid::now_v7();

    let envelope = queue::RoomMessageEnvelope {
        id,
        dedup_key: Some(format!("{}:{}", room_id, id)),
        room_id,
        sender_type: "ai".to_string(),
        sender_id: None,
        model_id: Some(model_id),
        thread_id: None,
        content: content.clone(),
        content_type: "text".to_string(),
        thinking_content: None,
        send_at: now,
        seq,
        in_reply_to: None,
        display_name: model_display_name.clone(),
    };

    queue.publish(room_id, envelope).await?;
    room_manager.metrics.messages_sent.increment(1);

    let event = queue::RoomMessageEvent {
        id,
        room_id,
        sender_type: "ai".to_string(),
        sender_id: None,
        thread_id: None,
        content: content.clone(),
        content_type: "text".to_string(),
        thinking_content: None,
        send_at: now,
        seq,
        display_name: model_display_name,
        in_reply_to: None,
        reactions: None,
        message_id: None,
    };
    room_manager.broadcast(room_id, event).await;

    super::notifications::publish_room_event(
        queue,
        project_id,
        crate::RoomEventType::NewMessage,
        Some(room_id),
        Some(id),
        Some(seq),
    );

    Ok(id)
}
