#[cfg(test)]
mod tests {
    // use crate::business::services::material_matching_service::MaterialMatchingService;
    use crate::data::models::{
        material::{Material, MaterialSegment, MaterialType, ProcessingStatus, MaterialMetadata},
        template::{SegmentMatchingRule, TrackSegment},
    };
    use crate::infrastructure::filename_utils::FilenameUtils;
    use std::collections::HashSet;
    use chrono::Utc;

    /// 创建测试用的素材片段
    fn create_test_material_segment(
        id: &str,
        material_id: &str,
        file_path: &str,
        duration: f64,
    ) -> MaterialSegment {
        MaterialSegment {
            id: id.to_string(),
            material_id: material_id.to_string(),
            segment_index: 0,
            start_time: 0.0,
            end_time: duration,
            duration,
            file_path: file_path.to_string(),
            file_size: 1024 * 1024, // 1MB
            thumbnail_path: None,
            usage_count: 0,
            is_used: false,
            last_used_at: None,
            created_at: Utc::now(),
        }
    }

    /// 创建测试用的素材
    fn create_test_material(id: &str, name: &str, model_id: Option<String>) -> Material {
        Material {
            id: id.to_string(),
            project_id: "test_project".to_string(),
            model_id,
            name: name.to_string(),
            original_path: format!("/test/path/{}.mp4", name),
            file_size: 1024 * 1024,
            md5_hash: "test_hash".to_string(),
            material_type: MaterialType::Video,
            processing_status: ProcessingStatus::Completed,
            metadata: MaterialMetadata::None,
            scene_detection: None,
            segments: Vec::new(),
            thumbnail_path: None,
            created_at: Utc::now(),
            updated_at: Utc::now(),
            processed_at: Some(Utc::now()),
            error_message: None,
        }
    }

    /// 创建测试用的轨道片段
    fn create_test_track_segment(
        id: &str,
        name: &str,
        duration_seconds: f64,
        matching_rule: SegmentMatchingRule,
    ) -> TrackSegment {
        let duration_microseconds = (duration_seconds * 1_000_000.0) as u64;
        let mut segment = TrackSegment::new(
            id.to_string(),
            "test_track".to_string(),
            name.to_string(),
            0,
            duration_microseconds,
            0,
        );
        segment.set_matching_rule(matching_rule);
        segment
    }

    #[test]
    fn test_filename_sequence_matching_basic() {
        // 测试基本的文件名序号匹配
        let segments = vec![
            (
                create_test_material_segment("seg1", "mat1", "video_001.mp4", 10.0),
                "category1".to_string(),
            ),
            (
                create_test_material_segment("seg2", "mat2", "video_002.mp4", 15.0),
                "category2".to_string(),
            ),
            (
                create_test_material_segment("seg3", "mat3", "image_001.jpg", 5.0),
                "category3".to_string(),
            ),
        ];

        let materials = vec![
            create_test_material("mat1", "video_001", Some("model1".to_string())),
            create_test_material("mat2", "video_002", Some("model2".to_string())),
            create_test_material("mat3", "image_001", None),
        ];

        let _track_segment = create_test_track_segment(
            "track_seg1",
            "Test Segment",
            8.0,
            SegmentMatchingRule::FilenameSequence {
                target_sequence: "001".to_string(),
            },
        );

        // 模拟匹配逻辑
        let mut matching_segments = Vec::new();
        for (segment, category) in &segments {
            if FilenameUtils::has_sequence_number(&segment.file_path, "001") {
                if FilenameUtils::is_video_file(&segment.file_path) {
                    if let Some(material) = materials.iter().find(|m| m.id == segment.material_id) {
                        matching_segments.push((segment, category, material));
                    }
                }
            }
        }

        // 应该找到一个匹配的视频文件
        assert_eq!(matching_segments.len(), 1);
        assert_eq!(matching_segments[0].0.file_path, "video_001.mp4");
    }

    #[test]
    fn test_filename_sequence_matching_no_videos() {
        // 测试没有视频文件的情况
        let segments = vec![
            (
                create_test_material_segment("seg1", "mat1", "image_001.jpg", 10.0),
                "category1".to_string(),
            ),
            (
                create_test_material_segment("seg2", "mat2", "audio_001.mp3", 15.0),
                "category2".to_string(),
            ),
        ];

        let materials = vec![
            create_test_material("mat1", "image_001", None),
            create_test_material("mat2", "audio_001", None),
        ];

        // 模拟匹配逻辑
        let mut matching_segments = Vec::new();
        for (segment, category) in &segments {
            if FilenameUtils::has_sequence_number(&segment.file_path, "001") {
                if FilenameUtils::is_video_file(&segment.file_path) {
                    if let Some(material) = materials.iter().find(|m| m.id == segment.material_id) {
                        matching_segments.push((segment, category, material));
                    }
                }
            }
        }

        // 应该没有找到匹配的视频文件
        assert_eq!(matching_segments.len(), 0);
    }

    #[test]
    fn test_filename_sequence_matching_wrong_sequence() {
        // 测试序号不匹配的情况
        let segments = vec![
            (
                create_test_material_segment("seg1", "mat1", "video_002.mp4", 10.0),
                "category1".to_string(),
            ),
            (
                create_test_material_segment("seg2", "mat2", "video_003.mp4", 15.0),
                "category2".to_string(),
            ),
        ];

        let materials = vec![
            create_test_material("mat1", "video_002", Some("model1".to_string())),
            create_test_material("mat2", "video_003", Some("model2".to_string())),
        ];

        // 模拟匹配逻辑 - 寻找序号001
        let mut matching_segments = Vec::new();
        for (segment, category) in &segments {
            if FilenameUtils::has_sequence_number(&segment.file_path, "001") {
                if FilenameUtils::is_video_file(&segment.file_path) {
                    if let Some(material) = materials.iter().find(|m| m.id == segment.material_id) {
                        matching_segments.push((segment, category, material));
                    }
                }
            }
        }

        // 应该没有找到匹配的文件（因为没有序号001的文件）
        assert_eq!(matching_segments.len(), 0);
    }

    #[test]
    fn test_sequence_001_usage_validation() {
        // 测试序号001使用限制逻辑
        let segments = vec![
            (
                create_test_material_segment("seg1", "mat1", "video_001.mp4", 10.0),
                "category1".to_string(),
            ),
            (
                create_test_material_segment("seg2", "mat2", "another_001.mp4", 15.0),
                "category2".to_string(),
            ),
        ];

        let mut used_segment_ids = HashSet::new();
        
        // 模拟第一次使用序号001的视频
        used_segment_ids.insert("seg1".to_string());

        // 检查是否已经使用了序号001的视频
        let mut has_used_sequence_001 = false;
        for used_id in &used_segment_ids {
            if let Some((used_segment, _)) = segments.iter().find(|(seg, _)| seg.id == *used_id) {
                if FilenameUtils::has_sequence_001(&used_segment.file_path) && 
                   FilenameUtils::is_video_file(&used_segment.file_path) {
                    has_used_sequence_001 = true;
                    break;
                }
            }
        }

        // 应该检测到已经使用了序号001的视频
        assert!(has_used_sequence_001);
    }

    #[test]
    fn test_multiple_sequence_001_files() {
        // 测试多个序号001文件的情况
        let files = vec![
            "video_001.mp4".to_string(),
            "scene_001.avi".to_string(),
            "take_001.mkv".to_string(),
            "video_002.mp4".to_string(),
        ];

        let sequence_001_videos = FilenameUtils::filter_videos_with_sequence_001(&files);
        
        // 应该找到3个序号001的视频文件
        assert_eq!(sequence_001_videos.len(), 3);
        assert!(sequence_001_videos.contains(&"video_001.mp4".to_string()));
        assert!(sequence_001_videos.contains(&"scene_001.avi".to_string()));
        assert!(sequence_001_videos.contains(&"take_001.mkv".to_string()));
    }

    #[test]
    fn test_segment_matching_rule_display() {
        // 测试匹配规则的显示名称
        let rule = SegmentMatchingRule::FilenameSequence {
            target_sequence: "001".to_string(),
        };

        assert_eq!(rule.display_name(), "文件名序号: 001");
        assert!(rule.is_filename_sequence());
        assert!(!rule.is_fixed_material());
        assert!(!rule.is_ai_classification());
        assert!(!rule.is_random_match());
        assert_eq!(rule.get_target_sequence(), Some(&"001".to_string()));
    }

    #[test]
    fn test_segment_matching_rule_serialization() {
        // 测试匹配规则的序列化和反序列化
        let rule = SegmentMatchingRule::FilenameSequence {
            target_sequence: "042".to_string(),
        };

        let serialized = serde_json::to_string(&rule).unwrap();
        let deserialized: SegmentMatchingRule = serde_json::from_str(&serialized).unwrap();

        match deserialized {
            SegmentMatchingRule::FilenameSequence { target_sequence } => {
                assert_eq!(target_sequence, "042");
            }
            _ => panic!("Deserialization failed"),
        }
    }

    #[test]
    fn test_integration_filename_sequence_workflow() {
        // 集成测试：完整的文件名序号匹配工作流程

        // 1. 创建测试数据 - 模拟项目中的视频文件
        let video_files = vec![
            "scene_001.mp4",
            "scene_002.mp4",
            "take_001.avi",
            "final_001.mkv",
            "backup_002.mp4",
            "test_video.mp4", // 无序号
        ];

        // 2. 测试文件名序号提取
        for file in &video_files {
            let sequence = FilenameUtils::extract_sequence_number(file);
            match *file {
                f if f.contains("_001") => assert_eq!(sequence, Some("001".to_string())),
                f if f.contains("_002") => assert_eq!(sequence, Some("002".to_string())),
                "test_video.mp4" => assert_eq!(sequence, None),
                _ => {} // 其他情况
            }
        }

        // 3. 测试序号001的筛选
        let sequence_001_files = FilenameUtils::filter_videos_with_sequence_001(
            &video_files.iter().map(|s| s.to_string()).collect::<Vec<_>>()
        );

        assert_eq!(sequence_001_files.len(), 3); // scene_001.mp4, take_001.avi, final_001.mkv
        assert!(sequence_001_files.contains(&"scene_001.mp4".to_string()));
        assert!(sequence_001_files.contains(&"take_001.avi".to_string()));
        assert!(sequence_001_files.contains(&"final_001.mkv".to_string()));

        // 4. 测试模板匹配规则创建
        let rule = SegmentMatchingRule::FilenameSequence {
            target_sequence: "001".to_string(),
        };

        assert!(rule.is_filename_sequence());
        assert_eq!(rule.get_target_sequence(), Some(&"001".to_string()));
        assert_eq!(rule.display_name(), "文件名序号: 001");

        // 5. 测试序列化兼容性（确保可以存储到数据库）
        let json = serde_json::to_string(&rule).unwrap();
        let restored: SegmentMatchingRule = serde_json::from_str(&json).unwrap();
        assert_eq!(rule, restored);

        println!("✅ 文件名序号匹配功能集成测试通过");
    }
}
