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 LoadTopicCommandHandler {
    store: Arc<SessionStore>,
}

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

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

    fn metadata(&self) -> Option<CommandMetadata> {
        Some(CommandMetadata {
            name: "load",
            description: "加载指定话题",
            usage: "/load <topic_id>",
        })
    }

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

async fn handle_load_topic(
    handler: &LoadTopicCommandHandler,
    topic_id: String,
    ctx: CommandContext,
) -> Result<CommandResponse, CommandError> {
    let topic = handler
        .store
        .get_topic(&topic_id)
        .map_err(|e| CommandError::new("LOAD_TOPIC_ERROR", e.to_string()))?
        .ok_or_else(|| CommandError::new("TOPIC_NOT_FOUND", format!("Topic not found: {}", topic_id)))?;

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