use anyhow::{anyhow, Result};
use reqwest::{Client, header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE}};
use std::time::Duration;
use tokio::time::sleep;
use tracing::{info, warn, debug};

use crate::data::models::bowong_text_video_agent::*;

/// BowongTextVideoAgent HTTP 客户端服务
#[derive(Clone)]
pub struct BowongTextVideoAgentService {
    client: Client,
    config: BowongTextVideoAgentConfig,
}

impl BowongTextVideoAgentService {
    /// 创建新的服务实例
    pub fn new(config: BowongTextVideoAgentConfig) -> Result<Self> {
        // 验证配置
        if config.base_url.trim().is_empty() {
            return Err(anyhow!("Base URL cannot be empty"));
        }
        if config.api_key.trim().is_empty() {
            return Err(anyhow!("API key cannot be empty"));
        }

        let mut headers = HeaderMap::new();
        headers.insert(
            AUTHORIZATION,
            HeaderValue::from_str(&format!("Bearer {}", config.api_key))
                .map_err(|e| anyhow!("Invalid API key: {}", e))?,
        );
        headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));

        let client = Client::builder()
            .timeout(Duration::from_secs(config.timeout.unwrap_or(30)))
            .default_headers(headers)
            .build()
            .map_err(|e| anyhow!("Failed to create HTTP client: {}", e))?;

        Ok(Self { client, config })
    }

    /// 获取服务配置的只读访问
    pub fn get_config(&self) -> &BowongTextVideoAgentConfig {
        &self.config
    }

    /// 执行 HTTP 请求的通用方法
    async fn execute_request<T, R>(&self, endpoint: &str, request: Option<&T>) -> Result<R>
    where
        T: serde::Serialize,
        R: serde::de::DeserializeOwned,
    {
        let url = format!("{}/{}", self.config.base_url.trim_end_matches('/'), endpoint);
        debug!("Making request to: {}", url);

        let mut req_builder = if request.is_some() {
            self.client.post(&url).json(request.unwrap())
        } else {
            self.client.get(&url)
        };

        let response = req_builder
            .send()
            .await
            .map_err(|e| anyhow!("Request failed: {}", e))?;

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            return Err(anyhow!("HTTP {} error: {}", status, error_text));
        }

        let result = response
            .json::<R>()
            .await
            .map_err(|e| anyhow!("Failed to parse response: {}", e))?;

        Ok(result)
    }

    /// 轮询任务状态直到完成
    async fn poll_task_status<F, Fut>(&self, task_id: &str, status_fn: F, max_wait_time: u64, poll_interval: u64) -> Result<TaskStatusResponse>
    where
        F: Fn(String) -> Fut,
        Fut: std::future::Future<Output = Result<TaskStatusResponse>>,
    {
        let start_time = std::time::Instant::now();
        let max_duration = Duration::from_secs(max_wait_time);
        let poll_duration = Duration::from_secs(poll_interval);

        loop {
            if start_time.elapsed() > max_duration {
                return Err(anyhow!("Task polling timeout after {} seconds", max_wait_time));
            }

            let status = status_fn(task_id.to_string()).await?;
            
            match status.status.as_str() {
                "completed" | "success" => {
                    info!("Task {} completed successfully", task_id);
                    return Ok(status);
                }
                "failed" | "error" => {
                    let error_msg = status.error.unwrap_or("Unknown error".to_string());
                    return Err(anyhow!("Task {} failed: {}", task_id, error_msg));
                }
                "cancelled" => {
                    return Err(anyhow!("Task {} was cancelled", task_id));
                }
                _ => {
                    debug!("Task {} status: {}, progress: {:?}", task_id, status.status, status.progress);
                    sleep(poll_duration).await;
                }
            }
        }
    }

    // ============================================================================
    // 提示词预处理模块
    // ============================================================================

    /// 获取示例提示词
    pub async fn get_sample_prompt(&self) -> Result<ApiResponse> {
        self.execute_request::<(), ApiResponse>("sample_prompt", None).await
    }

    /// 健康检查
    pub async fn health_check(&self) -> Result<ApiResponse> {
        self.execute_request::<(), ApiResponse>("health", None).await
    }

    // ============================================================================
    // 文件操作模块
    // ============================================================================

    /// 上传文件到 S3
    pub async fn upload_file_to_s3(&self, request: &S3FileUploadRequest) -> Result<FileUploadResponse> {
        self.execute_request("upload_file_to_s3", Some(request)).await
    }

    /// 上传文件到 COS
    pub async fn upload_file(&self, request: &COSFileUploadRequest) -> Result<FileUploadResponse> {
        self.execute_request("upload_file", Some(request)).await
    }

    /// 文件健康检查
    pub async fn file_health_check(&self) -> Result<ApiResponse> {
        self.execute_request::<(), ApiResponse>("file_health", None).await
    }

    // ============================================================================
    // 视频模板管理模块
    // ============================================================================

    /// 获取模板列表
    pub async fn get_templates(&self, request: &TemplateListRequest) -> Result<TemplateListResponse> {
        self.execute_request("templates", Some(request)).await
    }

    /// 获取单个模板
    pub async fn get_template(&self, template_id: &str) -> Result<VideoTemplate> {
        let endpoint = format!("templates/{}", template_id);
        self.execute_request::<(), VideoTemplate>(&endpoint, None).await
    }

    /// 创建模板
    pub async fn create_template(&self, request: &CreateTemplateRequest) -> Result<VideoTemplate> {
        self.execute_request("templates", Some(request)).await
    }

    /// 更新模板
    pub async fn update_template(&self, request: &UpdateTemplateRequest) -> Result<VideoTemplate> {
        let endpoint = format!("templates/{}", request.id);
        self.execute_request(&endpoint, Some(request)).await
    }

    /// 删除模板
    pub async fn delete_template(&self, template_id: &str) -> Result<ApiResponse> {
        let url = format!("{}/templates/{}", self.config.base_url.trim_end_matches('/'), template_id);
        let response = self.client.delete(&url).send().await
            .map_err(|e| anyhow!("Delete request failed: {}", e))?;

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            return Err(anyhow!("HTTP {} error: {}", status, error_text));
        }

        let result = response.json::<ApiResponse>().await
            .map_err(|e| anyhow!("Failed to parse response: {}", e))?;

        Ok(result)
    }

    // ============================================================================
    // Midjourney 图片生成模块
    // ============================================================================

    /// 检查提示词
    pub async fn check_prompt(&self, params: &PromptCheckParams) -> Result<ApiResponse> {
        self.execute_request("check_prompt", Some(params)).await
    }

    /// 同步生成图片
    pub async fn sync_generate_image(&self, request: &SyncImageGenerationRequest) -> Result<ImageGenerationResponse> {
        let max_wait_time = request.max_wait_time.unwrap_or(120);
        let poll_interval = request.poll_interval.unwrap_or(2);

        // 首先异步提交任务
        let async_request = AsyncImageGenerationRequest {
            prompt: request.prompt.clone(),
            img_file: request.img_file.clone(),
        };
        let task_response = self.async_generate_image(&async_request).await?;

        // 轮询任务状态
        let final_status = self.poll_task_status(
            task_response.task_id(),
            |task_id| async move { self.get_task_status(&task_id).await },
            max_wait_time as u64,
            poll_interval as u64,
        ).await?;

        Ok(ImageGenerationResponse {
            task_id: final_status.task_id,
            status: final_status.status,
            images: final_status.result.and_then(|r| {
                r.get("images").and_then(|v| serde_json::from_value(v.clone()).ok())
            }),
            error: final_status.error,
        })
    }

    /// 异步生成图片
    pub async fn async_generate_image(&self, request: &AsyncImageGenerationRequest) -> Result<TaskResponse> {
        self.execute_request("async_generate_image", Some(request)).await
    }

    /// 描述图片
    pub async fn describe_image(&self, request: &ImageDescribeRequest) -> Result<ApiResponse> {
        self.execute_request("describe_image", Some(request)).await
    }

    // ============================================================================
    // 极梦视频生成模块
    // ============================================================================

    /// 生成视频
    pub async fn generate_video(&self, request: &VideoGenerationRequest) -> Result<VideoGenerationResponse> {
        if let Some(max_wait_time) = request.max_wait_time {
            // 同步模式
            let poll_interval = request.poll_interval.unwrap_or(5);
            
            // 异步提交任务
            let task_response = self.execute_request::<VideoGenerationRequest, TaskResponse>("generate_video", Some(request)).await?;
            
            // 轮询状态
            let final_status = self.poll_task_status(
                task_response.task_id(),
                |task_id| async move { self.get_task_status(&task_id).await },
                max_wait_time as u64,
                poll_interval as u64,
            ).await?;

            Ok(VideoGenerationResponse {
                task_id: final_status.task_id,
                status: final_status.status,
                video_url: final_status.result.and_then(|r| {
                    r.get("video_url").and_then(|v| v.as_str().map(|s| s.to_string()))
                }),
                progress: final_status.progress,
                error: final_status.error,
            })
        } else {
            // 异步模式
            let task_response = self.execute_request::<VideoGenerationRequest, TaskResponse>("generate_video", Some(request)).await?;
            Ok(VideoGenerationResponse {
                task_id: task_response.data.clone(),
                status: task_response.status.to_string(),
                video_url: None,
                progress: None,
                error: None,
            })
        }
    }

    /// 批量查询视频状态
    pub async fn batch_query_video_status(&self, request: &VideoTaskStatus) -> Result<BatchVideoStatusResponse> {
        self.execute_request("batch_query_video_status", Some(request)).await
    }

    // ============================================================================
    // 任务管理模块
    // ============================================================================

    /// 创建任务
    pub async fn create_task(&self, request: &TaskRequest) -> Result<TaskResponse> {
        self.execute_request("create_task", Some(request)).await
    }

    /// 获取任务状态
    pub async fn get_task_status(&self, task_id: &str) -> Result<TaskStatusResponse> {
        let endpoint = format!("task_status/{}", task_id);
        self.execute_request::<(), TaskStatusResponse>(&endpoint, None).await
    }

    /// 检查任务类型
    pub async fn check_task_type(&self, params: &CheckTaskTypeParams) -> Result<ApiResponse> {
        self.execute_request("check_task_type", Some(params)).await
    }

    // ============================================================================
    // 302AI 服务集成模块
    // ============================================================================

    /// 302AI MJ 异步生成图片
    pub async fn ai302_mj_async_generate_image(&self, request: &AI302MJImageRequest) -> Result<TaskResponse> {
        self.execute_request("ai302_mj_async_generate_image", Some(request)).await
    }

    /// 302AI MJ 取消任务
    pub async fn ai302_mj_cancel_task(&self, request: &AI302TaskCancelRequest) -> Result<ApiResponse> {
        self.execute_request("ai302_mj_cancel_task", Some(request)).await
    }

    /// 302AI MJ 查询任务状态
    pub async fn ai302_mj_query_task_status(&self, params: &AI302TaskStatusParams) -> Result<TaskStatusResponse> {
        self.execute_request("ai302_mj_query_task_status", Some(params)).await
    }

    /// 302AI MJ 描述图片
    pub async fn ai302_mj_describe_image(&self, request: &ImageDescribeRequest) -> Result<ApiResponse> {
        self.execute_request("ai302_mj_describe_image", Some(request)).await
    }

    /// 302AI MJ 同步生成图片
    pub async fn ai302_mj_sync_generate_image(&self, request: &SyncImageGenerationRequest) -> Result<ImageGenerationResponse> {
        let max_wait_time = request.max_wait_time.unwrap_or(120);
        let poll_interval = request.poll_interval.unwrap_or(2);

        let ai302_request = AI302MJImageRequest {
            prompt: request.prompt.clone(),
            img_file: request.img_file.clone(),
            max_wait_time: Some(max_wait_time),
            poll_interval: Some(poll_interval),
        };

        let task_response = self.ai302_mj_async_generate_image(&ai302_request).await?;

        let final_status = self.poll_task_status(
            task_response.task_id(),
            |task_id| async move {
                self.ai302_mj_query_task_status(&AI302TaskStatusParams { task_id }).await
            },
            max_wait_time as u64,
            poll_interval as u64,
        ).await?;

        Ok(ImageGenerationResponse {
            task_id: final_status.task_id,
            status: final_status.status,
            images: final_status.result.and_then(|r| {
                r.get("images").and_then(|v| serde_json::from_value(v.clone()).ok())
            }),
            error: final_status.error,
        })
    }

    /// 302AI JM 同步生成视频
    pub async fn ai302_jm_sync_generate_video(&self, request: &AI302JMVideoRequest) -> Result<VideoGenerationResponse> {
        let max_wait_time = request.max_wait_time.unwrap_or(300);
        let poll_interval = request.poll_interval.unwrap_or(5);

        let task_response = self.ai302_jm_async_generate_video(request).await?;

        let final_status = self.poll_task_status(
            task_response.task_id(),
            |task_id| async move { self.ai302_jm_query_video_status(&task_id).await },
            max_wait_time as u64,
            poll_interval as u64,
        ).await?;

        Ok(VideoGenerationResponse {
            task_id: final_status.task_id,
            status: final_status.status,
            video_url: final_status.result.and_then(|r| {
                r.get("video_url").and_then(|v| v.as_str().map(|s| s.to_string()))
            }),
            progress: final_status.progress,
            error: final_status.error,
        })
    }

    /// 302AI JM 异步生成视频
    pub async fn ai302_jm_async_generate_video(&self, request: &AI302JMVideoRequest) -> Result<TaskResponse> {
        self.execute_request("ai302_jm_async_generate_video", Some(request)).await
    }

    /// 302AI JM 查询视频状态
    pub async fn ai302_jm_query_video_status(&self, task_id: &str) -> Result<TaskStatusResponse> {
        let endpoint = format!("ai302_jm_query_video_status/{}", task_id);
        self.execute_request::<(), TaskStatusResponse>(&endpoint, None).await
    }

    /// 302AI VEO 异步提交
    pub async fn ai302_veo_async_submit(&self, request: &AI302VEOVideoRequest) -> Result<TaskResponse> {
        self.execute_request("ai302_veo_async_submit", Some(request)).await
    }

    /// 302AI VEO 同步生成视频
    pub async fn ai302_veo_sync_generate_video(&self, request: &AI302VEOVideoRequest) -> Result<VideoGenerationResponse> {
        let max_wait_time = request.max_wait_time.unwrap_or(500); // 8分钟
        let poll_interval = request.interval.unwrap_or(5);

        let task_response = self.ai302_veo_async_submit(request).await?;

        let final_status = self.poll_task_status(
            task_response.task_id(),
            |task_id| async move {
                self.ai302_veo_get_task_status(&AI302VEOTaskStatusParams { task_id }).await
            },
            max_wait_time as u64,
            poll_interval as u64,
        ).await?;

        Ok(VideoGenerationResponse {
            task_id: final_status.task_id,
            status: final_status.status,
            video_url: final_status.result.and_then(|r| {
                r.get("video_url").and_then(|v| v.as_str().map(|s| s.to_string()))
            }),
            progress: final_status.progress,
            error: final_status.error,
        })
    }

    /// 302AI VEO 获取任务状态
    pub async fn ai302_veo_get_task_status(&self, params: &AI302VEOTaskStatusParams) -> Result<TaskStatusResponse> {
        self.execute_request("ai302_veo_get_task_status", Some(params)).await
    }

    // ============================================================================
    // 海螺API模块
    // ============================================================================

    /// 生成语音
    pub async fn generate_speech(&self, request: &SpeechGenerationRequest) -> Result<ApiResponse> {
        self.execute_request("generate_speech", Some(request)).await
    }

    /// 获取声音列表
    pub async fn get_voices(&self) -> Result<VoiceListResponse> {
        self.execute_request::<(), VoiceListResponse>("get_voices", None).await
    }

    /// 上传音频文件
    pub async fn upload_audio_file(&self, request: &AudioFileUploadRequest) -> Result<FileUploadResponse> {
        self.execute_request("upload_audio_file", Some(request)).await
    }

    /// 克隆声音
    pub async fn clone_voice(&self, request: &VoiceCloneRequest) -> Result<ApiResponse> {
        self.execute_request("clone_voice", Some(request)).await
    }

    // ============================================================================
    // 聚合接口模块
    // ============================================================================

    /// 获取图片模型列表
    pub async fn get_image_model_list(&self) -> Result<ModelListResponse> {
        self.execute_request::<(), ModelListResponse>("get_image_model_list", None).await
    }

    /// 聚合同步生成图片
    pub async fn union_sync_generate_image(&self, request: &UnionImageGenerationRequest) -> Result<ImageGenerationResponse> {
        self.execute_request("union_sync_generate_image", Some(request)).await
    }

    /// 获取视频模型列表
    pub async fn get_video_model_list(&self) -> Result<ModelListResponse> {
        self.execute_request::<(), ModelListResponse>("get_video_model_list", None).await
    }

    /// 聚合异步生成视频
    pub async fn union_async_generate_video(&self, request: &UnionVideoGenerationRequest) -> Result<TaskResponse> {
        self.execute_request("union_async_generate_video", Some(request)).await
    }

    /// 聚合查询视频任务状态
    pub async fn union_query_video_task_status(&self, task_id: &str) -> Result<TaskStatusResponse> {
        let endpoint = format!("union_query_video_task_status/{}", task_id);
        self.execute_request::<(), TaskStatusResponse>(&endpoint, None).await
    }

    // ============================================================================
    // ComfyUI 工作流模块
    // ============================================================================

    /// 获取运行节点
    pub async fn get_running_node(&self, params: Option<&GetRunningNodeParams>) -> Result<ApiResponse> {
        self.execute_request("get_running_node", params).await
    }

    /// 提交 ComfyUI 任务
    pub async fn submit_comfyui_task(&self, request: &ComfyUITaskRequest) -> Result<TaskResponse> {
        self.execute_request("submit_comfyui_task", Some(request)).await
    }

    /// 查询 ComfyUI 任务状态
    pub async fn query_comfyui_task_status(&self, params: &ComfyUITaskStatusParams) -> Result<TaskStatusResponse> {
        self.execute_request("query_comfyui_task_status", Some(params)).await
    }

    /// 同步执行工作流
    pub async fn sync_execute_workflow(&self, request: &ComfyUISyncExecuteRequest) -> Result<ApiResponse> {
        self.execute_request("sync_execute_workflow", Some(request)).await
    }

    // ============================================================================
    // Hedra 口型合成模块
    // ============================================================================

    /// Hedra 上传文件
    pub async fn hedra_upload_file(&self, request: &HedraFileUploadRequest) -> Result<FileUploadResponse> {
        // 读取文件内容
        let file_data = std::fs::read(&request.file_path)
            .map_err(|e| anyhow!("Failed to read file {}: {}", request.file_path, e))?;

        // 获取文件名
        let filename = std::path::Path::new(&request.file_path)
            .file_name()
            .and_then(|name| name.to_str())
            .ok_or_else(|| anyhow!("Invalid file path: {}", request.file_path))?
            .to_string();

        // 使用 Hedra v3 API 上传文件
        let url = format!("{}/api/302/hedra/v3/file/upload", self.config.base_url.trim_end_matches('/'));
        debug!("Making multipart request to: {}", url);

        // 构造 multipart form
        let part = reqwest::multipart::Part::bytes(file_data)
            .file_name(filename.clone())
            .mime_str("application/octet-stream")
            .map_err(|e| anyhow!("Failed to create multipart part: {}", e))?;

        let mut form = reqwest::multipart::Form::new()
            .part("local_file", part);

        // 添加 purpose 参数（如果提供）
        if let Some(purpose) = &request.purpose {
            form = form.text("purpose", purpose.clone());
        }

        // 发送请求
        let response = self.client
            .post(&url)
            .multipart(form)
            .send()
            .await
            .map_err(|e| anyhow!("Request failed: {}", e))?;

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            return Err(anyhow!("HTTP {} error: {}", status, error_text));
        }

        let response_text = response.text().await
            .map_err(|e| anyhow!("Failed to read response: {}", e))?;

        debug!("Hedra upload response: {}", response_text);

        // 尝试解析为通用的 JSON 值，然后转换为我们的格式
        let json_value: serde_json::Value = serde_json::from_str(&response_text)
            .map_err(|e| anyhow!("Failed to parse JSON response: {}", e))?;

        // 根据实际响应格式构造 FileUploadResponse
        // Hedra v3 API 可能返回不同的字段名
        let file_url = if let Some(url) = json_value.get("file_url").and_then(|v| v.as_str()) {
            Some(url.to_string())
        } else if let Some(url) = json_value.get("url").and_then(|v| v.as_str()) {
            Some(url.to_string())
        } else if let Some(data) = json_value.get("data").and_then(|v| v.as_str()) {
            Some(data.to_string())
        } else if let Some(id) = json_value.get("id").and_then(|v| v.as_str()) {
            // 如果返回的是资源ID，我们可能需要构造完整的URL
            Some(id.to_string())
        } else {
            debug!("No file URL found in response, checking for success status");
            None
        };

        // 检查是否成功
        let status = if file_url.is_some() {
            true
        } else {
            // 检查响应中的状态字段
            json_value.get("status").and_then(|v| v.as_bool()).unwrap_or(false) ||
            json_value.get("success").and_then(|v| v.as_bool()).unwrap_or(false)
        };

        let message = json_value.get("message")
            .or_else(|| json_value.get("msg"))
            .and_then(|v| v.as_str())
            .unwrap_or(if status { "Upload successful" } else { "Upload failed" })
            .to_string();

        if !status && file_url.is_none() {
            return Err(anyhow!("Upload failed: {}", message));
        }

        Ok(FileUploadResponse {
            status,
            msg: message,
            data: file_url,
        })
    }

    /// Hedra 提交任务
    pub async fn hedra_submit_task(&self, request: &HedraTaskSubmitRequest) -> Result<TaskResponse> {
        println!("=== Hedra Submit Task Service ===");
        println!("img_file: {}", request.img_file);
        println!("audio_file: {}", request.audio_file);
        println!("prompt: '{}'", request.prompt);
        println!("resolution: {}", request.resolution);
        println!("aspect_ratio: {}", request.aspect_ratio);

        // 使用 Hedra v3 API 提交任务
        let url = format!("{}/api/302/hedra/v3/submit/task", self.config.base_url.trim_end_matches('/'));
        debug!("Making multipart request to: {}", url);

        // 检查是否为本地文件路径，如果是则读取文件内容
        let img_data = if std::path::Path::new(&request.img_file).exists() {
            println!("读取本地图片文件: {}", request.img_file);
            std::fs::read(&request.img_file)
                .map_err(|e| anyhow!("Failed to read image file {}: {}", request.img_file, e))?
        } else {
            return Err(anyhow!("Image file not found: {}", request.img_file));
        };

        let audio_data = if std::path::Path::new(&request.audio_file).exists() {
            println!("读取本地音频文件: {}", request.audio_file);
            std::fs::read(&request.audio_file)
                .map_err(|e| anyhow!("Failed to read audio file {}: {}", request.audio_file, e))?
        } else {
            return Err(anyhow!("Audio file not found: {}", request.audio_file));
        };

        // 获取文件名
        let img_filename = std::path::Path::new(&request.img_file)
            .file_name()
            .and_then(|name| name.to_str())
            .unwrap_or("image.jpg")
            .to_string();

        let audio_filename = std::path::Path::new(&request.audio_file)
            .file_name()
            .and_then(|name| name.to_str())
            .unwrap_or("audio.mp3")
            .to_string();

        println!("图片文件名: {}, 大小: {} bytes", img_filename, img_data.len());
        println!("音频文件名: {}, 大小: {} bytes", audio_filename, audio_data.len());

        // 构造 multipart form
        let img_part = reqwest::multipart::Part::bytes(img_data)
            .file_name(img_filename)
            .mime_str("image/jpeg")
            .map_err(|e| anyhow!("Failed to create image part: {}", e))?;

        let audio_part = reqwest::multipart::Part::bytes(audio_data)
            .file_name(audio_filename)
            .mime_str("audio/mpeg")
            .map_err(|e| anyhow!("Failed to create audio part: {}", e))?;

        let mut form = reqwest::multipart::Form::new()
            .part("img_file", img_part)
            .part("audio_file", audio_part);

        // 添加 prompt 参数
        if !request.prompt.is_empty() {
            println!("添加 prompt: {}", request.prompt);
            form = form.text("prompt", request.prompt.clone());
        }

        // 添加 resolution 参数
        println!("添加 resolution: {}", request.resolution);
        form = form.text("resolution", request.resolution.clone());

        // 添加 aspect_ratio 参数
        println!("添加 aspect_ratio: {}", request.aspect_ratio);
        form = form.text("aspect_ratio", request.aspect_ratio.clone());

        // 添加其他参数（如果有）
        let form = if let Some(params) = &request.params {
            let mut form = form;
            for (key, value) in params {
                if let Some(str_value) = value.as_str() {
                    form = form.text(key.clone(), str_value.to_string());
                }
            }
            form
        } else {
            form
        };

        println!("=== 发送 multipart 请求 ===");

        let response = self.client
            .post(&url)
            .multipart(form)
            .send()
            .await
            .map_err(|e| anyhow!("Request failed: {}", e))?;

        println!("响应状态: {}", response.status());

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            println!("错误响应: {}", error_text);
            return Err(anyhow!("HTTP {} error: {}", status, error_text));
        }

        // 先获取响应文本
        let response_text = response.text().await
            .map_err(|e| anyhow!("Failed to read response text: {}", e))?;

        println!("=== 原始响应内容 ===");
        println!("{}", response_text);
        println!("=== 响应内容结束 ===");

        // 然后解析JSON
        let result: TaskResponse = serde_json::from_str(&response_text)
            .map_err(|e| anyhow!("Failed to parse response: {} - Response: {}", e, response_text))?;

        println!("成功解析响应: {:?}", result);
        Ok(result)
    }

    /// Hedra 查询任务状态
    pub async fn hedra_query_task_status(&self, params: &HedraTaskStatusParams) -> Result<TaskStatusResponse> {
        // 使用 Hedra v3 API 查询任务状态
        let url = format!("{}/api/302/hedra/v3/task/status?task_id={}",
            self.config.base_url.trim_end_matches('/'),
            params.task_id);

        println!("=== Hedra 查询任务状态 ===");
        println!("请求URL: {}", url);
        println!("任务ID: {}", params.task_id);

        let response = self.client
            .get(&url)
            .send()
            .await
            .map_err(|e| anyhow!("Request failed: {}", e))?;

        let status_code = response.status();
        println!("响应状态码: {}", status_code);

        if !response.status().is_success() {
            let error_text = response.text().await.unwrap_or_default();
            println!("错误响应内容: {}", error_text);
            return Err(anyhow!("HTTP {} error: {}", status_code, error_text));
        }

        // 先获取响应文本，然后打印并解析
        let response_text = response.text().await
            .map_err(|e| anyhow!("Failed to read response text: {}", e))?;

        println!("=== 原始响应内容 ===");
        println!("{}", response_text);
        println!("=== 响应内容结束 ===");

        let hedra_response: HedraTaskStatusResponse = serde_json::from_str(&response_text)
            .map_err(|e| anyhow!("Failed to parse response JSON: {}", e))?;

        println!("解析后的 Hedra 响应: {:?}", hedra_response);

        // 转换为标准的 TaskStatusResponse 格式
        let result = hedra_response.to_task_status_response(params.task_id.clone());

        println!("转换后的标准响应: {:?}", result);

        Ok(result)
    }

    // ============================================================================
    // FFMPEG 任务模块
    // ============================================================================

    /// 提交 FFMPEG 任务
    pub async fn submit_ffmpeg_task(&self, request: &FFMPEGTaskRequest) -> Result<TaskResponse> {
        self.execute_request("submit_ffmpeg_task", Some(request)).await
    }

    /// 查询 FFMPEG 任务状态
    pub async fn query_ffmpeg_task_status(&self, params: &FFMPEGTaskStatusParams) -> Result<TaskStatusResponse> {
        self.execute_request("query_ffmpeg_task_status", Some(params)).await
    }

    // ============================================================================
    // 批量操作和工具方法
    // ============================================================================

    /// 批量取消任务
    pub async fn cancel_tasks(&self, task_ids: Vec<String>) -> Result<Vec<ApiResponse>> {
        let mut results = Vec::new();

        for task_id in task_ids {
            match self.ai302_mj_cancel_task(&AI302TaskCancelRequest { task_id: task_id.clone() }).await {
                Ok(result) => results.push(result),
                Err(e) => {
                    warn!("Failed to cancel task {}: {}", task_id, e);
                    results.push(ApiResponse {
                        status: false,
                        message: format!("Failed to cancel task: {}", e),
                        data: None,
                    });
                }
            }
        }

        Ok(results)
    }

    /// 批量查询任务状态
    pub async fn batch_query_task_status(&self, task_ids: Vec<String>) -> Result<Vec<TaskStatusResponse>> {
        let mut results = Vec::new();

        for task_id in task_ids {
            match self.get_task_status(&task_id).await {
                Ok(status) => results.push(status),
                Err(e) => {
                    warn!("Failed to get status for task {}: {}", task_id, e);
                    results.push(TaskStatusResponse {
                        task_id: task_id.clone(),
                        status: "error".to_string(),
                        progress: None,
                        result: None,
                        error: Some(format!("Failed to get status: {}", e)),
                        created_at: None,
                        updated_at: None,
                    });
                }
            }
        }

        Ok(results)
    }

    /// 等待任务完成
    pub async fn wait_for_task_completion(&self, task_id: &str, max_wait_time: u64, poll_interval: u64) -> Result<TaskStatusResponse> {
        self.poll_task_status(
            task_id,
            |task_id| async move { self.get_task_status(&task_id).await },
            max_wait_time,
            poll_interval,
        ).await
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tokio;

    fn create_test_config() -> BowongTextVideoAgentConfig {
        BowongTextVideoAgentConfig {
            base_url: "https://api.test.com".to_string(),
            api_key: "test-api-key".to_string(),
            timeout: Some(30),
            retry_attempts: Some(3),
            enable_cache: Some(true),
            max_concurrency: Some(10),
        }
    }

    fn create_test_service() -> Result<BowongTextVideoAgentService> {
        BowongTextVideoAgentService::new(create_test_config())
    }

    #[tokio::test]
    async fn test_service_creation() {
        let service = create_test_service();
        assert!(service.is_ok());
    }

    #[tokio::test]
    async fn test_config_validation() {
        // 测试有效配置
        let valid_config = create_test_config();
        let service = BowongTextVideoAgentService::new(valid_config);
        assert!(service.is_ok());

        // 测试无效配置 - 空 base_url
        let invalid_config = BowongTextVideoAgentConfig {
            base_url: "".to_string(),
            api_key: "test-key".to_string(),
            timeout: None,
            retry_attempts: None,
            enable_cache: None,
            max_concurrency: None,
        };
        let service = BowongTextVideoAgentService::new(invalid_config);
        assert!(service.is_err());
    }

    #[tokio::test]
    async fn test_data_model_serialization() {
        // 测试数据模型的序列化和反序列化
        let config = create_test_config();
        let json = serde_json::to_string(&config).unwrap();
        let deserialized: BowongTextVideoAgentConfig = serde_json::from_str(&json).unwrap();

        assert_eq!(config.base_url, deserialized.base_url);
        assert_eq!(config.api_key, deserialized.api_key);
        assert_eq!(config.timeout, deserialized.timeout);
    }
}
