#[cfg(test)]
mod template_service_tests {
    use crate::business::services::template_service::TemplateService;
    use crate::data::models::template::{
        Template, TemplateMaterial, Track, TrackSegment, CanvasConfig,
        TemplateMaterialType, TrackType, ImportStatus, UploadStatus,
        SegmentMatchingRule
    };
    use crate::infrastructure::database::Database;
    use std::sync::Arc;

    use chrono::Utc;

    /// 创建测试数据库
    fn create_test_database() -> Arc<Database> {
        // 使用内存数据库进行测试
        Arc::new(Database::new().unwrap())
    }

    /// 创建测试模板
    fn create_test_template() -> Template {
        let now = Utc::now();
        let template_id = uuid::Uuid::new_v4().to_string();
        
        let mut template = Template {
            id: template_id.clone(),
            name: "测试模板".to_string(),
            description: Some("这是一个测试模板".to_string()),
            canvas_config: CanvasConfig {
                width: 1920,
                height: 1080,
                ratio: "16:9".to_string(),
            },
            duration: 30000000, // 30秒，微秒单位
            fps: 30.0,
            materials: Vec::new(),
            tracks: Vec::new(),
            import_status: ImportStatus::Completed,
            source_file_path: Some("/test/path/draft_content.json".to_string()),
            created_at: now,
            updated_at: now,
            is_active: true,
        };

        // 添加测试素材
        let material = TemplateMaterial {
            id: uuid::Uuid::new_v4().to_string(),
            template_id: template_id.clone(),
            original_id: "original_material_1".to_string(),
            name: "测试素材".to_string(),
            material_type: TemplateMaterialType::Video,
            original_path: "/test/path/video.mp4".to_string(),
            remote_url: None,
            file_size: Some(1024000),
            duration: Some(30000000),
            width: Some(1920),
            height: Some(1080),
            upload_status: UploadStatus::Completed,
            file_exists: true,
            upload_success: true,
            metadata: None,
            created_at: now,
            updated_at: now,
        };
        template.materials.push(material.clone());

        // 添加测试轨道
        let track_id = uuid::Uuid::new_v4().to_string();
        let mut track = Track {
            id: track_id.clone(),
            template_id: template_id.clone(),
            name: "视频轨道".to_string(),
            track_type: TrackType::Video,
            track_index: 0,
            segments: Vec::new(),
            created_at: now,
            updated_at: now,
        };

        // 添加测试轨道片段
        let segment = TrackSegment {
            id: uuid::Uuid::new_v4().to_string(),
            track_id: track_id.clone(),
            template_material_id: Some(material.id.clone()),
            name: "测试片段".to_string(),
            start_time: 0,
            end_time: 30000000,
            duration: 30000000,
            segment_index: 0,
            properties: None,
            matching_rule: SegmentMatchingRule::FixedMaterial,
            created_at: now,
            updated_at: now,
        };
        track.segments.push(segment);
        template.tracks.push(track);

        template
    }

    #[tokio::test]
    async fn test_save_template_with_validation() {
        let database = create_test_database();
        let service = TemplateService::new(database);
        let template = create_test_template();

        // 测试保存模板
        let result = service.save_template(&template).await;
        assert!(result.is_ok(), "保存模板应该成功: {:?}", result);

        // 验证模板是否正确保存
        let saved_template = service.get_template_by_id(&template.id).await.unwrap();
        assert!(saved_template.is_some(), "应该能够获取保存的模板");
        
        let saved = saved_template.unwrap();
        assert_eq!(saved.id, template.id);
        assert_eq!(saved.name, template.name);
        assert_eq!(saved.materials.len(), 1);
        assert_eq!(saved.tracks.len(), 1);
        assert_eq!(saved.tracks[0].segments.len(), 1);
    }

    #[tokio::test]
    async fn test_template_deletion_and_verification() {
        let database = create_test_database();
        let service = TemplateService::new(database);
        let template = create_test_template();

        // 保存模板
        service.save_template(&template).await.unwrap();

        // 获取关联数据统计
        let associations = service.get_template_associations(&template.id).await.unwrap();
        assert_eq!(associations.materials_count, 1);
        assert_eq!(associations.tracks_count, 1);
        assert_eq!(associations.segments_count, 1);

        // 硬删除模板
        let result = service.hard_delete_template(&template.id).await;
        assert!(result.is_ok(), "硬删除模板应该成功: {:?}", result);

        // 验证删除完整性
        let is_clean = service.verify_template_deletion(&template.id).await.unwrap();
        assert!(is_clean, "模板删除后应该没有残留数据");

        // 验证模板不再存在
        let deleted_template = service.get_template_by_id(&template.id).await.unwrap();
        assert!(deleted_template.is_none(), "删除后应该无法获取模板");
    }

    #[tokio::test]
    async fn test_foreign_key_constraint_validation() {
        let database = create_test_database();
        let service = TemplateService::new(database);
        let mut template = create_test_template();

        // 创建一个引用不存在素材的片段
        let invalid_material_id = uuid::Uuid::new_v4().to_string();
        template.tracks[0].segments[0].template_material_id = Some(invalid_material_id.clone());

        // 保存应该成功，但会将无效的素材引用设置为 NULL
        let result = service.save_template(&template).await;
        assert!(result.is_ok(), "保存应该成功，无效引用会被处理: {:?}", result);

        // 验证保存后的数据
        let saved_template = service.get_template_by_id(&template.id).await.unwrap().unwrap();
        // 无效的素材引用应该被设置为 None
        assert!(saved_template.tracks[0].segments[0].template_material_id.is_none() || 
                saved_template.tracks[0].segments[0].template_material_id != Some(invalid_material_id));
    }

    #[tokio::test]
    async fn test_template_data_validation() {
        let database = create_test_database();
        let service = TemplateService::new(database);
        let mut template = create_test_template();

        // 测试空模板ID
        template.id = "".to_string();
        let result = service.save_template(&template).await;
        assert!(result.is_err(), "空模板ID应该导致验证失败");

        // 恢复有效ID
        template.id = uuid::Uuid::new_v4().to_string();

        // 测试空模板名称
        template.name = "".to_string();
        let result = service.save_template(&template).await;
        assert!(result.is_err(), "空模板名称应该导致验证失败");

        // 恢复有效名称
        template.name = "测试模板".to_string();

        // 测试素材template_id不匹配
        template.materials[0].template_id = uuid::Uuid::new_v4().to_string();
        let result = service.save_template(&template).await;
        assert!(result.is_err(), "素材template_id不匹配应该导致验证失败");
    }

    #[tokio::test]
    async fn test_soft_delete_vs_hard_delete() {
        let database = create_test_database();
        let service = TemplateService::new(database);
        let template = create_test_template();

        // 保存模板
        service.save_template(&template).await.unwrap();

        // 软删除
        service.delete_template(&template.id).await.unwrap();

        // 软删除后，模板仍然存在但不活跃
        let soft_deleted = service.get_template_by_id(&template.id).await.unwrap();
        assert!(soft_deleted.is_some());
        assert!(!soft_deleted.unwrap().is_active);

        // 硬删除
        service.hard_delete_template(&template.id).await.unwrap();

        // 硬删除后，模板完全不存在
        let hard_deleted = service.get_template_by_id(&template.id).await.unwrap();
        assert!(hard_deleted.is_none());

        // 验证删除完整性
        let is_clean = service.verify_template_deletion(&template.id).await.unwrap();
        assert!(is_clean);
    }
}
