use crate::cache::{get_hash, get_str};
use crate::get_hash_all_values;
use cal_core::Region;
use redis::aio::MultiplexedConnection;
use redis::AsyncCommands;
use std::collections::HashMap;

pub async fn get_regions(con: MultiplexedConnection) -> HashMap<String, Region> {
    let mut regions = HashMap::<String, Region>::new();
    let result = get_hash_all_values(con.clone(), "cb:regions").await;
    for id in result.values() {
        if !regions.contains_key(id) {
            if let Some(region) = get_region_by_id(con.clone(), id.clone()).await {
                regions.insert(id.to_string(), region);
            }
        }
    }
    regions
}

pub async fn get_region_by_ident(con: MultiplexedConnection, key: &str) -> Option<Region> {
    match get_hash(con.clone(), "cb:regions", key).await {
        None => None,
        Some(value) => {
            get_region_by_id(con, value.clone()).await
        }
    }
}

pub async fn get_region_by_id(con: MultiplexedConnection, key: String) -> Option<Region> {
    let _key = format!("cb:region:{}", key);
    match get_str(con, &_key).await {
        None => None,
        Some(value) => {
            let region: Region = serde_json::from_str(&value).unwrap();
            Some(region)
        }
    }
}

pub async fn insert_region(mut con: MultiplexedConnection, region: Region) {
    let key = format!("cb:region:{}", region.id.clone());
    let value = serde_json::to_string(&region).unwrap();
    if let Err(e) = con.set::<String, String, String>(key, value).await {
        println!("Cache Error - Could not insert Region: {}", e);
    };
}

pub async fn insert_region_idents(mut con: MultiplexedConnection, items: Vec<(String, String)>) {
    if let Err(e) = con
        .hset_multiple::<&str, String, String, String>("cb:regions", &*items)
        .await
    {
        println!("Cache Error {:?}", e);
    }
}
