//! Slack conversation history persistence.

use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::Mutex as TokioMutex;

use crate::chat::history::{load_chat_history, save_chat_history};
use crate::chat::transport::matrix::RoomConversation;

/// Per-channel conversation history, keyed by channel ID.
pub type SlackConversationHistory = Arc<TokioMutex<HashMap<String, RoomConversation>>>;

/// Path to the persisted Slack conversation history file.
const SLACK_HISTORY_FILE: &str = ".huskies/slack_history.json";

/// Load Slack conversation history from disk.
pub fn load_slack_history(project_root: &std::path::Path) -> HashMap<String, RoomConversation> {
    load_chat_history(project_root, SLACK_HISTORY_FILE, "slack")
}

/// Save Slack conversation history to disk.
pub(super) fn save_slack_history(
    project_root: &std::path::Path,
    history: &HashMap<String, RoomConversation>,
) {
    save_chat_history(project_root, SLACK_HISTORY_FILE, "slack", history);
}

// ── Tests ───────────────────────────────────────────────────────────────

#[cfg(test)]
mod tests {
    use super::*;
    use crate::chat::transport::matrix::{ConversationEntry, ConversationRole};

    #[test]
    fn save_and_load_slack_history_round_trips() {
        let tmp = tempfile::tempdir().unwrap();
        let sk = tmp.path().join(".huskies");
        std::fs::create_dir_all(&sk).unwrap();

        let mut history = HashMap::new();
        history.insert(
            "C01ABCDEF".to_string(),
            RoomConversation {
                session_id: Some("sess-abc".to_string()),
                entries: vec![
                    ConversationEntry {
                        role: ConversationRole::User,
                        sender: "U01GHIJKL".to_string(),
                        content: "hello".to_string(),
                    },
                    ConversationEntry {
                        role: ConversationRole::Assistant,
                        sender: String::new(),
                        content: "hi there!".to_string(),
                    },
                ],
                ..Default::default()
            },
        );

        save_slack_history(tmp.path(), &history);
        let loaded = load_slack_history(tmp.path());

        assert_eq!(loaded.len(), 1);
        let conv = loaded.get("C01ABCDEF").unwrap();
        assert_eq!(conv.session_id.as_deref(), Some("sess-abc"));
        assert_eq!(conv.entries.len(), 2);
        assert_eq!(conv.entries[0].content, "hello");
        assert_eq!(conv.entries[1].content, "hi there!");
    }

    #[test]
    fn load_slack_history_returns_empty_when_file_missing() {
        let tmp = tempfile::tempdir().unwrap();
        let history = load_slack_history(tmp.path());
        assert!(history.is_empty());
    }

    #[test]
    fn load_slack_history_returns_empty_on_invalid_json() {
        let tmp = tempfile::tempdir().unwrap();
        let sk = tmp.path().join(".huskies");
        std::fs::create_dir_all(&sk).unwrap();
        std::fs::write(sk.join("slack_history.json"), "not json {{{").unwrap();
        let history = load_slack_history(tmp.path());
        assert!(history.is_empty());
    }
}
