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

/// 自定义标签分类
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomTagCategory {
    /// 分类ID
    pub id: String,
    /// 分类名称
    pub name: String,
    /// 分类描述
    pub description: Option<String>,
    /// 分类颜色（十六进制）
    pub color: String,
    /// 分类图标
    pub icon: Option<String>,
    /// 排序顺序
    pub sort_order: i32,
    /// 是否激活
    pub is_active: bool,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
}

impl Default for CustomTagCategory {
    fn default() -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            name: String::new(),
            description: None,
            color: "#3b82f6".to_string(),
            icon: None,
            sort_order: 0,
            is_active: true,
            created_at: now,
            updated_at: now,
        }
    }
}

/// 自定义标签
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomTag {
    /// 标签ID
    pub id: String,
    /// 所属分类ID
    pub category_id: String,
    /// 标签名称
    pub name: String,
    /// 标签描述
    pub description: Option<String>,
    /// 标签颜色（可选，继承分类颜色）
    pub color: Option<String>,
    /// 排序顺序
    pub sort_order: i32,
    /// 使用次数
    pub usage_count: i32,
    /// 是否激活
    pub is_active: bool,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
}

impl Default for CustomTag {
    fn default() -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            category_id: String::new(),
            name: String::new(),
            description: None,
            color: None,
            sort_order: 0,
            usage_count: 0,
            is_active: true,
            created_at: now,
            updated_at: now,
        }
    }
}

/// 标签关联
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TagAssociation {
    /// 关联ID
    pub id: String,
    /// 标签ID
    pub tag_id: String,
    /// 实体类型（如：material, model, project等）
    pub entity_type: String,
    /// 实体ID
    pub entity_id: String,
    /// 创建时间
    pub created_at: DateTime<Utc>,
}

impl Default for TagAssociation {
    fn default() -> Self {
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            tag_id: String::new(),
            entity_type: String::new(),
            entity_id: String::new(),
            created_at: Utc::now(),
        }
    }
}

/// 带分类信息的标签
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomTagWithCategory {
    /// 标签信息
    #[serde(flatten)]
    pub tag: CustomTag,
    /// 分类信息
    pub category: CustomTagCategory,
}

/// 标签创建请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateCustomTagRequest {
    /// 分类ID
    pub category_id: String,
    /// 标签名称
    pub name: String,
    /// 标签描述
    pub description: Option<String>,
    /// 标签颜色
    pub color: Option<String>,
}

/// 标签更新请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateCustomTagRequest {
    /// 标签名称
    pub name: Option<String>,
    /// 标签描述
    pub description: Option<String>,
    /// 标签颜色
    pub color: Option<String>,
    /// 排序顺序
    pub sort_order: Option<i32>,
    /// 是否激活
    pub is_active: Option<bool>,
}

/// 标签分类创建请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateCustomTagCategoryRequest {
    /// 分类名称
    pub name: String,
    /// 分类描述
    pub description: Option<String>,
    /// 分类颜色
    pub color: Option<String>,
    /// 分类图标
    pub icon: Option<String>,
}

/// 标签分类更新请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateCustomTagCategoryRequest {
    /// 分类名称
    pub name: Option<String>,
    /// 分类描述
    pub description: Option<String>,
    /// 分类颜色
    pub color: Option<String>,
    /// 分类图标
    pub icon: Option<String>,
    /// 排序顺序
    pub sort_order: Option<i32>,
    /// 是否激活
    pub is_active: Option<bool>,
}

/// 标签筛选条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TagFilter {
    /// 分类ID列表
    pub category_ids: Option<Vec<String>>,
    /// 标签名称搜索
    pub name_search: Option<String>,
    /// 是否只显示激活的标签
    pub active_only: Option<bool>,
    /// 实体类型过滤
    pub entity_type: Option<String>,
    /// 实体ID过滤
    pub entity_id: Option<String>,
}

impl Default for TagFilter {
    fn default() -> Self {
        Self {
            category_ids: None,
            name_search: None,
            active_only: Some(true),
            entity_type: None,
            entity_id: None,
        }
    }
}

/// 标签统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TagStatistics {
    /// 总标签数
    pub total_tags: i32,
    /// 激活标签数
    pub active_tags: i32,
    /// 总分类数
    pub total_categories: i32,
    /// 激活分类数
    pub active_categories: i32,
    /// 总关联数
    pub total_associations: i32,
    /// 按分类统计
    pub by_category: Vec<CategoryTagCount>,
}

/// 分类标签数量统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CategoryTagCount {
    /// 分类信息
    pub category: CustomTagCategory,
    /// 标签数量
    pub tag_count: i32,
    /// 关联数量
    pub association_count: i32,
}

/// 实体支持的标签类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EntityType {
    /// 素材
    Material,
    /// 模特
    Model,
    /// 项目
    Project,
    /// 模板
    Template,
    /// 素材片段
    MaterialSegment,
}

impl EntityType {
    pub fn as_str(&self) -> &'static str {
        match self {
            EntityType::Material => "material",
            EntityType::Model => "model",
            EntityType::Project => "project",
            EntityType::Template => "template",
            EntityType::MaterialSegment => "material_segment",
        }
    }

    pub fn from_str(s: &str) -> Option<Self> {
        match s {
            "material" => Some(EntityType::Material),
            "model" => Some(EntityType::Model),
            "project" => Some(EntityType::Project),
            "template" => Some(EntityType::Template),
            "material_segment" => Some(EntityType::MaterialSegment),
            _ => None,
        }
    }
}

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

    #[test]
    fn test_custom_tag_category_default() {
        let category = CustomTagCategory::default();
        assert!(!category.id.is_empty());
        assert_eq!(category.color, "#3b82f6");
        assert!(category.is_active);
        assert_eq!(category.sort_order, 0);
    }

    #[test]
    fn test_custom_tag_default() {
        let tag = CustomTag::default();
        assert!(!tag.id.is_empty());
        assert!(tag.is_active);
        assert_eq!(tag.usage_count, 0);
        assert_eq!(tag.sort_order, 0);
    }

    #[test]
    fn test_entity_type_conversion() {
        assert_eq!(EntityType::Material.as_str(), "material");
        assert_eq!(EntityType::Model.as_str(), "model");
        
        assert!(matches!(EntityType::from_str("material"), Some(EntityType::Material)));
        assert!(matches!(EntityType::from_str("model"), Some(EntityType::Model)));
        assert!(EntityType::from_str("invalid").is_none());
    }

    #[test]
    fn test_tag_filter_default() {
        let filter = TagFilter::default();
        assert!(filter.category_ids.is_none());
        assert!(filter.name_search.is_none());
        assert_eq!(filter.active_only, Some(true));
    }
}
