use tvai_sdk::*;
use tempfile::TempDir;
use std::fs;

#[test]
fn test_template_loading_from_file() {
    // Create a temporary template file
    let temp_dir = TempDir::new().unwrap();
    let template_path = temp_dir.path().join("test_template.json");
    
    let template_json = r#"{
        "name": "Test Template",
        "description": "A test template",
        "author": "Test Author",
        "date": "Mon Jan 01 12:00:00 2024 GMT+0000",
        "veaiversion": "5.1.2",
        "editable": true,
        "enabled": true,
        "saveOutputSettings": false,
        "settings": {
            "stabilize": {
                "active": false,
                "smooth": 50,
                "method": 1,
                "rsc": false,
                "reduceMotion": false,
                "reduceMotionIteration": 2
            },
            "motionblur": {
                "active": false,
                "model": "thm-2"
            },
            "slowmo": {
                "active": false,
                "model": "apo-8",
                "factor": 1,
                "duplicate": true,
                "duplicateThreshold": 10
            },
            "enhance": {
                "active": true,
                "model": "prob-4",
                "videoType": 1,
                "auto": 0,
                "fieldOrder": 0,
                "compress": 0,
                "detail": 0,
                "sharpen": 0,
                "denoise": 0,
                "dehalo": 0,
                "deblur": 0,
                "addNoise": 0,
                "recoverOriginalDetailValue": 20,
                "isArtemis": false,
                "isGaia": false,
                "isTheia": false,
                "isProteus": true,
                "isIris": false
            },
            "grain": {
                "active": false,
                "grain": 5,
                "grainSize": 2
            },
            "output": {
                "active": true,
                "outSizeMethod": 7,
                "cropToFit": false,
                "outputPAR": 0,
                "outFPS": 0
            }
        }
    }"#;
    
    fs::write(&template_path, template_json).unwrap();
    
    // Test loading template
    let mut sdk = TvaiSdk::new();
    let template = sdk.load_template_from_file(&template_path).unwrap();
    
    assert_eq!(template.name, "Test Template");
    assert_eq!(template.description, "A test template");
    assert!(template.settings.enhance.active);
    assert_eq!(template.settings.enhance.model, "prob-4");
}

#[test]
fn test_template_validation_and_completion() {
    let mut template = Template {
        name: "Test".to_string(),
        description: "".to_string(),
        author: "".to_string(),
        date: "".to_string(),
        veai_version: "".to_string(),
        editable: true,
        enabled: true,
        save_output_settings: false,
        path: None,
        settings: TemplateSettings::default(),
    };
    
    // Should complete missing fields
    template.validate_and_complete().unwrap();
    
    assert_eq!(template.author, "Unknown");
    assert!(!template.date.is_empty());
    assert_eq!(template.veai_version, "5.1.2");
}

#[test]
fn test_ffmpeg_command_generation() {
    let template = TemplatePresets::upscale_to_4k().unwrap();
    let sdk = TvaiSdk::new();
    
    let command = sdk.generate_ffmpeg_command(&template, "input.mp4", "output.mp4").unwrap();
    
    assert!(command.contains("ffmpeg"));
    assert!(command.contains("input.mp4"));
    assert!(command.contains("output.mp4"));
    assert!(command.contains("tvai_up"));
    assert!(command.contains("model=ahq-12"));
}

#[test]
fn test_template_builder() {
    let template = TemplateBuilder::new("Custom Template")
        .description("A custom template")
        .author("Test User")
        .enable_enhancement("prob-4")
        .enhancement_params(30, 20, 10)
        .enable_stabilization(60, 1)
        .output_settings(6, 60.0)
        .build()
        .unwrap();
    
    assert_eq!(template.name, "Custom Template");
    assert_eq!(template.description, "A custom template");
    assert_eq!(template.author, "Test User");
    assert!(template.settings.enhance.active);
    assert_eq!(template.settings.enhance.denoise, 30);
    assert_eq!(template.settings.enhance.detail, 20);
    assert_eq!(template.settings.enhance.sharpen, 10);
    assert!(template.settings.stabilize.active);
    assert_eq!(template.settings.stabilize.smooth, 60);
    assert_eq!(template.settings.output.out_fps, 60.0);
}

#[test]
fn test_template_presets() {
    // Test all presets can be created successfully
    let upscale_4k = TemplatePresets::upscale_to_4k().unwrap();
    assert_eq!(upscale_4k.name, "Upscale to 4K");
    assert!(upscale_4k.settings.enhance.active);
    
    let convert_60fps = TemplatePresets::convert_to_60fps().unwrap();
    assert_eq!(convert_60fps.name, "Convert to 60 FPS");
    assert!(convert_60fps.settings.slow_motion.active);
    assert_eq!(convert_60fps.settings.output.out_fps, 60.0);
    
    let remove_noise = TemplatePresets::remove_noise().unwrap();
    assert_eq!(remove_noise.name, "Remove Noise");
    assert!(remove_noise.settings.enhance.active);
    assert_eq!(remove_noise.settings.enhance.model, "nyx-3");
    
    let stabilize = TemplatePresets::stabilize_video().unwrap();
    assert_eq!(stabilize.name, "Stabilize Video");
    assert!(stabilize.settings.stabilize.active);
    
    let slow_motion = TemplatePresets::slow_motion_4x().unwrap();
    assert_eq!(slow_motion.name, "4x Slow Motion");
    assert!(slow_motion.settings.slow_motion.active);
    assert_eq!(slow_motion.settings.slow_motion.factor, 4.0);
}

#[test]
fn test_template_manager() {
    let mut sdk = TvaiSdk::new();
    
    // Add templates
    let template1 = TemplatePresets::upscale_to_4k().unwrap();
    let template2 = TemplatePresets::convert_to_60fps().unwrap();
    
    sdk.add_template(template1).unwrap();
    sdk.add_template(template2).unwrap();
    
    assert_eq!(sdk.template_count(), 2);
    assert!(sdk.has_template("Upscale to 4K"));
    assert!(sdk.has_template("Convert to 60 FPS"));
    
    // Test finding templates
    let found = sdk.find_template("Upscale to 4K").unwrap();
    assert_eq!(found.name, "Upscale to 4K");
    
    // Test removing template
    let removed = sdk.remove_template("Upscale to 4K").unwrap();
    assert_eq!(removed.name, "Upscale to 4K");
    assert_eq!(sdk.template_count(), 1);
    assert!(!sdk.has_template("Upscale to 4K"));
}

#[test]
fn test_batch_command_generation() {
    let template = TemplatePresets::upscale_to_4k().unwrap();
    let sdk = TvaiSdk::new();
    
    let input_files = vec![
        "video1.mp4".to_string(),
        "video2.mp4".to_string(),
        "video3.mp4".to_string(),
    ];
    
    let commands = sdk.generate_batch_commands(&template, &input_files, "/output").unwrap();
    
    assert_eq!(commands.len(), 3);
    assert!(commands[0].contains("video1.mp4"));
    assert!(commands[0].contains("/output/video1_processed.mp4"));
    assert!(commands[1].contains("video2.mp4"));
    assert!(commands[2].contains("video3.mp4"));
}

#[test]
fn test_hardware_acceleration_command() {
    let template = TemplatePresets::upscale_to_4k().unwrap();
    let sdk = TvaiSdk::new();
    
    let command = sdk.generate_ffmpeg_command_with_gpu(&template, "input.mp4", "output.mp4", "0").unwrap();
    
    assert!(command.contains("device=0:"));
}

#[test]
fn test_custom_codec_command() {
    let template = TemplatePresets::upscale_to_4k().unwrap();
    let sdk = TvaiSdk::new();

    let command = sdk.generate_ffmpeg_command_with_codec(&template, "input.mp4", "output.mp4", "hevc_nvenc", Some(20)).unwrap();

    assert!(command.contains("hevc_nvenc"));
    assert!(command.contains("-cq 20"));
}

#[test]
fn test_json_export_import() {
    let mut sdk = TvaiSdk::new();
    
    // Add some templates
    sdk.add_template(TemplatePresets::upscale_to_4k().unwrap()).unwrap();
    sdk.add_template(TemplatePresets::convert_to_60fps().unwrap()).unwrap();
    
    // Export to JSON
    let json = sdk.export_templates_to_json().unwrap();
    assert!(json.contains("Upscale to 4K"));
    assert!(json.contains("Convert to 60 FPS"));
    
    // Clear and import
    sdk.clear_templates();
    assert_eq!(sdk.template_count(), 0);
    
    let imported_count = sdk.import_templates_from_json(&json).unwrap();
    assert_eq!(imported_count, 2);
    assert_eq!(sdk.template_count(), 2);
    assert!(sdk.has_template("Upscale to 4K"));
    assert!(sdk.has_template("Convert to 60 FPS"));
}
