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

/// 切换话题命令处理器
pub struct SwitchTopicCommandHandler {
    store: Arc<SessionStore>,
    session_manager: Option<SessionManager>,
}

impl SwitchTopicCommandHandler {
    pub fn new(store: Arc<SessionStore>) -> Self {
        Self { store, session_manager: None }
    }

    pub fn with_session_manager(mut self, session_manager: SessionManager) -> Self {
        self.session_manager = Some(session_manager);
        self
    }
}

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

    fn metadata(&self) -> Option<CommandMetadata> {
        Some(CommandMetadata {
            name: "use",
            description: "切换到指定话题",
            usage: "/use <topic_id>",
        })
    }

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

async fn handle_switch_topic(
    handler: &SwitchTopicCommandHandler,
    topic_id: String,
    ctx: CommandContext,
) -> Result<CommandResponse, CommandError> {
    let session_id = ctx.session_id.as_deref()
        .ok_or_else(|| CommandError::new("NO_SESSION", "No active session"))?;
    let chat_id = ctx.chat_id.as_deref()
        .ok_or_else(|| CommandError::new("NO_CHAT_ID", "No chat_id in context"))?;

    // 尝试解析为序号
    let target_topic_id = if let Ok(index) = topic_id.parse::<usize>() {
        let topics = handler
            .store
            .list_topics(session_id)
            .map_err(|e| CommandError::new("LIST_TOPICS_ERROR", e.to_string()))?;

        let index = index.saturating_sub(1);
        if index >= topics.len() {
            return Err(CommandError::new(
                "INVALID_TOPIC_INDEX",
                format!("Topic index {} is out of range (1-{})", index + 1, topics.len())
            ));
        }
        topics[index].id.clone()
    } else {
        topic_id
    };

    // 验证目标话题存在
    let topic = handler
        .store
        .get_topic(&target_topic_id)
        .map_err(|e| CommandError::new("SWITCH_TOPIC_ERROR", e.to_string()))?
        .ok_or_else(|| CommandError::new("TOPIC_NOT_FOUND", format!("Topic not found: {}", target_topic_id)))?;

    // 如果有 SessionManager，实际切换话题历史
    if let Some(ref session_manager) = handler.session_manager {
        if let Some(session) = session_manager.get(&ctx.channel_name).await {
            let mut session_guard = session.lock().await;
            session_guard.switch_topic(chat_id, &target_topic_id)
                .map_err(|e| CommandError::new("SWITCH_TOPIC_ERROR", e.to_string()))?;
        }
    }

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

    let message = format!(
        "✓ Switched to topic: {} ({} messages)",
        topic.title, msg_count
    );

    Ok(CommandResponse::success(ctx.request_id)
        .with_message(MessageKind::Notification, &message)
        .with_metadata("topic_id", &topic.id)
        .with_metadata("title", &topic.title)
        .with_metadata("message_count", &msg_count.to_string()))
}
