use tauri::{State, AppHandle, Emitter};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use uuid::Uuid;
use serde::{Deserialize, Serialize};

use tvai::{
    TvaiProcessor, TvaiConfig, ProcessResult, TvaiError,
    VideoUpscaleParams, InterpolationParams, VideoEnhanceParams,
    ImageUpscaleParams, ImageFormat,
    UpscaleModel, InterpolationModel, QualityPreset,
    quick_upscale_video, quick_upscale_image, quick_interpolate_video, auto_enhance_video,
    detect_topaz_installation, detect_gpu_support, detect_ffmpeg,
    get_video_info, get_image_info, estimate_processing_time,
    GpuInfo, FfmpegInfo, VideoInfo,
};

/// TVAI处理任务状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TvaiTaskStatus {
    Pending,
    Processing,
    Completed,
    Failed,
    Cancelled,
}

/// TVAI处理任务
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TvaiTask {
    pub id: String,
    pub task_type: String,
    pub input_path: String,
    pub output_path: String,
    pub status: TvaiTaskStatus,
    pub progress: f32,
    pub error_message: Option<String>,
    pub created_at: chrono::DateTime<chrono::Utc>,
    pub started_at: Option<chrono::DateTime<chrono::Utc>>,
    pub completed_at: Option<chrono::DateTime<chrono::Utc>>,
    pub processing_time: Option<u64>, // milliseconds
}

/// TVAI服务状态管理
pub struct TvaiState {
    processor: Arc<Mutex<Option<TvaiProcessor>>>,
    tasks: Arc<Mutex<HashMap<String, TvaiTask>>>,
    config: Arc<Mutex<Option<TvaiConfig>>>,
}

impl TvaiState {
    pub fn new() -> Self {
        Self {
            processor: Arc::new(Mutex::new(None)),
            tasks: Arc::new(Mutex::new(HashMap::new())),
            config: Arc::new(Mutex::new(None)),
        }
    }
}

/// 检测Topaz Video AI安装
#[tauri::command]
pub async fn detect_topaz_installation_command() -> Result<Option<String>, String> {
    match detect_topaz_installation() {
        Some(path) => Ok(Some(path.to_string_lossy().to_string())),
        None => Ok(None),
    }
}

/// 检测GPU支持
#[tauri::command]
pub async fn detect_gpu_support_command() -> Result<GpuInfo, String> {
    Ok(detect_gpu_support())
}

/// 检测FFmpeg
#[tauri::command]
pub async fn detect_ffmpeg_command() -> Result<FfmpegInfo, String> {
    Ok(detect_ffmpeg())
}

/// 初始化TVAI配置
#[tauri::command]
pub async fn initialize_tvai_config(
    state: State<'_, TvaiState>,
    topaz_path: Option<String>,
    use_gpu: Option<bool>,
    temp_dir: Option<String>,
) -> Result<(), String> {
    let topaz_path = match topaz_path {
        Some(path) => PathBuf::from(path),
        None => detect_topaz_installation()
            .ok_or("Topaz Video AI not found. Please specify the installation path.")?,
    };

    let mut config_builder = TvaiConfig::builder()
        .topaz_path(topaz_path)
        .use_gpu(use_gpu.unwrap_or(true));

    if let Some(temp_dir) = temp_dir {
        config_builder = config_builder.temp_dir(PathBuf::from(temp_dir));
    }

    let config = config_builder
        .build()
        .map_err(|e| format!("Failed to create TVAI config: {}", e))?;

    let processor = TvaiProcessor::new(config.clone())
        .map_err(|e| format!("Failed to create TVAI processor: {}", e))?;

    {
        let mut config_guard = state.config.lock().unwrap();
        *config_guard = Some(config);
    }

    {
        let mut processor_guard = state.processor.lock().unwrap();
        *processor_guard = Some(processor);
    }

    Ok(())
}

/// 获取视频信息
#[tauri::command]
pub async fn get_video_info_command(
    video_path: String,
) -> Result<serde_json::Value, String> {
    let path = Path::new(&video_path);
    let info = get_video_info(path).await
        .map_err(|e| format!("Failed to get video info: {}", e))?;
    
    let json_info = serde_json::json!({
        "width": info.width,
        "height": info.height,
        "fps": info.fps,
        "duration": info.duration.as_secs(),
        "codec": info.codec,
        "bitrate": info.bitrate,
        "file_size": info.file_size,
    });
    
    Ok(json_info)
}

/// 获取图片信息
#[tauri::command]
pub async fn get_image_info_command(
    image_path: String,
) -> Result<serde_json::Value, String> {
    let path = Path::new(&image_path);
    let info = get_image_info(path)
        .map_err(|e| format!("Failed to get image info: {}", e))?;
    
    let json_info = serde_json::json!({
        "width": info.width,
        "height": info.height,
        "format": info.format,
        "color_depth": info.color_depth,
        "file_size": info.file_size,
    });
    
    Ok(json_info)
}

/// 估算处理时间
#[tauri::command]
pub async fn estimate_processing_time_command(
    input_path: String,
    scale_factor: Option<f32>,
) -> Result<u64, String> {
    let path = Path::new(&input_path);

    // 获取视频信息
    let video_info = get_video_info(path).await
        .map_err(|e| format!("Failed to get video info: {}", e))?;

    // 创建默认的放大参数
    let params = VideoUpscaleParams {
        scale_factor: scale_factor.unwrap_or(2.0),
        model: UpscaleModel::Iris3,
        compression: 0.0,
        blend: 0.0,
        quality_preset: QualityPreset::HighQuality,
        ..Default::default()
    };

    let time = estimate_processing_time(&video_info, &params);
    Ok(time.as_secs())
}

/// 快速视频放大
#[tauri::command]
pub async fn quick_upscale_video_command(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
    scale_factor: f32,
    model: Option<String>,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();
    
    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "video_upscale".to_string(),
        input_path: input_path.clone(),
        output_path: output_path.clone(),
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };
    
    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }
    
    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();
    
    // 异步处理
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();
    
    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }
        
        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
        
        let start_time = std::time::Instant::now();

        // 解析模型参数
        let upscale_model = if let Some(model_str) = model {
            match model_str.as_str() {
                "aaa-9" => Some(UpscaleModel::Aaa9),
                "ahq-12" => Some(UpscaleModel::Ahq12),
                "alq-13" => Some(UpscaleModel::Alq13),
                "alqs-2" => Some(UpscaleModel::Alqs2),
                "amq-13" => Some(UpscaleModel::Amq13),
                "amqs-2" => Some(UpscaleModel::Amqs2),
                "ghq-5" => Some(UpscaleModel::Ghq5),
                "iris-2" => Some(UpscaleModel::Iris2),
                "iris-3" => Some(UpscaleModel::Iris3),
                "nyx-3" => Some(UpscaleModel::Nyx3),
                "prob-4" => Some(UpscaleModel::Prob4),
                "thf-4" => Some(UpscaleModel::Thf4),
                "thd-3" => Some(UpscaleModel::Thd3),
                "thm-2" => Some(UpscaleModel::Thm2),
                "rhea-1" => Some(UpscaleModel::Rhea1),
                "rxl-1" => Some(UpscaleModel::Rxl1),
                _ => None, // 使用默认模型
            }
        } else {
            None // 使用默认模型
        };

        // 执行处理
        let result = tvai::quick_upscale_video_with_model(
            Path::new(&input_path),
            Path::new(&output_path),
            scale_factor,
            upscale_model,
        ).await;
        
        let processing_time = start_time.elapsed();
        
        // 更新任务状态
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                match result {
                    Ok(_) => {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                    Err(e) => {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
            }
        }
        
        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });
    
    Ok(task_id)
}

/// 快速图片放大
#[tauri::command]
pub async fn quick_upscale_image_command(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
    scale_factor: f32,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();
    
    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "image_upscale".to_string(),
        input_path: input_path.clone(),
        output_path: output_path.clone(),
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };
    
    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }
    
    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();
    
    // 异步处理
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();
    
    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }
        
        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
        
        let start_time = std::time::Instant::now();
        
        // 执行处理
        let result = quick_upscale_image(
            Path::new(&input_path),
            Path::new(&output_path),
            scale_factor,
        ).await;
        
        let processing_time = start_time.elapsed();
        
        // 更新任务状态
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                match result {
                    Ok(_) => {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                    Err(e) => {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
            }
        }
        
        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });
    
    Ok(task_id)
}

/// 快速视频插帧
#[tauri::command]
pub async fn quick_interpolate_video_command(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
    multiplier: f32,
    input_fps: u32,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();

    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "video_interpolation".to_string(),
        input_path: input_path.clone(),
        output_path: output_path.clone(),
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };

    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }

    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();

    // 异步处理
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();

    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();

        let start_time = std::time::Instant::now();

        // 执行插帧处理
        let result = quick_interpolate_video(
            Path::new(&input_path),
            Path::new(&output_path),
            multiplier,
            input_fps,
        ).await;

        let processing_time = start_time.elapsed();

        // 更新任务状态
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                match result {
                    Ok(_) => {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                    Err(e) => {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });

    Ok(task_id)
}

/// 自动增强视频
#[tauri::command]
pub async fn auto_enhance_video_command(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();

    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "video_auto_enhance".to_string(),
        input_path: input_path.clone(),
        output_path: output_path.clone(),
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };

    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }

    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();

    // 异步处理
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();

    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();

        let start_time = std::time::Instant::now();

        // 执行处理
        let result = auto_enhance_video(
            Path::new(&input_path),
            Path::new(&output_path),
        ).await;

        let processing_time = start_time.elapsed();

        // 更新任务状态
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                match result {
                    Ok(_) => {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                    Err(e) => {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });

    Ok(task_id)
}

/// 自动增强图片（使用快速放大作为替代）
#[tauri::command]
pub async fn auto_enhance_image_command(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
) -> Result<String, String> {
    // 使用快速图片放大作为自动增强的替代
    quick_upscale_image_command(app_handle, state, input_path, output_path, 2.0).await
}

/// 高级视频放大（支持自定义参数）
#[tauri::command]
pub async fn upscale_video_advanced(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
    scale_factor: f32,
    model: String,
    compression: f32,
    blend: f32,
    quality_preset: String,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();

    // 解析模型
    let upscale_model = match model.as_str() {
        "aaa-9" => UpscaleModel::Aaa9,
        "ahq-12" => UpscaleModel::Ahq12,
        "alq-13" => UpscaleModel::Alq13,
        "alqs-2" => UpscaleModel::Alqs2,
        "amq-13" => UpscaleModel::Amq13,
        "amqs-2" => UpscaleModel::Amqs2,
        "ghq-5" => UpscaleModel::Ghq5,
        "iris-2" => UpscaleModel::Iris2,
        "iris-3" => UpscaleModel::Iris3,
        "nyx-3" => UpscaleModel::Nyx3,
        "prob-4" => UpscaleModel::Prob4,
        "thf-4" => UpscaleModel::Thf4,
        "thd-3" => UpscaleModel::Thd3,
        "thm-2" => UpscaleModel::Thm2,
        "rhea-1" => UpscaleModel::Rhea1,
        "rxl-1" => UpscaleModel::Rxl1,
        _ => return Err(format!("Unsupported upscale model: {}", model)),
    };

    // 解析质量预设
    let preset = match quality_preset.as_str() {
        "fast" => QualityPreset::Fast,
        "balanced" => QualityPreset::Balanced,
        "high_quality" => QualityPreset::HighQuality,
        "maximum" => QualityPreset::Maximum,
        _ => return Err(format!("Unsupported quality preset: {}", quality_preset)),
    };

    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "video_upscale_advanced".to_string(),
        input_path: input_path.clone(),
        output_path: output_path.clone(),
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };

    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }

    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();

    // 异步处理
    let processor_clone = state.processor.clone();
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();

    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();

        let start_time = std::time::Instant::now();

        // 执行处理
        let result: Result<ProcessResult, TvaiError> = {
            let processor_guard = processor_clone.lock().unwrap();
            if let Some(ref mut processor) = processor_guard.as_ref() {
                let params = VideoUpscaleParams {
                    scale_factor,
                    model: upscale_model,
                    compression,
                    blend,
                    quality_preset: preset,
                    ..Default::default()
                };

                // 注意：这里需要克隆processor，因为我们不能在异步块中持有锁
                // 实际实现中可能需要重新设计架构
                Err(TvaiError::InvalidParameter("Processor architecture needs redesign for async usage".to_string()))
            } else {
                Err(TvaiError::ConfigurationError("TVAI processor not initialized".to_string()))
            }
        };

        let processing_time = start_time.elapsed();

        // 更新任务状态
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                match result {
                    Ok(_) => {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                    Err(e) => {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });

    Ok(task_id)
}

/// 高级图片放大（支持自定义参数）
#[tauri::command]
pub async fn upscale_image_advanced(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    input_path: String,
    output_path: String,
    scale_factor: f32,
    model: String,
    compression: f32,
    blend: f32,
    output_format: String,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();

    // 解析模型
    let upscale_model = match model.as_str() {
        "aaa-9" => UpscaleModel::Aaa9,
        "ahq-12" => UpscaleModel::Ahq12,
        "alq-13" => UpscaleModel::Alq13,
        "alqs-2" => UpscaleModel::Alqs2,
        "amq-13" => UpscaleModel::Amq13,
        "amqs-2" => UpscaleModel::Amqs2,
        "ghq-5" => UpscaleModel::Ghq5,
        "iris-2" => UpscaleModel::Iris2,
        "iris-3" => UpscaleModel::Iris3,
        "nyx-3" => UpscaleModel::Nyx3,
        "prob-4" => UpscaleModel::Prob4,
        "thf-4" => UpscaleModel::Thf4,
        "thd-3" => UpscaleModel::Thd3,
        "thm-2" => UpscaleModel::Thm2,
        "rhea-1" => UpscaleModel::Rhea1,
        "rxl-1" => UpscaleModel::Rxl1,
        _ => return Err(format!("Unsupported upscale model: {}", model)),
    };

    // 解析输出格式
    let format = match output_format.as_str() {
        "png" => ImageFormat::Png,
        "jpg" | "jpeg" => ImageFormat::Jpg,
        "tiff" => ImageFormat::Tiff,
        "bmp" => ImageFormat::Bmp,
        _ => return Err(format!("Unsupported output format: {}", output_format)),
    };

    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "image_upscale_advanced".to_string(),
        input_path: input_path.clone(),
        output_path: output_path.clone(),
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };

    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }

    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();

    // 异步处理（使用快速函数，因为高级处理器需要重新设计架构）
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();

    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();

        let start_time = std::time::Instant::now();

        // 执行处理（暂时使用快速函数）
        let result = quick_upscale_image(
            Path::new(&input_path),
            Path::new(&output_path),
            scale_factor,
        ).await;

        let processing_time = start_time.elapsed();

        // 更新任务状态
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                match result {
                    Ok(_) => {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                    Err(e) => {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });

    Ok(task_id)
}

/// 获取任务状态
#[tauri::command]
pub async fn get_tvai_task_status(
    state: State<'_, TvaiState>,
    task_id: String,
) -> Result<Option<TvaiTask>, String> {
    let tasks = state.tasks.lock().unwrap();
    Ok(tasks.get(&task_id).cloned())
}

/// 获取所有任务
#[tauri::command]
pub async fn get_all_tvai_tasks(
    state: State<'_, TvaiState>,
) -> Result<Vec<TvaiTask>, String> {
    let tasks = state.tasks.lock().unwrap();
    Ok(tasks.values().cloned().collect())
}

/// 取消任务
#[tauri::command]
pub async fn cancel_tvai_task(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    task_id: String,
) -> Result<(), String> {
    {
        let mut tasks = state.tasks.lock().unwrap();
        if let Some(task) = tasks.get_mut(&task_id) {
            if matches!(task.status, TvaiTaskStatus::Pending | TvaiTaskStatus::Processing) {
                task.status = TvaiTaskStatus::Cancelled;
                task.completed_at = Some(chrono::Utc::now());
            } else {
                return Err("Task cannot be cancelled in current state".to_string());
            }
        } else {
            return Err("Task not found".to_string());
        }
    }

    app_handle.emit("tvai_task_updated", &task_id).unwrap();
    Ok(())
}

/// 清理已完成的任务
#[tauri::command]
pub async fn cleanup_completed_tvai_tasks(
    state: State<'_, TvaiState>,
) -> Result<usize, String> {
    let mut tasks = state.tasks.lock().unwrap();
    let initial_count = tasks.len();

    tasks.retain(|_, task| {
        !matches!(task.status, TvaiTaskStatus::Completed | TvaiTaskStatus::Failed | TvaiTaskStatus::Cancelled)
    });

    let removed_count = initial_count - tasks.len();
    Ok(removed_count)
}

/// 列出可用/已下载模型
#[tauri::command]
pub async fn list_available_tvai_models() -> Result<serde_json::Value, String> {
    match tvai::list_available_models() {
        Ok((all, downloaded)) => {
            let all_json: Vec<serde_json::Value> = all.into_iter().map(|m| {
                serde_json::json!({
                    "short_name": m.short_name,
                    "display_name": m.display_name,
                    "model_type": match m.model_type {
                        tvai::ModelType::Upscale => "upscale",
                        tvai::ModelType::Interpolation => "interpolation",
                        tvai::ModelType::Other => "other",
                    },
                    "is_downloaded": m.is_downloaded,
                })
            }).collect();
            Ok(serde_json::json!({ "all": all_json, "downloaded": downloaded }))
        }
        Err(e) => Err(e.to_string()),
    }
}

/// 校验所需模型并给出替代建议
#[tauri::command]
pub async fn validate_tvai_models(required_models: Vec<String>) -> Result<serde_json::Value, String> {
    let refs: Vec<&str> = required_models.iter().map(|s| s.as_str()).collect();
    match tvai::validate_models(&refs) {
        Ok(report) => {
            // 转换 suggestions HashMap<String, Vec<String>> 为 JSON
            let suggestions_json: serde_json::Value = serde_json::json!(report.suggestions
                .into_iter()
                .map(|(k,v)| (k, v))
                .collect::<std::collections::HashMap<_,_>>());
            Ok(serde_json::json!({
                "required": report.required,
                "available": report.available,
                "missing": report.missing,
                "suggestions": suggestions_json
            }))
        }
        Err(e) => Err(e.to_string()),
    }
}

/// 调试模型检测 - 列出所有 JSON 和 TZ 文件
#[tauri::command]
pub async fn debug_model_detection() -> Result<serde_json::Value, String> {
    match tvai::utils::detect_topaz_installation() {
        Some(topaz_path) => {
            match tvai::ModelManager::new(&topaz_path) {
                Ok(manager) => {
                    let all_models = manager.get_all_models().map_err(|e| e.to_string())?;
                    let downloaded = manager.get_downloaded_models().map_err(|e| e.to_string())?;

                    // 列出所有 JSON 和 TZ 文件
                    let models_dir = topaz_path.join("models").exists().then(|| topaz_path.join("models"))
                        .or_else(|| {
                            let programdata_dir = std::path::PathBuf::from(r"C:\ProgramData\Topaz Labs LLC\Topaz Video AI\models");
                            programdata_dir.exists().then(|| programdata_dir)
                        });

                    let mut json_files = Vec::new();
                    let mut tz_files = Vec::new();

                    if let Some(dir) = models_dir {
                        if let Ok(entries) = std::fs::read_dir(&dir) {
                            for entry in entries.flatten() {
                                let filename = entry.file_name().to_string_lossy().to_string();
                                if filename.ends_with(".json") {
                                    json_files.push(filename);
                                } else if filename.ends_with(".tz") {
                                    tz_files.push(filename);
                                }
                            }
                        }
                    }

                    Ok(serde_json::json!({
                        "all_models": all_models.into_iter().map(|m| serde_json::json!({
                            "short_name": m.short_name,
                            "display_name": m.display_name,
                            "model_type": match m.model_type {
                                tvai::ModelType::Upscale => "upscale",
                                tvai::ModelType::Interpolation => "interpolation",
                                tvai::ModelType::Other => "other",
                            },
                            "is_downloaded": m.is_downloaded,
                        })).collect::<Vec<_>>(),
                        "downloaded_families": downloaded,
                        "json_files": json_files,
                        "tz_files": tz_files,
                    }))
                }
                Err(e) => Err(e.to_string()),
            }
        }
        None => Err("Topaz Video AI not found".to_string()),
    }
}

/// 检查 Topaz 环境变量设置
#[tauri::command]
pub async fn check_topaz_environment() -> Result<serde_json::Value, String> {
    use std::env;

    let topaz_path = detect_topaz_installation();
    let models_dir = if let Some(ref path) = topaz_path {
        let models_in_install = path.join("models");
        if models_in_install.exists() {
            Some(models_in_install)
        } else {
            let programdata_models = std::path::PathBuf::from(r"C:\ProgramData\Topaz Labs LLC\Topaz Video AI\models");
            if programdata_models.exists() {
                Some(programdata_models)
            } else {
                None
            }
        }
    } else {
        None
    };

    let current_tvai_model_dir = env::var("TVAI_MODEL_DIR").ok();
    let current_tvai_model_data_dir = env::var("TVAI_MODEL_DATA_DIR").ok();
    let current_path = env::var("PATH").ok();

    let topaz_in_path = if let (Some(ref path), Some(ref current)) = (&topaz_path, &current_path) {
        current.contains(&path.to_string_lossy().to_string())
    } else {
        false
    };

    Ok(serde_json::json!({
        "topaz_installation": topaz_path.as_ref().map(|p| p.to_string_lossy().to_string()),
        "models_directory": models_dir.as_ref().map(|p| p.to_string_lossy().to_string()),
        "environment_variables": {
            "TVAI_MODEL_DIR": current_tvai_model_dir,
            "TVAI_MODEL_DATA_DIR": current_tvai_model_data_dir,
            "topaz_in_path": topaz_in_path
        },
        "recommendations": {
            "should_set_tvai_model_dir": current_tvai_model_dir.is_none() && models_dir.is_some(),
            "should_set_tvai_model_data_dir": current_tvai_model_data_dir.is_none() && models_dir.is_some(),
            "should_add_to_path": !topaz_in_path && topaz_path.is_some(),
            "suggested_tvai_model_dir": models_dir.as_ref().map(|p| p.to_string_lossy().to_string()),
            "suggested_path_addition": topaz_path.as_ref().map(|p| p.to_string_lossy().to_string())
        }
    }))
}

/// 执行自定义 FFmpeg 命令
#[tauri::command]
pub async fn execute_ffmpeg_command(
    app_handle: AppHandle,
    state: State<'_, TvaiState>,
    command_args: Vec<String>,
    use_topaz_ffmpeg: Option<bool>,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();
    let use_topaz = use_topaz_ffmpeg.unwrap_or(true);

    // 创建任务记录
    let task = TvaiTask {
        id: task_id.clone(),
        task_type: "custom_ffmpeg".to_string(),
        input_path: command_args.get(2).unwrap_or(&"unknown".to_string()).clone(), // 通常 -i 后面是输入文件
        output_path: command_args.last().unwrap_or(&"unknown".to_string()).clone(), // 最后一个参数通常是输出文件
        status: TvaiTaskStatus::Pending,
        progress: 0.0,
        error_message: None,
        created_at: chrono::Utc::now(),
        started_at: None,
        completed_at: None,
        processing_time: None,
    };

    {
        let mut tasks = state.tasks.lock().unwrap();
        tasks.insert(task_id.clone(), task);
    }

    // 发送任务创建事件
    app_handle.emit("tvai_task_created", &task_id).unwrap();

    // 异步执行 FFmpeg 命令
    let tasks_clone = state.tasks.clone();
    let app_handle_clone = app_handle.clone();
    let task_id_clone = task_id.clone();

    tokio::spawn(async move {
        // 更新任务状态为处理中
        {
            let mut tasks = tasks_clone.lock().unwrap();
            if let Some(task) = tasks.get_mut(&task_id_clone) {
                task.status = TvaiTaskStatus::Processing;
                task.started_at = Some(chrono::Utc::now());
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();

        let start_time = std::time::Instant::now();

        // 执行 FFmpeg 命令
        let result = execute_ffmpeg_with_tvai(command_args.clone(), use_topaz, task_id_clone.clone(), app_handle_clone.clone()).await;

        let processing_time = start_time.elapsed();

        // 更新任务状态并发送结果事件
        match result {
            Ok((stdout_log, stderr_log)) => {
                {
                    let mut tasks = tasks_clone.lock().unwrap();
                    if let Some(task) = tasks.get_mut(&task_id_clone) {
                        task.status = TvaiTaskStatus::Completed;
                        task.progress = 100.0;
                        task.completed_at = Some(chrono::Utc::now());
                        task.processing_time = Some(processing_time.as_millis() as u64);
                    }
                }
                let _ = app_handle_clone.emit("ffmpeg_command_finished", &serde_json::json!({
                    "taskId": task_id_clone,
                    "success": true,
                    "stdout": stdout_log,
                    "stderr": stderr_log,
                    "args": command_args,
                }));
            }
            Err(e) => {
                {
                    let mut tasks = tasks_clone.lock().unwrap();
                    if let Some(task) = tasks.get_mut(&task_id_clone) {
                        task.status = TvaiTaskStatus::Failed;
                        task.error_message = Some(e.to_string());
                        task.completed_at = Some(chrono::Utc::now());
                    }
                }
                let _ = app_handle_clone.emit("ffmpeg_command_finished", &serde_json::json!({
                    "taskId": task_id_clone,
                    "success": false,
                    "stdout": "",
                    "stderr": e.to_string(),
                    "args": command_args,
                }));
            }
        }

        app_handle_clone.emit("tvai_task_updated", &task_id_clone).unwrap();
    });

    Ok(task_id)
}

/// 执行 FFmpeg 命令的内部函数（带进度监控）
async fn execute_ffmpeg_with_tvai(
    args: Vec<String>,
    use_topaz: bool,
    task_id: String,
    app_handle: tauri::AppHandle
) -> Result<(String, String), TvaiError> {
    use std::env;
    use std::io::{BufRead, BufReader};
    use std::process::Stdio;
    use tokio::process::Command as TokioCommand;
    use tokio::io::{AsyncBufReadExt, BufReader as TokioBufReader};

    // 检测 Topaz 安装路径
    let topaz_path = if use_topaz {
        detect_topaz_installation()
    } else {
        None
    };

    if use_topaz && topaz_path.is_none() {
        return Err(TvaiError::TopazNotFound("Topaz Video AI installation not found".into()));
    }

    let topaz_dir = topaz_path.unwrap_or_else(|| std::path::PathBuf::from("."));
    let ffmpeg_path = topaz_dir.join("ffmpeg.exe");

    // 设置模型目录环境变量
    let models_dir = topaz_dir.join("models");
    let programdata_models = std::path::PathBuf::from(r"C:\ProgramData\Topaz Labs LLC\Topaz Video AI\models");

    let model_dir = if models_dir.exists() {
        models_dir
    } else if programdata_models.exists() {
        programdata_models
    } else {
        models_dir // 默认使用安装目录下的 models
    };

    // 构建异步命令
    let mut cmd = TokioCommand::new(&ffmpeg_path);
    cmd.args(&args);
    cmd.current_dir(&topaz_dir);
    cmd.stdout(Stdio::piped());
    cmd.stderr(Stdio::piped());

    // 设置关键环境变量
    cmd.env("TVAI_MODEL_DIR", &model_dir);
    cmd.env("TVAI_MODEL_DATA_DIR", &model_dir);

    // 确保 PATH 包含 Topaz 目录
    if let Ok(current_path) = env::var("PATH") {
        let topaz_dir_str = topaz_dir.to_string_lossy();
        if !current_path.contains(&*topaz_dir_str) {
            let new_path = format!("{};{}", topaz_dir_str, current_path);
            cmd.env("PATH", new_path);
        }
    } else {
        cmd.env("PATH", topaz_dir.to_string_lossy().as_ref());
    }

    // 启动进程
    let mut child = cmd.spawn().map_err(|e| {
        TvaiError::FfmpegError(format!("Failed to spawn FFmpeg: {}", e))
    })?;

    let stderr = child.stderr.take().unwrap();
    let stdout = child.stdout.take().unwrap();

    // 异步读取 stderr 进行进度解析
    let task_id_clone = task_id.clone();
    let app_handle_clone = app_handle.clone();
    let stderr_handle = tokio::spawn(async move {
        let reader = TokioBufReader::new(stderr);
        let mut lines = reader.lines();
        let mut stderr_output = String::new();
        let mut total_duration: Option<f32> = None;

        while let Ok(Some(line)) = lines.next_line().await {
            stderr_output.push_str(&line);
            stderr_output.push('\n');

            // 打印调试信息
            println!("FFmpeg stderr line: {}", line);

            // 解析总时长信息
            if total_duration.is_none() && line.contains("Duration:") {
                if let Some(duration) = parse_duration_from_line(&line) {
                    total_duration = Some(duration);
                    println!("Detected total duration: {:.2} seconds", duration);
                }
            }

            // 解析进度信息
            if let Some(mut progress) = parse_ffmpeg_progress(&line) {
                // 如果有总时长，重新计算更准确的百分比
                if let Some(total) = total_duration {
                    if let Some(current_seconds) = parse_time_to_seconds(&progress.time) {
                        progress.percentage = (current_seconds / total * 100.0).min(100.0);
                    }
                }

                println!("Parsed progress: frame={}, fps={}, time={}, percentage={:.1}%",
                         progress.frame, progress.fps, progress.time, progress.percentage);

                // 发送 ffmpeg_progress 事件（原有功能）
                let emit_result = app_handle_clone.emit("ffmpeg_progress", &serde_json::json!({
                    "taskId": task_id_clone,
                    "progress": progress.percentage,
                    "frame": progress.frame,
                    "fps": progress.fps,
                    "time": progress.time,
                    "speed": progress.speed,
                    "bitrate": progress.bitrate
                }));

                // 如果任务ID以 "topaz_" 开头，也发送 topaz-progress 事件
                if task_id_clone.starts_with("topaz_") {
                    let status = if progress.percentage < 30.0 {
                        "分析视频信息..."
                    } else if progress.percentage < 70.0 {
                        "处理视频帧..."
                    } else if progress.percentage < 95.0 {
                        "编码输出..."
                    } else {
                        "即将完成..."
                    };

                    let _ = app_handle_clone.emit("topaz-progress", serde_json::json!({
                        "progress": progress.percentage as i32,
                        "status": status
                    }));
                }

                if let Err(e) = emit_result {
                    println!("Failed to emit progress event: {}", e);
                }
            }
        }
        stderr_output
    });

    // 异步读取 stdout
    let stdout_handle = tokio::spawn(async move {
        let reader = TokioBufReader::new(stdout);
        let mut lines = reader.lines();
        let mut stdout_output = String::new();

        while let Ok(Some(line)) = lines.next_line().await {
            stdout_output.push_str(&line);
            stdout_output.push('\n');
        }
        stdout_output
    });

    // 等待进程完成
    let status = child.wait().await.map_err(|e| {
        TvaiError::FfmpegError(format!("Failed to wait for FFmpeg: {}", e))
    })?;

    let stdout_log = stdout_handle.await.unwrap_or_default();
    let stderr_log = stderr_handle.await.unwrap_or_default();

    if !status.success() {
        return Err(TvaiError::FfmpegError(format!(
            "FFmpeg failed: {}",
            if stderr_log.is_empty() { stdout_log } else { stderr_log }
        )));
    }

    Ok((stdout_log, stderr_log))
}

/// FFmpeg 进度信息结构
#[derive(Debug)]
struct FfmpegProgress {
    frame: u32,
    fps: f32,
    time: String,
    bitrate: String,
    speed: String,
    percentage: f32,
}

/// 解析 FFmpeg 输出中的进度信息
fn parse_ffmpeg_progress(line: &str) -> Option<FfmpegProgress> {
    // FFmpeg 进度行格式可能包含回车符，需要处理最后一个完整的进度行
    // 实际格式: frame=   29 fps=2.3 q=7.0 size=       0KiB time=00:00:01.20 bitrate=   0.0kbits/s speed=N/A

    // 只处理包含 frame= 和 time= 的行，跳过 time=N/A 的行
    if !line.contains("frame=") || line.contains("time=N/A") {
        return None;
    }

    // 处理可能的回车符覆盖 - 取最后一个完整的进度信息
    let clean_line = if line.contains('\r') {
        // 按回车符分割，取最后一个非空部分
        line.split('\r')
            .filter(|s| !s.is_empty() && s.contains("frame="))
            .last()
            .unwrap_or(line)
    } else {
        line
    };

    println!("Attempting to parse progress line: {}", clean_line);

    let mut frame = 0u32;
    let mut fps = 0.0f32;
    let mut time = String::new();
    let mut bitrate = String::new();
    let mut speed = String::new();

    // 简单的字符串解析，避免正则表达式的复杂性
    // 按空格分割并查找各个字段
    let parts: Vec<&str> = clean_line.split_whitespace().collect();

    for i in 0..parts.len() {
        let part = parts[i];

        if part.starts_with("frame=") {
            if let Some(value) = part.strip_prefix("frame=") {
                frame = value.parse().unwrap_or(0);
            }
        } else if part.starts_with("fps=") {
            if let Some(value) = part.strip_prefix("fps=") {
                fps = value.parse().unwrap_or(0.0);
            }
        } else if part.starts_with("time=") {
            if let Some(value) = part.strip_prefix("time=") {
                time = value.to_string();
            }
        } else if part.starts_with("bitrate=") {
            if let Some(value) = part.strip_prefix("bitrate=") {
                bitrate = value.to_string();
            }
        } else if part.starts_with("speed=") {
            if let Some(value) = part.strip_prefix("speed=") {
                speed = value.to_string();
            }
        }

        // 处理分离的情况，如 "frame=" "29"
        if part == "frame=" && i + 1 < parts.len() {
            frame = parts[i + 1].parse().unwrap_or(0);
        } else if part == "fps=" && i + 1 < parts.len() {
            fps = parts[i + 1].parse().unwrap_or(0.0);
        } else if part == "time=" && i + 1 < parts.len() {
            time = parts[i + 1].to_string();
        } else if part == "bitrate=" && i + 1 < parts.len() {
            bitrate = parts[i + 1].to_string();
        } else if part == "speed=" && i + 1 < parts.len() {
            speed = parts[i + 1].to_string();
        }
    }

    // 简单的百分比估算 - 这里会在外部重新计算
    let percentage = if !time.is_empty() && time != "N/A" {
        if let Some(seconds) = parse_time_to_seconds(&time) {
            // 简单估算，外部会重新计算更准确的值
            (seconds / 60.0 * 100.0).min(100.0) // 假设60秒为100%
        } else {
            0.0
        }
    } else if frame > 0 {
        // 基于帧数的简单估算
        (frame as f32 / 1000.0 * 100.0).min(100.0) // 假设1000帧为100%
    } else {
        0.0
    };

    println!("Parsed: frame={}, fps={}, time={}, percentage={:.1}%", frame, fps, time, percentage);

    // 只有当解析到有效数据时才返回
    if frame > 0 || !time.is_empty() {
        Some(FfmpegProgress {
            frame,
            fps,
            time,
            bitrate,
            speed,
            percentage,
        })
    } else {
        None
    }
}

/// 解析时间字符串为秒数
fn parse_time_to_seconds(time_str: &str) -> Option<f32> {
    // 格式: HH:MM:SS.ms 或 MM:SS.ms
    let parts: Vec<&str> = time_str.split(':').collect();

    match parts.len() {
        3 => {
            // HH:MM:SS.ms
            let hours: f32 = parts[0].parse().ok()?;
            let minutes: f32 = parts[1].parse().ok()?;
            let seconds: f32 = parts[2].parse().ok()?;
            Some(hours * 3600.0 + minutes * 60.0 + seconds)
        }
        2 => {
            // MM:SS.ms
            let minutes: f32 = parts[0].parse().ok()?;
            let seconds: f32 = parts[1].parse().ok()?;
            Some(minutes * 60.0 + seconds)
        }
        1 => {
            // SS.ms
            parts[0].parse().ok()
        }
        _ => None,
    }
}

/// 从 FFmpeg 输出行中解析总时长
fn parse_duration_from_line(line: &str) -> Option<f32> {
    // 格式: "Duration: 00:00:41.25, start: 0.000000, bitrate: 10778 kb/s"
    if let Some(duration_start) = line.find("Duration: ") {
        let after_duration = &line[duration_start + 10..];
        if let Some(comma_pos) = after_duration.find(',') {
            let duration_str = &after_duration[..comma_pos];
            return parse_time_to_seconds(duration_str);
        }
    }
    None
}

/// 解析 FFmpeg 命令，特殊处理元数据参数
fn parse_ffmpeg_command(command: &str) -> Vec<String> {
    let mut args = Vec::new();
    let parts: Vec<&str> = command.split_whitespace().collect();

    let mut i = 1; // 跳过 "ffmpeg"
    while i < parts.len() {
        let part = parts[i];

        // 特殊处理 -metadata 参数
        if part == "-metadata" && i + 1 < parts.len() {
            args.push(part.to_string());

            // 查找 videoai= 开头的元数据
            if parts[i + 1].starts_with("videoai=") {
                // 收集所有后续的部分直到下一个 - 开头的参数或文件路径
                let mut metadata_parts = vec![parts[i + 1]];
                let mut j = i + 2;

                while j < parts.len() {
                    let next_part = parts[j];
                    // 如果遇到下一个参数（以 - 开头）或者看起来像文件路径，停止
                    if next_part.starts_with('-') ||
                       next_part.contains('\\') ||
                       next_part.contains('/') ||
                       next_part.ends_with(".mp4") ||
                       next_part.ends_with(".mov") ||
                       next_part.ends_with(".avi") {
                        break;
                    }
                    metadata_parts.push(next_part);
                    j += 1;
                }

                // 将元数据部分合并为单个参数
                args.push(metadata_parts.join(" "));
                i = j;
            } else {
                args.push(parts[i + 1].to_string());
                i += 2;
            }
        } else {
            args.push(part.to_string());
            i += 1;
        }
    }

    args
}



// ============================================================================
// Topaz Video AI 模板和命令生成相关命令
// ============================================================================

/// 获取 Topaz Video AI 模板列表
#[tauri::command]
pub async fn get_topaz_templates() -> Result<serde_json::Value, String> {
    use tvai::WebApi;

    match WebApi::get_templates() {
        Ok(templates) => {
            // 将模板转换为前端期望的格式
            let mut template_map = serde_json::Map::new();

            for template_info in templates {
                let template_data = serde_json::json!({
                    "name": template_info.name,
                    "description": template_info.description,
                    "category": "AI处理", // 默认分类
                    "icon": "🎯", // 默认图标
                    "settings": template_info.settings
                });
                template_map.insert(template_info.key, template_data);
            }

            Ok(serde_json::Value::Object(template_map))
        }
        Err(e) => Err(format!("获取模板失败: {}", e))
    }
}

/// 生成 Topaz Video AI FFmpeg 命令
#[tauri::command]
pub async fn generate_topaz_command(
    settings: serde_json::Value,
    input_file: String,
    output_file: String,
    processing_mode: String,
    rate_control: String,
) -> Result<String, String> {
    use tvai::{WebApi, web_api::{GenerateCommandRequest, ProcessingMode}};

    // 解析处理模式
    let mode = match processing_mode.as_str() {
        "two_pass" => ProcessingMode::TwoPass,
        _ => ProcessingMode::Single,
    };

    // 将 JSON 设置转换为 WebTopazSettings
    let web_settings: tvai::web_api::WebTopazSettings = serde_json::from_value(settings)
        .map_err(|e| format!("设置格式错误: {}", e))?;

    let request = GenerateCommandRequest {
        settings: web_settings,
        input_file,
        output_file,
        processing_mode: mode.clone(),
        rate_control,
    };

    let response = WebApi::generate_command(request);

    if response.success {
        // 根据处理模式返回相应的命令
        match mode {
            ProcessingMode::Single => {
                response.single_command.ok_or_else(|| "单阶段命令生成失败".to_string())
            }
            ProcessingMode::TwoPass => {
                if let (Some(analysis), Some(processing)) = (response.analysis_command, response.processing_command) {
                    Ok(format!("# 分析阶段\n{}\n\n# 处理阶段\n{}", analysis, processing))
                } else {
                    Err("两阶段命令生成失败".to_string())
                }
            }
        }
    } else {
        Err(response.error.unwrap_or_else(|| "命令生成失败".to_string()))
    }
}

/// 执行 Topaz Video AI 视频处理
#[tauri::command]
pub async fn execute_topaz_video_processing(
    settings: serde_json::Value,
    input_file: String,
    output_file: String,
    processing_mode: String,
    rate_control: String,
) -> Result<String, String> {
    use tvai::{WebApi, web_api::{GenerateCommandRequest, ProcessingMode}};

    // 解析处理模式
    let mode = match processing_mode.as_str() {
        "two_pass" => ProcessingMode::TwoPass,
        _ => ProcessingMode::Single,
    };

    // 将 JSON 设置转换为 WebTopazSettings
    let web_settings: tvai::web_api::WebTopazSettings = serde_json::from_value(settings)
        .map_err(|e| format!("设置格式错误: {}", e))?;

    let request = GenerateCommandRequest {
        settings: web_settings,
        input_file: input_file.clone(),
        output_file: output_file.clone(),
        processing_mode: mode.clone(),
        rate_control,
    };

    // 生成命令
    let response = WebApi::generate_command(request);

    if !response.success {
        return Err(response.error.unwrap_or_else(|| "命令生成失败".to_string()));
    }

    // 获取要执行的命令
    let command = match mode {
        ProcessingMode::Single => {
            response.single_command.ok_or_else(|| "单阶段命令生成失败".to_string())?
        }
        ProcessingMode::TwoPass => {
            // 对于两阶段处理，先执行分析命令，再执行处理命令
            if let (Some(analysis), Some(processing)) = (response.analysis_command, response.processing_command) {
                // 这里可以实现两阶段处理逻辑
                // 目前先返回处理命令
                processing
            } else {
                return Err("两阶段命令生成失败".to_string());
            }
        }
    };

    // 执行 FFmpeg 命令
    // 暂时返回成功消息，实际实现中应该调用 FFmpeg 执行引擎
    tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
    Ok(format!("视频处理完成: {} -> {}", input_file, output_file))
}

/// 执行 Topaz Video AI 视频处理（带进度监控）
#[tauri::command]
pub async fn execute_topaz_video_processing_with_progress(
    app_handle: tauri::AppHandle,
    settings: serde_json::Value,
    input_file: String,
    output_file: String,
    processing_mode: String,
    rate_control: String,
) -> Result<String, String> {
    use tvai::{WebApi, web_api::{GenerateCommandRequest, ProcessingMode}};

    // 解析处理模式
    let mode = match processing_mode.as_str() {
        "two_pass" => ProcessingMode::TwoPass,
        _ => ProcessingMode::Single,
    };

    // 将 JSON 设置转换为 WebTopazSettings
    let web_settings: tvai::web_api::WebTopazSettings = serde_json::from_value(settings)
        .map_err(|e| format!("设置格式错误: {}", e))?;

    let request = GenerateCommandRequest {
        settings: web_settings,
        input_file: input_file.clone(),
        output_file: output_file.clone(),
        processing_mode: mode.clone(),
        rate_control,
    };

    // 生成命令
    let response = WebApi::generate_command(request);

    if !response.success {
        return Err(response.error.unwrap_or_else(|| "命令生成失败".to_string()));
    }

    // 获取要执行的命令
    let command = match mode {
        ProcessingMode::Single => {
            response.single_command.ok_or_else(|| "单阶段命令生成失败".to_string())?
        }
        ProcessingMode::TwoPass => {
            if let (Some(_analysis), Some(processing)) = (response.analysis_command, response.processing_command) {
                processing
            } else {
                return Err("两阶段命令生成失败".to_string());
            }
        }
    };

    // 记录开始处理的详细信息
    println!("[Topaz] 开始处理视频");
    println!("[Topaz] 输入文件: {}", input_file);
    println!("[Topaz] 输出文件: {}", output_file);
    println!("[Topaz] 处理模式: {}", processing_mode);
    println!("[Topaz] 生成的命令: {}", command);

    // 发送开始事件
    let _ = app_handle.emit("topaz-progress", serde_json::json!({
        "progress": 0,
        "status": "开始处理视频..."
    }));

    // 解析命令参数 - 需要特殊处理包含空格的元数据
    let args = parse_ffmpeg_command(&command);
    println!("[FFmpeg] 执行参数: {:?}", args);

    // 生成临时任务ID用于进度监控
    let task_id = format!("topaz_{}", chrono::Utc::now().timestamp_millis());

    // 使用现有的 execute_ffmpeg_with_tvai 函数
    match execute_ffmpeg_with_tvai(args, true, task_id.clone(), app_handle.clone()).await {
        Ok((stdout, stderr)) => {
            println!("[FFmpeg] 处理成功完成");
            println!("[FFmpeg] stdout: {}", stdout);
            if !stderr.is_empty() {
                println!("[FFmpeg] stderr: {}", stderr);
            }

            // 发送完成事件
            let _ = app_handle.emit("topaz-progress", serde_json::json!({
                "progress": 100,
                "status": "处理完成！"
            }));

            Ok(format!("视频处理完成: {} -> {}", input_file, output_file))
        },
        Err(e) => {
            println!("[FFmpeg ERROR] 处理失败: {:?}", e);

            // 构建详细的错误消息
            let error_msg = match e {
                TvaiError::FfmpegError(msg) => format!("FFmpeg 执行错误: {}", msg),
                TvaiError::FfmpegNotFound(msg) => format!("FFmpeg 未找到: {}", msg),
                TvaiError::TopazNotFound(msg) => format!("Topaz Video AI 未找到: {}", msg),
                TvaiError::IoError(msg) => format!("文件操作错误: {}", msg),
                TvaiError::ProcessingError(msg) => format!("处理错误: {}", msg),
                TvaiError::InvalidParameter(msg) => format!("参数错误: {}", msg),
                TvaiError::FileNotFound(msg) => format!("文件未找到: {}", msg),
                TvaiError::GpuError(msg) => format!("GPU 错误: {}", msg),
                TvaiError::UnsupportedFormat(msg) => format!("不支持的格式: {}", msg),
                TvaiError::ConfigurationError(msg) => format!("配置错误: {}", msg),
                TvaiError::InsufficientResources(msg) => format!("资源不足: {}", msg),
                TvaiError::OperationCancelled(msg) => format!("操作已取消: {}", msg),
                TvaiError::NetworkError(msg) => format!("网络错误: {}", msg),
                TvaiError::PermissionDenied(msg) => format!("权限被拒绝: {}", msg),
                TvaiError::GpuNotAvailable => "GPU 不可用".to_string(),
            };

            // 发送错误事件
            let _ = app_handle.emit("topaz-progress", serde_json::json!({
                "progress": 0,
                "status": "处理失败",
                "error": error_msg
            }));

            Err(error_msg)
        }
    }

}
