//! 滤镜组合实现

use std::path::Path;
use crate::core::{TvaiError, ProcessResult, ProgressCallback};
use crate::config::UpscaleModel;
use super::{FilterProcessor, QualityLevel, ProcessOptions};

impl FilterProcessor {
    /// 应用超分辨率放大
    pub async fn apply_upscale(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        model: UpscaleModel,
        scale: f32,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();
        
        if let Some(callback) = progress_callback {
            callback(0.0);
        }

        // 构建 tvai_up 滤镜参数
        let mut filter_args = vec![
            format!("model={}", model.as_str()),
            format!("scale={}", scale as u32),
            format!("device={}", options.device),
            format!("vram={}", options.vram_limit),
        ];

        // 根据质量等级调整参数
        match quality {
            QualityLevel::Fast => {
                filter_args.extend_from_slice(&[
                    "estimate=4".to_string(),
                    "instances=2".to_string(),
                ]);
            }
            QualityLevel::Balanced => {
                filter_args.extend_from_slice(&[
                    "estimate=8".to_string(),
                    "instances=1".to_string(),
                ]);
            }
            QualityLevel::High => {
                filter_args.extend_from_slice(&[
                    "estimate=12".to_string(),
                    "instances=1".to_string(),
                    "preblur=0".to_string(),
                    "noise=0".to_string(),
                    "details=0".to_string(),
                ]);
            }
            QualityLevel::Maximum => {
                filter_args.extend_from_slice(&[
                    "estimate=20".to_string(),
                    "instances=1".to_string(),
                    "preblur=0".to_string(),
                    "noise=0".to_string(),
                    "details=0".to_string(),
                    "halo=0".to_string(),
                    "blur=0".to_string(),
                    "compression=0".to_string(),
                ]);
            }
        }

        // 如果指定了输出分辨率
        if let Some((width, height)) = options.output_resolution {
            filter_args.extend_from_slice(&[
                format!("w={}", width),
                format!("h={}", height),
            ]);
        }

        let filter_complex = format!("tvai_up={}", filter_args.join(":"));

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

        // 构建完整的 FFmpeg 命令
        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &filter_complex,
        ];

        // 添加编码参数
        self.add_encoding_args(&mut args, &quality, &options);

        // 添加音频处理
        if options.keep_audio {
            args.extend_from_slice(&["-c:a", "copy"]);
        } else {
            args.push("-an");
        }

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

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

        // 执行命令
        let start_time = std::time::Instant::now();
        self.processor.execute_ffmpeg_command(&args, true, progress_callback).await?;
        let processing_time = start_time.elapsed();

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

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata: self.processor.create_metadata(
                operation_id,
                input_path,
                format!("upscale: model={}, scale={}, quality={:?}", 
                    model.as_str(), scale, quality),
            ),
        })
    }

    /// 应用慢动作处理
    pub async fn apply_slow_motion(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        factor: f32,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();
        
        if let Some(callback) = progress_callback {
            callback(0.0);
        }

        // 选择插值模型
        let model = match quality {
            QualityLevel::Fast => "apf-1",
            QualityLevel::Balanced => "chr-2",
            QualityLevel::High | QualityLevel::Maximum => "apo-8",
        };

        // 构建 tvai_fi 滤镜参数
        let filter_args = vec![
            format!("model={}", model),
            format!("slowmo={}", factor),
            format!("device={}", options.device),
            format!("vram={}", options.vram_limit),
            "rdt=0.01".to_string(),
        ];

        let filter_complex = format!("tvai_fi={}", filter_args.join(":"));

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

        // 构建 FFmpeg 命令
        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &filter_complex,
        ];

        self.add_encoding_args(&mut args, &quality, &options);

        if options.keep_audio {
            args.extend_from_slice(&["-c:a", "copy"]);
        } else {
            args.push("-an");
        }

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

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

        let start_time = std::time::Instant::now();
        self.processor.execute_ffmpeg_command(&args, true, progress_callback).await?;
        let processing_time = start_time.elapsed();

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

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata: self.processor.create_metadata(
                operation_id,
                input_path,
                format!("slow_motion: factor={}, model={}, quality={:?}", 
                    factor, model, quality),
            ),
        })
    }

    /// 应用视频稳定化
    pub async fn apply_stabilize(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        strength: f32,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();
        
        if let Some(callback) = progress_callback {
            callback(0.0);
        }

        // 第一步：相机姿态估算
        let cpe_file = self.processor.create_temp_path(&operation_id, "cpe.json");
        
        let cpe_args = vec![
            format!("model=cpe-1"),
            format!("filename={}", cpe_file.to_str().unwrap()),
            format!("device={}", options.device),
        ];

        let cpe_filter = format!("tvai_cpe={}", cpe_args.join(":"));

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

        // 执行 CPE
        let cpe_cmd = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &cpe_filter,
            "-f", "null", "-",
        ];

        self.processor.execute_ffmpeg_command(&cpe_cmd, true, None).await?;

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

        // 第二步：视频稳定化
        let smoothness = match quality {
            QualityLevel::Fast => 4.0,
            QualityLevel::Balanced => 6.0,
            QualityLevel::High => 8.0,
            QualityLevel::Maximum => 12.0,
        };

        let stb_args = vec![
            format!("model=ref-2"),
            format!("device={}", options.device),
            format!("vram={}", options.vram_limit),
            format!("filename={}", cpe_file.to_str().unwrap()),
            format!("smoothness={}", smoothness * strength),
            "full=1".to_string(),
            "dof=1111".to_string(),
        ];

        let stb_filter = format!("tvai_stb={}", stb_args.join(":"));

        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &stb_filter,
        ];

        self.add_encoding_args(&mut args, &quality, &options);

        if options.keep_audio {
            args.extend_from_slice(&["-c:a", "copy"]);
        } else {
            args.push("-an");
        }

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

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

        let start_time = std::time::Instant::now();
        self.processor.execute_ffmpeg_command(&args, true, progress_callback).await?;
        let processing_time = start_time.elapsed();

        // 清理临时文件
        let _ = std::fs::remove_file(&cpe_file);

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

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata: self.processor.create_metadata(
                operation_id,
                input_path,
                format!("stabilize: strength={}, quality={:?}", strength, quality),
            ),
        })
    }

    /// 添加编码参数
    fn add_encoding_args(&self, args: &mut Vec<&str>, quality: &QualityLevel, _options: &ProcessOptions) {
        // 根据质量等级选择编码参数
        match quality {
            QualityLevel::Fast => {
                args.extend_from_slice(&["-c:v", "h264_nvenc", "-preset", "p1", "-crf", "25"]);
            }
            QualityLevel::Balanced => {
                args.extend_from_slice(&["-c:v", "h264_nvenc", "-preset", "p4", "-crf", "20"]);
            }
            QualityLevel::High => {
                args.extend_from_slice(&["-c:v", "h264_nvenc", "-preset", "p6", "-crf", "17"]);
            }
            QualityLevel::Maximum => {
                args.extend_from_slice(&["-c:v", "h264_nvenc", "-preset", "p7", "-crf", "15"]);
            }
        }

        args.extend_from_slice(&["-pix_fmt", "yuv420p"]);
    }

    /// 应用完整增强 (放大 + 稳定化)
    pub async fn apply_full_enhance(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        upscale_factor: f32,
        stabilize: bool,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();

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

        if stabilize {
            // 两步处理：先稳定化，再放大
            let temp_stabilized = self.processor.create_temp_path(&operation_id, "stabilized.mp4");

            // 第一步：稳定化
            self.apply_stabilize(input_path, &temp_stabilized, 1.0, quality, options.clone(), None).await?;

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

            // 第二步：放大
            let result = self.apply_upscale(&temp_stabilized, output_path, UpscaleModel::Iris3, upscale_factor, quality, options, None).await?;

            // 清理临时文件
            let _ = std::fs::remove_file(&temp_stabilized);

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

            Ok(result)
        } else {
            // 只进行放大
            self.apply_upscale(input_path, output_path, UpscaleModel::Iris3, upscale_factor, quality, options, progress_callback).await
        }
    }

    /// 应用老视频修复
    pub async fn apply_restore_old_video(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        upscale_factor: f32,
        denoise_level: f32,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();

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

        // 使用 Proteus 模型进行老视频修复
        let mut filter_args = vec![
            "model=prob-4".to_string(),
            format!("scale={}", upscale_factor as u32),
            format!("device={}", options.device),
            format!("vram={}", options.vram_limit),
            format!("noise={}", denoise_level),
            format!("details={}", 0.3),
            format!("compression={}", 0.2),
            "estimate=12".to_string(),
        ];

        // 根据质量等级调整参数
        match quality {
            QualityLevel::Fast => {
                filter_args.push("instances=2".to_string());
            }
            QualityLevel::Balanced => {
                filter_args.extend_from_slice(&[
                    "halo=0.1".to_string(),
                    "blur=0.1".to_string(),
                ]);
            }
            QualityLevel::High | QualityLevel::Maximum => {
                filter_args.extend_from_slice(&[
                    "halo=0.2".to_string(),
                    "blur=0.2".to_string(),
                    "preblur=0.1".to_string(),
                ]);
            }
        }

        let filter_complex = format!("tvai_up={}", filter_args.join(":"));

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

        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &filter_complex,
        ];

        self.add_encoding_args(&mut args, &quality, &options);

        if options.keep_audio {
            args.extend_from_slice(&["-c:a", "copy"]);
        } else {
            args.push("-an");
        }

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

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

        let start_time = std::time::Instant::now();
        self.processor.execute_ffmpeg_command(&args, true, progress_callback).await?;
        let processing_time = start_time.elapsed();

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

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata: self.processor.create_metadata(
                operation_id,
                input_path,
                format!("restore_old_video: upscale={}, denoise={}, quality={:?}",
                    upscale_factor, denoise_level, quality),
            ),
        })
    }

    /// 应用游戏录像优化
    pub async fn apply_game_footage(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        upscale_factor: f32,
        sharpen: bool,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();

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

        // 使用 Gaia 模型进行游戏内容优化
        let mut filter_args = vec![
            "model=ghq-5".to_string(),
            format!("scale={}", upscale_factor as u32),
            format!("device={}", options.device),
            format!("vram={}", options.vram_limit),
            "compression=0".to_string(),
            "noise=0".to_string(),
            "estimate=8".to_string(),
        ];

        if sharpen {
            filter_args.extend_from_slice(&[
                "details=0.5".to_string(),
                "blur=-0.2".to_string(),
            ]);
        }

        // 根据质量等级调整参数
        match quality {
            QualityLevel::Fast => {
                filter_args.push("instances=2".to_string());
            }
            QualityLevel::Maximum => {
                filter_args.extend_from_slice(&[
                    "estimate=16".to_string(),
                    "details=0.7".to_string(),
                ]);
            }
            _ => {}
        }

        let filter_complex = format!("tvai_up={}", filter_args.join(":"));

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

        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &filter_complex,
        ];

        self.add_encoding_args(&mut args, &quality, &options);

        if options.keep_audio {
            args.extend_from_slice(&["-c:a", "copy"]);
        } else {
            args.push("-an");
        }

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

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

        let start_time = std::time::Instant::now();
        self.processor.execute_ffmpeg_command(&args, true, progress_callback).await?;
        let processing_time = start_time.elapsed();

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

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata: self.processor.create_metadata(
                operation_id,
                input_path,
                format!("game_footage: upscale={}, sharpen={}, quality={:?}",
                    upscale_factor, sharpen, quality),
            ),
        })
    }

    /// 应用图片放大
    pub async fn apply_image_upscale(
        &mut self,
        input_path: &Path,
        output_path: &Path,
        model: UpscaleModel,
        scale: f32,
        quality: QualityLevel,
        options: ProcessOptions,
        progress_callback: Option<&ProgressCallback>,
    ) -> Result<ProcessResult, TvaiError> {
        let operation_id = self.processor.generate_operation_id();

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

        // 构建图片放大滤镜参数
        let mut filter_args = vec![
            format!("model={}", model.as_str()),
            format!("scale={}", scale as u32),
            format!("device={}", options.device),
            format!("vram={}", options.vram_limit),
        ];

        // 根据质量等级调整参数
        match quality {
            QualityLevel::Fast => {
                filter_args.push("estimate=4".to_string());
            }
            QualityLevel::Balanced => {
                filter_args.push("estimate=8".to_string());
            }
            QualityLevel::High => {
                filter_args.extend_from_slice(&[
                    "estimate=12".to_string(),
                    "details=0.2".to_string(),
                ]);
            }
            QualityLevel::Maximum => {
                filter_args.extend_from_slice(&[
                    "estimate=20".to_string(),
                    "details=0.3".to_string(),
                    "noise=0.1".to_string(),
                ]);
            }
        }

        let filter_complex = format!("tvai_up={}", filter_args.join(":"));

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

        let mut args = vec![
            "-y", "-hide_banner", "-nostdin",
            "-i", input_path.to_str().unwrap(),
            "-filter_complex", &filter_complex,
        ];

        // 图片输出格式
        let output_format = options.output_format.as_deref().unwrap_or("png");
        args.extend_from_slice(&["-f", output_format]);

        // 图片质量设置
        match quality {
            QualityLevel::Fast => args.extend_from_slice(&["-q:v", "5"]),
            QualityLevel::Balanced => args.extend_from_slice(&["-q:v", "3"]),
            QualityLevel::High => args.extend_from_slice(&["-q:v", "2"]),
            QualityLevel::Maximum => args.extend_from_slice(&["-q:v", "1"]),
        }

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

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

        let start_time = std::time::Instant::now();
        self.processor.execute_ffmpeg_command(&args, true, progress_callback).await?;
        let processing_time = start_time.elapsed();

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

        Ok(ProcessResult {
            output_path: output_path.to_path_buf(),
            processing_time,
            metadata: self.processor.create_metadata(
                operation_id,
                input_path,
                format!("image_upscale: model={}, scale={}, quality={:?}",
                    model.as_str(), scale, quality),
            ),
        })
    }
}
