use crate::db::{Item, Meta, Tag};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
/// Structure representing an item with its associated tags and metadata.
///
/// This is a composite type used for querying and displaying items with their relational data.
/// It combines the core Item with lists of Tags and Meta for complete item representation.
pub struct ItemWithMeta {
    /// The core item data.
    pub item: Item,
    /// Associated tags.
    pub tags: Vec<Tag>,
    /// Associated metadata.
    pub meta: Vec<Meta>,
}

impl ItemWithMeta {
    /// Converts metadata to a HashMap for easy lookup.
    ///
    /// This method transforms the vec of Meta into a simple key-value map,
    /// useful for quick access by metadata name.
    ///
    /// # Returns
    ///
    /// `HashMap<String, String>` - Metadata as key-value pairs, where keys are names and values are strings.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// let item_with_meta = ItemWithMeta { /* ... */ };
    /// let meta_map = item_with_meta.meta_as_map();
    /// assert_eq!(meta_map.get("hostname"), Some(&"example.com".to_string()));
    /// ```
    pub fn meta_as_map(&self) -> HashMap<String, String> {
        self.meta
            .iter()
            .cloned()
            .map(|m| (m.name, m.value))
            .collect()
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
/// Structure representing an item with its content, tags, and metadata.
///
/// This extends ItemWithMeta by including the actual content bytes, suitable for full item retrieval
/// including binary or text data. Note: For large content, consider streaming alternatives.
pub struct ItemWithContent {
    /// Item with associated metadata and tags.
    pub item_with_meta: ItemWithMeta,
    /// The content bytes.
    pub content: Vec<u8>,
}
