//! Image processing examples demonstrating all image enhancement features

use tvai::*;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("Topaz Video AI Library - Image Processing Examples");
    
    // Detect Topaz installation
    if let Some(topaz_path) = detect_topaz_installation() {
        println!("Found Topaz Video AI at: {}", topaz_path.display());
        
        // Create configuration
        let config = TvaiConfig::builder()
            .topaz_path(topaz_path)
            .use_gpu(true)
            .build()?;
        
        // Create processor
        let mut processor = TvaiProcessor::new(config)?;
        println!("Processor created successfully");
        
        // Demonstrate image upscaling
        demonstrate_image_upscaling(&mut processor).await?;
        
        // Demonstrate batch processing
        demonstrate_batch_processing(&mut processor).await?;
        
        // Demonstrate format conversion
        demonstrate_format_conversion(&mut processor).await?;
        
        // Demonstrate image enhancement
        demonstrate_image_enhancement(&mut processor).await?;
        
        // Demonstrate quick functions
        demonstrate_quick_functions().await?;
        
        println!("All image processing examples completed successfully!");
    } else {
        println!("Topaz Video AI not found. Please install it first.");
    }
    
    Ok(())
}

async fn demonstrate_image_upscaling(processor: &mut TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Image Upscaling Demo ===");
    
    // Create upscaling parameters for different scenarios
    let scenarios = vec![
        ("Photo Enhancement", ImageUpscaleParams::for_photo()),
        ("Artwork Upscaling", ImageUpscaleParams::for_artwork()),
        ("Screenshot Enhancement", ImageUpscaleParams::for_screenshot()),
        ("Portrait Enhancement", ImageUpscaleParams::for_portrait()),
        ("Custom Parameters", ImageUpscaleParams {
            scale_factor: 3.0,
            model: UpscaleModel::Ghq5,
            compression: -0.2,
            blend: 0.0,
            output_format: ImageFormat::Tiff,
        }),
    ];
    
    for (name, params) in scenarios {
        println!("Scenario: {}", name);
        println!("  Model: {} ({})", params.model.as_str(), params.model.description());
        println!("  Scale: {}x", params.scale_factor);
        println!("  Compression: {}", params.compression);
        println!("  Blend: {}", params.blend);
        println!("  Output Format: {}", params.output_format.extension().to_uppercase());
        
        // In a real scenario, you would call:
        // let result = processor.upscale_image(input, output, params, Some(&progress_callback)).await?;
        // println!("  Processing time: {:?}", result.processing_time);
    }
    
    Ok(())
}

async fn demonstrate_batch_processing(processor: &mut TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Batch Processing Demo ===");
    
    println!("Batch Image Upscaling:");
    println!("  - Process multiple images at once");
    println!("  - Consistent parameters across all images");
    println!("  - Progress tracking for entire batch");
    println!("  - Automatic output filename generation");
    
    // In a real scenario:
    // let input_paths = vec![Path::new("image1.jpg"), Path::new("image2.png")];
    // let params = ImageUpscaleParams::for_photo();
    // let results = processor.batch_upscale_images(&input_paths, output_dir, params, Some(&progress_callback)).await?;
    // println!("  Processed {} images", results.len());
    
    println!("\nDirectory Processing:");
    println!("  - Auto-discover images in directory");
    println!("  - Support for recursive subdirectory scanning");
    println!("  - Filter by supported image formats");
    println!("  - Batch process all discovered images");
    
    // In a real scenario:
    // let results = processor.upscale_directory(input_dir, output_dir, params, true, Some(&progress_callback)).await?;
    // println!("  Processed {} images from directory", results.len());
    
    Ok(())
}

async fn demonstrate_format_conversion(processor: &mut TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Format Conversion Demo ===");
    
    let formats = vec![
        (ImageFormat::Png, "Lossless compression, transparency support"),
        (ImageFormat::Jpg, "Lossy compression, smaller file size"),
        (ImageFormat::Tiff, "Professional format, lossless compression"),
        (ImageFormat::Bmp, "Uncompressed format, large file size"),
    ];
    
    for (format, description) in formats {
        println!("Format: {} - {}", format.extension().to_uppercase(), description);
        println!("  FFmpeg format: {}", format.ffmpeg_format());
        
        // In a real scenario:
        // let result = processor.convert_image_format(input, output, format, 95, Some(&progress_callback)).await?;
        // println!("  Conversion time: {:?}", result.processing_time);
    }
    
    println!("\nBatch Format Conversion:");
    println!("  - Convert multiple images to same format");
    println!("  - Configurable quality settings");
    println!("  - Preserve original filenames");
    
    // In a real scenario:
    // let input_paths = vec![/* image paths */];
    // let results = processor.batch_convert_images(&input_paths, output_dir, ImageFormat::Png, 95, Some(&progress_callback)).await?;
    
    Ok(())
}

async fn demonstrate_image_enhancement(processor: &mut TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Image Enhancement Demo ===");
    
    println!("Traditional Resize (Non-AI):");
    println!("  - Fast geometric scaling");
    println!("  - Maintain aspect ratio option");
    println!("  - Multiple output formats");
    println!("  - Good for simple size adjustments");
    
    // In a real scenario:
    // let result = processor.resize_image(input, output, 1920, 1080, true, ImageFormat::Png, Some(&progress_callback)).await?;
    
    println!("\nAI-Powered Upscaling:");
    println!("  - Machine learning enhancement");
    println!("  - Detail reconstruction");
    println!("  - Artifact reduction");
    println!("  - Superior quality for enlargement");
    
    println!("\nModel Comparison:");
    let models = vec![
        (UpscaleModel::Iris3, "Best general purpose model"),
        (UpscaleModel::Nyx3, "Optimized for portraits"),
        (UpscaleModel::Thf4, "Old content restoration"),
        (UpscaleModel::Ghq5, "Game/CG content"),
        (UpscaleModel::Prob4, "Problem content repair"),
    ];
    
    for (model, description) in models {
        println!("  {}: {}", model.as_str(), description);
        if let Some(scale) = model.forces_scale() {
            println!("    (Forces {}x scale)", scale);
        }
    }
    
    Ok(())
}

async fn demonstrate_quick_functions() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Quick Functions Demo ===");
    
    println!("Quick Image Upscale:");
    println!("  - One-line image upscaling");
    println!("  - Automatic Topaz detection");
    println!("  - Default high-quality settings");
    println!("  - Usage: quick_upscale_image(input, output, 2.0).await?");
    
    println!("\nAuto Enhance Image:");
    println!("  - Intelligent enhancement detection");
    println!("  - Automatic parameter selection");
    println!("  - Based on image characteristics");
    println!("  - Usage: auto_enhance_image(input, output).await?");
    
    println!("\nBatch Directory Processing:");
    println!("  - Process entire directories");
    println!("  - Recursive subdirectory support");
    println!("  - Automatic file discovery");
    println!("  - Usage: batch_upscale_directory(input_dir, output_dir, 2.0, true).await?");
    
    println!("\nFormat Conversion:");
    println!("  - Simple format conversion");
    println!("  - Quality control");
    println!("  - No AI processing needed");
    println!("  - Usage: convert_image(input, output, ImageFormat::Png, 95).await?");
    
    // In a real scenario, you would call these functions:
    // let result = quick_upscale_image(Path::new("input.jpg"), Path::new("output.png"), 2.0).await?;
    // let result = auto_enhance_image(Path::new("input.jpg"), Path::new("enhanced.png")).await?;
    // let results = batch_upscale_directory(Path::new("input_dir"), Path::new("output_dir"), 2.0, true).await?;
    // let result = convert_image(Path::new("input.jpg"), Path::new("output.png"), ImageFormat::Png, 95).await?;
    
    Ok(())
}

// Progress callback example
fn create_progress_callback(operation_name: &str) -> ProgressCallback {
    let name = operation_name.to_string();
    Box::new(move |progress| {
        let percentage = (progress * 100.0) as u32;
        println!("{}: {}%", name, percentage);
    })
}
