use crate::command::context::CommandContext;
use crate::command::handler::{CommandHandler, CommandMetadata};
use crate::command::response::{CommandError, CommandResponse, MessageKind};
use crate::command::Command;
use crate::storage::SessionStore;
use async_trait::async_trait;
use std::sync::Arc;

/// 列出话题命令处理器
pub struct ListSessionsCommandHandler {
    store: Arc<SessionStore>,
}

impl ListSessionsCommandHandler {
    pub fn new(store: Arc<SessionStore>) -> Self {
        Self { store }
    }
}

#[async_trait]
impl CommandHandler for ListSessionsCommandHandler {
    fn can_handle(&self, cmd: &Command) -> bool {
        matches!(cmd, Command::ListSessions { .. })
    }

    fn metadata(&self) -> Option<CommandMetadata> {
        Some(CommandMetadata {
            name: "list",
            description: "列出所有话题",
            usage: "/list [all]",
        })
    }

    async fn handle(
        &self,
        cmd: Command,
        ctx: CommandContext,
    ) -> Result<CommandResponse, CommandError> {
        match cmd {
            Command::ListSessions { include_archived } => {
                handle_list_sessions(self, include_archived, ctx).await
            }
            _ => unreachable!(),
        }
    }
}

async fn handle_list_sessions(
    handler: &ListSessionsCommandHandler,
    _include_archived: bool,
    ctx: CommandContext,
) -> Result<CommandResponse, CommandError> {
    let session_id = ctx.session_id.as_deref()
        .ok_or_else(|| CommandError::new("NO_SESSION", "No active session"))?;

    let topics = handler
        .store
        .list_topics(session_id)
        .map_err(|e| CommandError::new("LIST_TOPICS_ERROR", e.to_string()))?;

    let current_topic_id = ctx.topic_id.as_deref().unwrap_or("");

    let message = if topics.is_empty() {
        "No topics found. Use /new <title> to create a topic.".to_string()
    } else {
        let mut lines = vec![format!("Found {} topic(s):", topics.len())];
        lines.push(String::new());

        for (idx, topic) in topics.iter().enumerate() {
            let num = idx + 1;
            let is_current = topic.id == current_topic_id;
            let marker = if is_current { " *" } else { "" };

            // 使用辅助方法获取消息数量
            let msg_count = handler.store
                .get_topic_message_count(&topic.id)
                .unwrap_or(0);

            lines.push(format!(
                "{}. {}{} ({})",
                num, topic.title, marker, msg_count
            ));

            // 显示描述（如果有）
            if let Some(ref desc) = topic.description {
                if !desc.is_empty() {
                    lines.push(format!("   {}", desc));
                }
            }
        }

        lines.push(String::new());
        lines.push("* = current topic".to_string());
        lines.push("Use /use <number> to switch".to_string());

        lines.join("\n")
    };

    let topics_json = serde_json::to_string(&topics)
        .map_err(|e| CommandError::new("SERIALIZE_ERROR", e.to_string()))?;

    Ok(CommandResponse::success(ctx.request_id)
        .with_message(MessageKind::Notification, &message)
        .with_metadata("topics", &topics_json)
        .with_metadata("count", &topics.len().to_string())
        .with_metadata("current_topic_id", current_topic_id))
}