//! Image processing functionality

pub mod upscale;
pub mod enhance;

use std::path::Path;
use serde::{Deserialize, Serialize};

use crate::core::{TvaiError, ProcessResult};
use crate::config::UpscaleModel;

/// Supported image formats
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImageFormat {
    Png,
    Jpg,
    Tiff,
    Bmp,
}

impl ImageFormat {
    /// Get file extension for this format
    pub fn extension(&self) -> &'static str {
        match self {
            Self::Png => "png",
            Self::Jpg => "jpg",
            Self::Tiff => "tiff",
            Self::Bmp => "bmp",
        }
    }
    
    /// Get FFmpeg format name
    pub fn ffmpeg_format(&self) -> &'static str {
        match self {
            Self::Png => "png",
            Self::Jpg => "mjpeg",
            Self::Tiff => "tiff",
            Self::Bmp => "bmp",
        }
    }
}

/// Parameters for image upscaling
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageUpscaleParams {
    pub scale_factor: f32,
    pub model: UpscaleModel,
    pub compression: f32,
    pub blend: f32,
    pub output_format: ImageFormat,
}

impl ImageUpscaleParams {
    /// Create parameters optimized for photos
    pub fn for_photo() -> Self {
        Self {
            scale_factor: 2.0,
            model: UpscaleModel::Iris3,
            compression: 0.0,
            blend: 0.1,
            output_format: ImageFormat::Png,
        }
    }
    
    /// Create parameters optimized for artwork
    pub fn for_artwork() -> Self {
        Self {
            scale_factor: 2.0,
            model: UpscaleModel::Thf4,
            compression: -0.1,
            blend: 0.0,
            output_format: ImageFormat::Png,
        }
    }
    
    /// Create parameters optimized for screenshots
    pub fn for_screenshot() -> Self {
        Self {
            scale_factor: 2.0,
            model: UpscaleModel::Ghq5,
            compression: 0.0,
            blend: 0.0,
            output_format: ImageFormat::Png,
        }
    }
    
    /// Create parameters optimized for portraits
    pub fn for_portrait() -> Self {
        Self {
            scale_factor: 2.0,
            model: UpscaleModel::Nyx3,
            compression: -0.2,
            blend: 0.1,
            output_format: ImageFormat::Png,
        }
    }
}

/// Quick image upscaling function
pub async fn quick_upscale_image(
    input: &Path,
    output: &Path,
    scale: f32,
) -> Result<ProcessResult, TvaiError> {
    // Detect Topaz installation
    let topaz_path = crate::utils::detect_topaz_installation()
        .ok_or_else(|| TvaiError::TopazNotFound("Topaz Video AI not found".to_string()))?;

    // Create default configuration
    let config = crate::core::TvaiConfig::builder()
        .topaz_path(topaz_path)
        .use_gpu(true)
        .build()?;

    // Create processor
    let mut processor = crate::core::TvaiProcessor::new(config)?;

    // Create default upscaling parameters
    let params = ImageUpscaleParams {
        scale_factor: scale,
        model: UpscaleModel::Iris3, // Best general purpose model
        compression: 0.0,
        blend: 0.0,
        output_format: ImageFormat::Png,
    };

    // Perform upscaling
    processor.upscale_image(input, output, params, None).await
}

/// Auto-enhance image with intelligent parameter selection
pub async fn auto_enhance_image(
    input: &Path,
    output: &Path,
) -> Result<ProcessResult, TvaiError> {
    // Detect Topaz installation
    let topaz_path = crate::utils::detect_topaz_installation()
        .ok_or_else(|| TvaiError::TopazNotFound("Topaz Video AI not found".to_string()))?;

    // Create default configuration
    let config = crate::core::TvaiConfig::builder()
        .topaz_path(topaz_path)
        .use_gpu(true)
        .build()?;

    // Create processor
    let mut processor = crate::core::TvaiProcessor::new(config)?;

    // Get image info to determine best enhancement strategy
    let image_info = crate::utils::get_image_info(input)?;

    // Auto-determine enhancement parameters based on image characteristics
    let scale_factor = if image_info.width < 1920 && image_info.height < 1080 {
        if image_info.width <= 720 || image_info.height <= 720 {
            4.0 // Very small image, scale 4x
        } else {
            2.0 // Medium image, scale 2x
        }
    } else {
        1.5 // Large image, modest enhancement
    };

    // Choose model based on image characteristics
    let model = if image_info.format.to_lowercase().contains("jpg") || image_info.format.to_lowercase().contains("jpeg") {
        UpscaleModel::Iris3 // Good for photos
    } else {
        UpscaleModel::Iris3 // Default to best general purpose
    };

    let params = ImageUpscaleParams {
        scale_factor,
        model,
        compression: -0.1, // Slight sharpening
        blend: 0.1,
        output_format: ImageFormat::Png, // High quality output
    };

    // Perform enhancement
    processor.upscale_image(input, output, params, None).await
}

/// Batch upscale images in a directory
pub async fn batch_upscale_directory(
    input_dir: &Path,
    output_dir: &Path,
    scale: f32,
    recursive: bool,
) -> Result<Vec<ProcessResult>, TvaiError> {
    // Detect Topaz installation
    let topaz_path = crate::utils::detect_topaz_installation()
        .ok_or_else(|| TvaiError::TopazNotFound("Topaz Video AI not found".to_string()))?;

    // Create default configuration
    let config = crate::core::TvaiConfig::builder()
        .topaz_path(topaz_path)
        .use_gpu(true)
        .build()?;

    // Create processor
    let mut processor = crate::core::TvaiProcessor::new(config)?;

    // Create default upscaling parameters
    let params = ImageUpscaleParams {
        scale_factor: scale,
        model: UpscaleModel::Iris3,
        compression: 0.0,
        blend: 0.0,
        output_format: ImageFormat::Png,
    };

    // Perform batch upscaling
    processor.upscale_directory(input_dir, output_dir, params, recursive, None).await
}

/// Convert image format
pub async fn convert_image(
    input: &Path,
    output: &Path,
    format: ImageFormat,
    quality: u8,
) -> Result<ProcessResult, TvaiError> {
    // Detect Topaz installation (though we don't need it for conversion)
    let topaz_path = crate::utils::detect_topaz_installation()
        .ok_or_else(|| TvaiError::TopazNotFound("Topaz Video AI not found".to_string()))?;

    // Create default configuration
    let config = crate::core::TvaiConfig::builder()
        .topaz_path(topaz_path)
        .use_gpu(false) // Don't need GPU for simple conversion
        .build()?;

    // Create processor
    let mut processor = crate::core::TvaiProcessor::new(config)?;

    // Perform conversion
    processor.convert_image_format(input, output, format, quality, None).await
}
