use std::sync::Arc;

use crate::agent::{AgentError, EmittedMessageHandler};
use crate::bus::{MediaItem, OutboundMessage};

use super::execution::{AgentExecutionService, MessageExecutionRequest};
use super::session_lifecycle::SessionLifecycleService;

#[derive(Clone)]
pub(crate) struct SessionMessageService {
    lifecycle: SessionLifecycleService,
    show_tool_results: bool,
}

impl SessionMessageService {
    pub(crate) fn new(lifecycle: SessionLifecycleService, show_tool_results: bool) -> Self {
        Self {
            lifecycle,
            show_tool_results,
        }
    }

    pub(crate) async fn handle_message(
        &self,
        channel_name: &str,
        sender_id: &str,
        chat_id: &str,
        content: &str,
        media: Vec<MediaItem>,
        live_emitter: Option<Arc<dyn EmittedMessageHandler>>,
    ) -> Result<Vec<OutboundMessage>, AgentError> {
        #[cfg(debug_assertions)]
        {
            tracing::debug!(
                channel = %channel_name,
                chat_id = %chat_id,
                content_len = content.len(),
                media_count = %media.len(),
                "Routing message to agent"
            );
            for (i, m) in media.iter().enumerate() {
                tracing::debug!(media_index = i, media_type = %m.media_type, path = %m.path, "Media in handle_message");
            }
        }

        let session = self.lifecycle.active_session(channel_name).await?;

        let outbound_messages = AgentExecutionService::new(self.show_tool_results)
            .prepare_and_execute_message(MessageExecutionRequest {
                session,
                channel_name,
                sender_id,
                chat_id,
                content,
                media,
                live_emitter,
            })
            .await?;

        #[cfg(debug_assertions)]
        tracing::debug!(
            channel = %channel_name,
            chat_id = %chat_id,
            outbound_count = outbound_messages.len(),
            "Agent response sequence received"
        );

        Ok(outbound_messages)
    }
}
