//! Domain types for {{TOOL_NAME}}
//!
//! Core data structures used throughout {{TOOL_NAME}}.

use serde::{Deserialize, Serialize};
use uuid::Uuid;
use chrono::{DateTime, Utc};

/// Primary entity type for {{TOOL_NAME}}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {{MainType}} {
    /// Unique identifier
    pub id: String,

    /// Display name
    pub name: String,

    /// Description
    pub description: String,

    /// Metadata
    pub metadata: serde_json::Value,

    /// Creation timestamp
    pub created_at: DateTime<Utc>,

    /// Last modification timestamp
    pub updated_at: DateTime<Utc>,
}

impl {{MainType}} {
    /// Create a new {{MainType}}
    pub fn new(name: impl Into<String>, description: impl Into<String>) -> Self {
        Self {
            id: Uuid::new_v4().to_string(),
            name: name.into(),
            description: description.into(),
            metadata: serde_json::json!({}),
            created_at: Utc::now(),
            updated_at: Utc::now(),
        }
    }

    /// Update the name
    pub fn set_name(&mut self, name: impl Into<String>) {
        self.name = name.into();
        self.updated_at = Utc::now();
    }

    /// Update the description
    pub fn set_description(&mut self, description: impl Into<String>) {
        self.description = description.into();
        self.updated_at = Utc::now();
    }
}

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

    #[test]
    fn test_create_new() {
        let item = {{MainType}}::new("Test Item", "A test item");
        assert_eq!(item.name, "Test Item");
        assert_eq!(item.description, "A test item");
        assert!(!item.id.is_empty());
    }

    #[test]
    fn test_set_name() {
        let mut item = {{MainType}}::new("Original", "Description");
        let original_updated = item.updated_at;

        // Add small delay to ensure timestamp difference
        std::thread::sleep(std::time::Duration::from_millis(10));

        item.set_name("Updated");
        assert_eq!(item.name, "Updated");
        assert!(item.updated_at > original_updated);
    }

    #[test]
    fn test_set_description() {
        let mut item = {{MainType}}::new("Name", "Original");
        let original_updated = item.updated_at;

        std::thread::sleep(std::time::Duration::from_millis(10));

        item.set_description("Updated");
        assert_eq!(item.description, "Updated");
        assert!(item.updated_at > original_updated);
    }

    #[test]
    fn test_serialization() {
        let item = {{MainType}}::new("Test", "Description");
        let json = serde_json::to_string(&item).expect("should serialize");
        let deserialized: {{MainType}} = serde_json::from_str(&json).expect("should deserialize");

        assert_eq!(item.id, deserialized.id);
        assert_eq!(item.name, deserialized.name);
    }
}
