pub const CATEGORY_VIDEOS: &str = "videos";
pub const CATEGORY_SEARCH: &str = "search";
pub const CATEGORY_HYBRID_SEARCH: &str = "hybrid_search";
pub const CATEGORY_N8N_SEARCH: &str = "n8n_search";
pub const CATEGORY_VIDEO_META: &str = "video_meta";
pub const CATEGORY_HEALTH: &str = "health";

pub const KEY_PREFIX_VIDEOS_LIST: &str = "videos:list:";
pub const KEY_PREFIX_VIDEO: &str = "video:";
pub const KEY_PREFIX_SEARCH: &str = "search:";
pub const KEY_PREFIX_SEARCH_HYBRID: &str = "search:hybrid:";
pub const KEY_PREFIX_SEARCH_N8N: &str = "search:n8n:";
pub const KEY_PREFIX_SEARCH_BM25: &str = "search:bm25:";
pub const KEY_PREFIX_SEARCH_N8N_BM25: &str = "search:n8n:bm25:";
pub const KEY_HEALTH: &str = "health:basic";

pub fn videos_list(page: usize, limit: usize) -> String {
    format!("{}page={}:limit={}", KEY_PREFIX_VIDEOS_LIST, page, limit)
}

pub fn video_meta(uuid: &str) -> String {
    format!("{}{}", KEY_PREFIX_VIDEO, uuid)
}

pub fn search(query_hash: &str) -> String {
    format!("{}{}", KEY_PREFIX_SEARCH, query_hash)
}

pub fn hybrid_search(query_hash: &str) -> String {
    format!("{}{}", KEY_PREFIX_SEARCH_HYBRID, query_hash)
}

pub fn n8n_search(query_hash: &str) -> String {
    format!("{}{}", KEY_PREFIX_SEARCH_N8N, query_hash)
}

pub fn bm25_search(query_hash: &str) -> String {
    format!("{}{}", KEY_PREFIX_SEARCH_BM25, query_hash)
}

pub fn n8n_bm25_search(query_hash: &str) -> String {
    format!("{}{}", KEY_PREFIX_SEARCH_N8N_BM25, query_hash)
}

pub fn health() -> String {
    KEY_HEALTH.to_string()
}

pub fn videos_list_prefix() -> String {
    format!("^{}", KEY_PREFIX_VIDEOS_LIST)
}

pub fn video_prefix(uuid: &str) -> String {
    format!("^{}{}", KEY_PREFIX_VIDEO, uuid)
}

pub fn search_prefix() -> String {
    format!("^{}", KEY_PREFIX_SEARCH)
}

pub const KEY_PREFIX_VISUAL_SEARCH: &str = "search:visual:";
pub const CATEGORY_VISUAL_SEARCH: &str = "visual_search";

pub fn visual_search(uuid: &str, criteria_hash: &str) -> String {
    format!("{}{}:{}", KEY_PREFIX_VISUAL_SEARCH, uuid, criteria_hash)
}

pub fn visual_search_prefix() -> String {
    format!("^{}", KEY_PREFIX_VISUAL_SEARCH)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_videos_list() {
        assert_eq!(videos_list(1, 20), "videos:list:page=1:limit=20");
        assert_eq!(videos_list(2, 50), "videos:list:page=2:limit=50");
    }

    #[test]
    fn test_video_meta() {
        assert_eq!(video_meta("abc123"), "video:abc123");
    }

    #[test]
    fn test_search() {
        assert_eq!(search("hash123"), "search:hash123");
    }

    #[test]
    fn test_hybrid_search() {
        assert_eq!(hybrid_search("hash123"), "search:hybrid:hash123");
    }

    #[test]
    fn test_n8n_search() {
        assert_eq!(n8n_search("hash123"), "search:n8n:hash123");
    }

    #[test]
    fn test_bm25_search() {
        assert_eq!(bm25_search("hash123"), "search:bm25:hash123");
    }

    #[test]
    fn test_n8n_bm25_search() {
        assert_eq!(n8n_bm25_search("hash123"), "search:n8n:bm25:hash123");
    }

    #[test]
    fn test_health() {
        assert_eq!(health(), "health:basic");
    }

    #[test]
    fn test_visual_search() {
        assert_eq!(visual_search("abc123", "hash"), "search:visual:abc123:hash");
    }

    #[test]
    fn test_visual_search_prefix() {
        assert_eq!(visual_search_prefix(), "^search:visual:");
    }
}
