use crate::domain::theme::{Theme, ThemeRepository};

pub fn list_themes(repo: &dyn ThemeRepository) -> Vec<Theme> {
    repo.list()
}

pub fn get_theme_css(repo: &dyn ThemeRepository, id: &str) -> Option<String> {
    repo.get_css(id)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::domain::theme::{Theme, ThemeRepository};

    struct MockRepo {
        themes: Vec<(&'static str, &'static str, &'static str)>,
    }

    impl ThemeRepository for MockRepo {
        fn list(&self) -> Vec<Theme> {
            self.themes.iter().map(|(id, label, _)| Theme { id: id.to_string(), label: label.to_string() }).collect()
        }
        fn get_css(&self, id: &str) -> Option<String> {
            self.themes.iter().find(|(i, _, _)| *i == id).map(|(_, _, css)| css.to_string())
        }
    }

    fn mock_repo() -> MockRepo {
        MockRepo {
            themes: vec![
                ("dark", "Mode sombre", ".content{background:#000}"),
                ("light", "Clair", ".content{background:#fff}"),
            ],
        }
    }

    #[test]
    fn list_themes_delegates_to_repo() {
        let repo = mock_repo();
        let themes = list_themes(&repo);
        assert_eq!(themes.len(), 2);
        assert_eq!(themes[0].id, "dark");
        assert_eq!(themes[1].label, "Clair");
    }

    #[test]
    fn get_theme_css_returns_css_for_known_id() {
        let repo = mock_repo();
        let css = get_theme_css(&repo, "dark");
        assert_eq!(css, Some(".content{background:#000}".to_string()));
    }

    #[test]
    fn get_theme_css_returns_none_for_unknown_id() {
        let repo = mock_repo();
        assert!(get_theme_css(&repo, "unknown").is_none());
    }
}
