//! Image enhancement utilities

use std::path::Path;
use std::time::Instant;
use crate::core::{TvaiError, TvaiProcessor, ProcessResult, ProgressCallback};
use crate::image::ImageFormat;

/// Image enhancement and conversion utilities
impl TvaiProcessor {
    /// Convert image format without upscaling
    pub async fn convert_image_format(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        output_format: ImageFormat,
        quality: u8,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let start_time = Instant::now();

        // Validate inputs
        self.validate_input_file(input_path)?;
        self.validate_output_path(output_path)?;

        let operation_id = self.generate_operation_id();

        if let Some(callback) = progress_callback {
            callback(0.0);
        }

        // Build FFmpeg command for format conversion
        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
        ];

        // Add format-specific settings
        let q_value = ((100 - quality) / 3).to_string(); // Convert to FFmpeg scale
        match output_format {
            ImageFormat::Png => {
                args.extend_from_slice(&["-f", "image2", "-compression_level", "6"]);
            }
            ImageFormat::Jpg => {
                args.extend_from_slice(&["-f", "image2", "-q:v", &q_value]);
            }
            ImageFormat::Tiff => {
                args.extend_from_slice(&["-f", "image2", "-compression_algo", "lzw"]);
            }
            ImageFormat::Bmp => {
                args.extend_from_slice(&["-f", "image2"]);
            }
        }

        args.push(output_path.to_str().unwrap());

        if let Some(callback) = progress_callback {
            callback(0.3);
        }

        // Execute conversion (use system FFmpeg for simple conversion)
        self.execute_ffmpeg_command(&args, false, progress_callback).await?;

        let processing_time = start_time.elapsed();

        // Create result metadata
        let metadata = self.create_metadata(
            operation_id,
            input_path,
            format!("format_conversion: to={}, quality={}", output_format.extension(), quality),
        );

        if let Some(callback) = progress_callback {
            callback(1.0);
        }

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata,
        })
    }

    /// Batch convert image formats
    pub async fn batch_convert_images(
        &mut self,
        input_paths: &[std::path::PathBuf],
        output_dir: &Path,
        output_format: ImageFormat,
        quality: u8,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<Vec<ProcessResult>, TvaiError> {
        if input_paths.is_empty() {
            return Err(TvaiError::InvalidParameter("No input images provided".to_string()));
        }

        // Validate output directory
        std::fs::create_dir_all(output_dir)?;

        let mut results = Vec::new();
        let total_images = input_paths.len();

        if let Some(callback) = progress_callback {
            callback(0.0);
        }

        for (index, input_path) in input_paths.iter().enumerate() {
            // Generate output filename
            let input_stem = input_path.file_stem()
                .and_then(|s| s.to_str())
                .unwrap_or("image");
            let output_filename = format!("{}.{}", input_stem, output_format.extension());
            let output_path = output_dir.join(output_filename);

            // Convert individual image (simplified progress for now)
            let result = self.convert_image_format(
                input_path,
                &output_path,
                output_format,
                quality,
                None, // TODO: Fix progress callback forwarding
            ).await?;

            // Update overall progress
            if let Some(callback) = progress_callback {
                let overall_progress = (index + 1) as f32 / total_images as f32;
                callback(overall_progress);
            }

            results.push(result);
        }

        if let Some(callback) = progress_callback {
            callback(1.0);
        }

        Ok(results)
    }

    /// Resize image without AI upscaling (traditional resize)
    pub async fn resize_image(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        width: u32,
        height: u32,
        maintain_aspect: bool,
        output_format: ImageFormat,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let start_time = Instant::now();

        // Validate inputs
        self.validate_input_file(input_path)?;
        self.validate_output_path(output_path)?;

        let operation_id = self.generate_operation_id();

        if let Some(callback) = progress_callback {
            callback(0.0);
        }

        // Build resize filter
        let resize_filter = if maintain_aspect {
            format!("scale={}:{}:force_original_aspect_ratio=decrease", width, height)
        } else {
            format!("scale={}:{}", width, height)
        };

        // Build FFmpeg command
        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-vf", &resize_filter,
        ];

        // Add format settings
        match output_format {
            ImageFormat::Png => {
                args.extend_from_slice(&["-f", "image2", "-compression_level", "6"]);
            }
            ImageFormat::Jpg => {
                args.extend_from_slice(&["-f", "image2", "-q:v", "2"]);
            }
            ImageFormat::Tiff => {
                args.extend_from_slice(&["-f", "image2", "-compression_algo", "lzw"]);
            }
            ImageFormat::Bmp => {
                args.extend_from_slice(&["-f", "image2"]);
            }
        }

        args.push(output_path.to_str().unwrap());

        if let Some(callback) = progress_callback {
            callback(0.3);
        }

        // Execute resize
        self.execute_ffmpeg_command(&args, false, progress_callback).await?;

        let processing_time = start_time.elapsed();

        // Create result metadata
        let metadata = self.create_metadata(
            operation_id,
            input_path,
            format!("resize: {}x{}, aspect={}, format={}",
                width, height, maintain_aspect, output_format.extension()),
        );

        if let Some(callback) = progress_callback {
            callback(1.0);
        }

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata,
        })
    }
}
