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

/// 项目实体模型
/// 遵循 Tauri 开发规范的数据模型设计原则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Project {
    pub id: String,
    pub name: String,
    pub path: String,
    pub description: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub is_active: bool,
}

impl Project {
    /// 创建新项目实例
    pub fn new(name: String, path: String, description: Option<String>) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            name,
            path,
            description,
            created_at: now,
            updated_at: now,
            is_active: true,
        }
    }

    /// 更新项目信息
    pub fn update(&mut self, name: Option<String>, description: Option<String>) {
        if let Some(name) = name {
            self.name = name;
        }
        if let Some(description) = description {
            self.description = Some(description);
        }
        self.updated_at = Utc::now();
    }

    /// 验证项目数据
    pub fn validate(&self) -> Result<(), String> {
        if self.name.trim().is_empty() {
            return Err("项目名称不能为空".to_string());
        }

        if self.name.len() > 100 {
            return Err("项目名称不能超过100个字符".to_string());
        }

        if self.path.trim().is_empty() {
            return Err("项目路径不能为空".to_string());
        }

        if let Some(ref desc) = self.description {
            if desc.len() > 500 {
                return Err("项目描述不能超过500个字符".to_string());
            }
        }

        Ok(())
    }
}

/// 创建项目请求模型
#[derive(Debug, Deserialize)]
pub struct CreateProjectRequest {
    pub name: String,
    pub path: String,
    pub description: Option<String>,
}

impl CreateProjectRequest {
    pub fn validate(&self) -> Result<(), String> {
        if self.name.trim().is_empty() {
            return Err("项目名称不能为空".to_string());
        }

        if self.name.len() > 100 {
            return Err("项目名称不能超过100个字符".to_string());
        }

        if self.path.trim().is_empty() {
            return Err("项目路径不能为空".to_string());
        }

        if let Some(ref desc) = self.description {
            if desc.len() > 500 {
                return Err("项目描述不能超过500个字符".to_string());
            }
        }

        Ok(())
    }
}

/// 更新项目请求模型
#[derive(Debug, Deserialize)]
pub struct UpdateProjectRequest {
    pub name: Option<String>,
    pub description: Option<String>,
}

impl UpdateProjectRequest {
    pub fn validate(&self) -> Result<(), String> {
        if let Some(ref name) = self.name {
            if name.trim().is_empty() {
                return Err("项目名称不能为空".to_string());
            }
            if name.len() > 100 {
                return Err("项目名称不能超过100个字符".to_string());
            }
        }

        if let Some(ref desc) = self.description {
            if desc.len() > 500 {
                return Err("项目描述不能超过500个字符".to_string());
            }
        }

        Ok(())
    }
}

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

    #[test]
    fn test_project_creation() {
        let project = Project::new(
            "Test Project".to_string(),
            "/path/to/project".to_string(),
            Some("Test description".to_string()),
        );

        assert_eq!(project.name, "Test Project");
        assert_eq!(project.path, "/path/to/project");
        assert_eq!(project.description, Some("Test description".to_string()));
        assert!(project.is_active);
        assert!(!project.id.is_empty());
    }

    #[test]
    fn test_project_validation() {
        let mut project = Project::new(
            "Valid Project".to_string(),
            "/valid/path".to_string(),
            None,
        );

        // 有效项目应该通过验证
        assert!(project.validate().is_ok());

        // 空名称应该失败
        project.name = "".to_string();
        assert!(project.validate().is_err());

        // 过长名称应该失败
        project.name = "a".repeat(101);
        assert!(project.validate().is_err());

        // 空路径应该失败
        project.name = "Valid Name".to_string();
        project.path = "".to_string();
        assert!(project.validate().is_err());

        // 过长描述应该失败
        project.path = "/valid/path".to_string();
        project.description = Some("a".repeat(501));
        assert!(project.validate().is_err());
    }

    #[test]
    fn test_create_project_request_validation() {
        let valid_request = CreateProjectRequest {
            name: "Valid Project".to_string(),
            path: "/valid/path".to_string(),
            description: Some("Valid description".to_string()),
        };
        assert!(valid_request.validate().is_ok());

        let invalid_name_request = CreateProjectRequest {
            name: "".to_string(),
            path: "/valid/path".to_string(),
            description: None,
        };
        assert!(invalid_name_request.validate().is_err());
    }
}
