//! Content utilities using trait-based dependency injection

use crate::*;

/// Simple content item implementation
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SimpleContentItem {
    /// Content metadata
    pub metadata: ContentMetadata,
    /// Content body
    pub body: String,
    /// Content format (markdown, html, etc.)
    pub format: String,
}

impl SimpleContentItem {
    /// Create new content item
    pub fn new(metadata: ContentMetadata, body: String, format: String) -> Self {
        Self {
            metadata,
            body,
            format,
        }
    }
}

/// Simple content query for filtering
#[derive(Debug, Clone)]
pub struct SimpleContentQuery {
    /// Content type filter
    pub content_type: Option<String>,
    /// Tag filter
    pub tags: Vec<String>,
    /// Category filter
    pub category: Option<String>,
    /// Published status filter
    pub published_only: bool,
    /// Limit results
    pub limit: Option<usize>,
}

impl SimpleContentQuery {
    /// Create new query
    pub fn new() -> Self {
        Self {
            content_type: None,
            tags: Vec::new(),
            category: None,
            published_only: true,
            limit: None,
        }
    }

    /// Filter by content type
    pub fn content_type(mut self, content_type: impl Into<String>) -> Self {
        self.content_type = Some(content_type.into());
        self
    }

    /// Filter by tags
    pub fn tags(mut self, tags: Vec<String>) -> Self {
        self.tags = tags;
        self
    }

    /// Filter by category
    pub fn category(mut self, category: impl Into<String>) -> Self {
        self.category = Some(category.into());
        self
    }

    /// Include unpublished content
    pub fn include_unpublished(mut self) -> Self {
        self.published_only = false;
        self
    }

    /// Limit results
    pub fn limit(mut self, limit: usize) -> Self {
        self.limit = Some(limit);
        self
    }
}

impl Default for SimpleContentQuery {
    fn default() -> Self {
        Self::new()
    }
}

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

    #[test]
    fn test_simple_content_item() {
        let metadata = ContentMetadata {
            id: "test".to_string(),
            title: "Test Content".to_string(),
            description: Some("Test description".to_string()),
            author: Some("Test Author".to_string()),
            published_date: None,
            modified_date: None,
            tags: vec!["test".to_string()],
            category: Some("test".to_string()),
            language: "en".to_string(),
            content_type: "blog".to_string(),
            is_published: true,
            is_featured: false,
            custom_fields: HashMap::new(),
        };

        let item = SimpleContentItem::new(
            metadata.clone(),
            "Test body".to_string(),
            "markdown".to_string(),
        );

        assert_eq!(item.metadata.title, "Test Content");
        assert_eq!(item.body, "Test body");
        assert_eq!(item.format, "markdown");
    }

    #[test]
    fn test_simple_content_query() {
        let query = SimpleContentQuery::new()
            .content_type("blog")
            .tags(vec!["rust".to_string(), "web".to_string()])
            .category("tech")
            .limit(10);

        assert_eq!(query.content_type, Some("blog".to_string()));
        assert_eq!(query.tags, vec!["rust", "web"]);
        assert_eq!(query.category, Some("tech".to_string()));
        assert_eq!(query.limit, Some(10));
        assert!(query.published_only);
    }
}
