use config::{Config, ConfigError, File};
use serde::Deserialize;
use std::collections::HashMap;

#[derive(Debug, Deserialize)]
pub struct Account {
    pub username: String,
    pub password: String,
}

#[derive(Debug, Deserialize)]
pub struct Settings {
    redis: Option<HashMap<String, String>>,
    api: Option<HashMap<String, String>>,
    accounts: Option<HashMap<String, Account>>,
    cron: Option<HashMap<String, Vec<String>>>,
}

pub fn load_config() -> Result<Settings, ConfigError> {
    let settings = Config::builder()
        .add_source(File::with_name("config"))
        .build()?
        .try_deserialize::<Settings>()?;

    Ok(settings)
}

pub fn get_config(config: &Settings, section: &str) -> String {
    match section {
        "redis" => {
            if let Some(redis_map) = &config.redis {
                redis_map.get("url").cloned().unwrap_or_default()
            } else {
                println!("Redis configuration not found.");
                String::new()
            }
        }
        "api" => {
            if let Some(api_map) = &config.api {
                api_map.get("url").cloned().unwrap_or_default()
            } else {
                String::new()
            }
        }
        "token" => {
            if let Some(api_map) = &config.api {
                api_map.get("token").cloned().unwrap_or_default()
            } else {
                String::new()
            }
        }
        _ => String::new(),
    }
}

pub fn get_cron(config: &Settings, section: &str) -> Vec<String> {
    if let Some(map) = &config.cron {
        map.get(section).cloned().unwrap_or_default()
    } else {
        Vec::new()
    }
}

pub fn get_account_by_class<'a>(config: &'a Settings, class_name: &str) -> Option<&'a Account> {
    config
        .accounts
        .as_ref()
        .and_then(|accounts| accounts.get(class_name))
}

pub fn list_classes(config: &Settings) -> Vec<String> {
    config
        .accounts
        .as_ref()
        .map(|accounts| accounts.keys().cloned().collect())
        .unwrap_or_default()
}
