//! 视频合成处理

use serde_json;
use crate::utils;
use crate::ApiResponse;

/// 处理视频合成请求
pub async fn handle_video_synthesis(
    app: &tauri::AppHandle,
    project_dir: &std::path::PathBuf,
    payload: serde_json::Value,
) -> ApiResponse<serde_json::Value> {
    let payload_obj = match payload.as_object() {
        Some(p) => p,
        None => return ApiResponse {
            code: 400,
            message: "Invalid payload: expected object".to_string(),
            data: None,
        }
    };

    let video_paths = payload_obj.get("videoPaths").and_then(|v| v.as_array());
    let audio_path = payload_obj.get("audioPath").and_then(|v| v.as_str());
    let cover_path = payload_obj.get("coverPath").and_then(|v| v.as_str());
    let output_path = payload_obj.get("outputPath").and_then(|v| v.as_str());

    let output_path = match output_path {
        Some(p) => p,
        None => return ApiResponse {
            code: 400,
            message: "Missing required field: outputPath".to_string(),
            data: None,
        }
    };

    if let Some(v_paths) = video_paths {
        let mut concat_output = project_dir.clone();
        concat_output.push(format!("temp_concat_{}.mp4", utils::uuid_v4()));
        let mut final_output = project_dir.clone();
        final_output.push(format!("final_out_{}.mp4", utils::uuid_v4()));

        let mut paths_vec: Vec<String> = v_paths.iter()
            .filter_map(|v| v.as_str().map(|s| s.to_string()))
            .collect();

        if paths_vec.is_empty() {
            return ApiResponse {
                code: 400,
                message: "No valid video paths provided".to_string(),
                data: None
            };
        }

        let mut temp_cover_video: Option<std::path::PathBuf> = None;

        // 如果有封面，先转换为视频
        if let Some(c_path) = cover_path {
            let mut cover_v_path = project_dir.clone();
            cover_v_path.push(format!("temp_cover_{}.mp4", utils::uuid_v4()));
            let cover_v_path_str = cover_v_path.to_string_lossy().to_string();

            match crate::ffmpeg_cmd::create_cover_video(app, c_path, &cover_v_path_str, "0.5").await {
                Ok(_) => {
                    paths_vec.insert(0, cover_v_path_str);
                    temp_cover_video = Some(cover_v_path);
                }
                Err(e) => {
                    return ApiResponse {
                        code: 500,
                        message: format!("封面视频转换失败: {}", e),
                        data: None,
                    };
                }
            }
        }

        // 执行视频拼接
        match crate::ffmpeg_cmd::concat_videos_robust(app, paths_vec, concat_output.to_string_lossy().as_ref()).await {
            Ok(_) => {
                // 如果有音频，合并音频；否则直接使用拼接结果
                let has_audio = audio_path.map(|p| !p.is_empty()).unwrap_or(false);

                if has_audio {
                    // 合并音频
                    match crate::ffmpeg_cmd::add_audio_to_video(
                        app,
                        concat_output.to_string_lossy().as_ref(),
                        audio_path.unwrap(),
                        final_output.to_string_lossy().as_ref(),
                    ).await {
                        Ok(_) => {
                            // 移动到目标路径
                            let move_result = std::fs::rename(&final_output, output_path)
                                .or_else(|_| {
                                    std::fs::copy(&final_output, output_path).map(|_| {
                                        let _ = std::fs::remove_file(&final_output);
                                    })
                                });
                            // 兜底：如果 rename 和 copy 都失败，强制删除 final_output
                            if move_result.is_err() {
                                let _ = std::fs::remove_file(&final_output);
                            }
                            // 清理临时文件
                            let _ = std::fs::remove_file(&concat_output);
                            if let Some(ref p) = temp_cover_video {
                                let _ = std::fs::remove_file(p);
                            }
                            match move_result {
                                Ok(_) => ApiResponse {
                                    code: 200,
                                    message: "压制成片成功".to_string(),
                                    data: Some(serde_json::json!({
                                        "outputPath": output_path,
                                    })),
                                },
                                Err(e) => ApiResponse {
                                    code: 500,
                                    message: format!("移动最终视频失败: {}", e),
                                    data: None,
                                }
                            }
                        }
                        Err(e) => {
                            let _ = std::fs::remove_file(&concat_output);
                            if let Some(ref p) = temp_cover_video {
                                let _ = std::fs::remove_file(p);
                            }
                            ApiResponse {
                                code: 500,
                                message: format!("音频合并失败: {}", e),
                                data: None
                            }
                        }
                    }
                } else {
                    // 无音频，移动到目标路径
                    let move_result = std::fs::rename(&concat_output, output_path)
                        .or_else(|_| {
                            std::fs::copy(&concat_output, output_path).map(|_| {
                                let _ = std::fs::remove_file(&concat_output);
                            })
                        });
                    // 兜底：如果 rename 和 copy 都失败，强制删除 concat_output
                    if move_result.is_err() {
                        let _ = std::fs::remove_file(&concat_output);
                    }
                    if let Some(ref p) = temp_cover_video {
                        let _ = std::fs::remove_file(p);
                    }
                    match move_result {
                        Ok(_) => ApiResponse {
                            code: 200,
                            message: "压制成片成功".to_string(),
                            data: Some(serde_json::json!({
                                "outputPath": output_path,
                            })),
                        },
                        Err(e) => ApiResponse {
                            code: 500,
                            message: format!("移动最终视频失败: {}", e),
                            data: None,
                        }
                    }
                }
            }
            Err(e) => {
                if let Some(ref p) = temp_cover_video {
                    let _ = std::fs::remove_file(p);
                }
                ApiResponse {
                    code: 500,
                    message: format!("视频拼接失败: {}", e),
                    data: None
                }
            }
        }
    } else {
        ApiResponse {
            code: 400,
            message: "Missing required field: videoPaths".to_string(),
            data: None
        }
    }
}
