use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashMap;

/// API 响应基础结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiResponse {
    pub status: bool,
    pub message: String,
    pub data: Option<serde_json::Value>,
}

/// 任务响应结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskResponse {
    pub status: bool,
    #[serde(deserialize_with = "deserialize_string_or_bool")]
    pub data: String,
    #[serde(deserialize_with = "deserialize_string_or_bool")]
    pub msg: String,
}

impl TaskResponse {
    /// 获取任务ID（从data字段）
    pub fn task_id(&self) -> &str {
        &self.data
    }
}

/// 任务状态响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskStatusResponse {
    #[serde(deserialize_with = "deserialize_string_or_bool")]
    pub task_id: String,
    #[serde(deserialize_with = "deserialize_string_or_bool")]
    pub status: String,
    pub progress: Option<f32>,
    pub result: Option<serde_json::Value>,
    #[serde(deserialize_with = "deserialize_optional_string_or_bool", default)]
    pub error: Option<String>,
    #[serde(deserialize_with = "deserialize_optional_string_or_bool", default)]
    pub created_at: Option<String>,
    #[serde(deserialize_with = "deserialize_optional_string_or_bool", default)]
    pub updated_at: Option<String>,
}

/// 文件上传响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileUploadResponse {
    pub status: bool,
    pub msg: String,
    pub data: Option<String>, // 文件URL
}

/// 提示词检查参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PromptCheckParams {
    pub prompt: String,
}

/// 同步图片生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SyncImageGenerationRequest {
    pub prompt: String,
    pub img_file: Option<String>,
    pub max_wait_time: Option<u32>,
    pub poll_interval: Option<u32>,
}

/// 异步图片生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AsyncImageGenerationRequest {
    pub prompt: String,
    pub img_file: Option<String>,
}

/// 图片描述请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageDescribeRequest {
    pub img_url: String,
}

/// 图片生成响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageGenerationResponse {
    pub task_id: String,
    pub status: String,
    pub images: Option<Vec<String>>,
    pub error: Option<String>,
}

/// 视频生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoGenerationRequest {
    pub prompt: String,
    pub img_url: Option<String>,
    pub duration: Option<u32>,
    pub max_wait_time: Option<u32>,
    pub poll_interval: Option<u32>,
}

/// 视频生成响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoGenerationResponse {
    pub task_id: String,
    pub status: String,
    pub video_url: Option<String>,
    pub progress: Option<f32>,
    pub error: Option<String>,
}

/// 视频任务状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoTaskStatus {
    pub task_ids: Vec<String>,
}

/// 批量视频状态响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchVideoStatusResponse {
    pub results: Vec<TaskStatusResponse>,
}

/// 任务请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskRequest {
    pub task_type: String,
    pub params: serde_json::Value,
}

/// 302AI MJ 图片请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AI302MJImageRequest {
    pub prompt: String,
    pub img_file: Option<String>,
    pub max_wait_time: Option<u32>,
    pub poll_interval: Option<u32>,
}

/// 302AI 任务取消请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AI302TaskCancelRequest {
    pub task_id: String,
}

/// 302AI 任务状态参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AI302TaskStatusParams {
    pub task_id: String,
}

/// 302AI JM 视频请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AI302JMVideoRequest {
    pub prompt: String,
    pub img_url: Option<String>,
    pub duration: Option<u32>,
    pub max_wait_time: Option<u32>,
    pub poll_interval: Option<u32>,
}

/// 302AI VEO 视频请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AI302VEOVideoRequest {
    pub prompt: String,
    pub img_url: Option<String>,
    pub duration: Option<u32>,
    pub max_wait_time: Option<u32>,
    pub interval: Option<u32>,
}

/// 302AI VEO 任务状态参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AI302VEOTaskStatusParams {
    pub task_id: String,
}

/// 语音生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpeechGenerationRequest {
    pub text: String,
    pub voice_id: Option<String>,
    pub speed: Option<f32>,
    pub volume: Option<f32>,
}

/// 声音列表响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VoiceListResponse {
    pub voices: Vec<VoiceInfo>,
}

/// 声音信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VoiceInfo {
    pub id: String,
    pub name: String,
    pub language: String,
    pub gender: String,
}

/// 音频文件上传请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AudioFileUploadRequest {
    pub file_data: Vec<u8>,
    pub filename: String,
}

/// 声音克隆请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VoiceCloneRequest {
    pub audio_url: String,
    pub voice_name: String,
}

/// 模型列表响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelListResponse {
    pub models: Vec<ModelInfo>,
}

/// 模型信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelInfo {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub capabilities: Vec<String>,
}

/// 聚合图片生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnionImageGenerationRequest {
    pub model: String,
    pub prompt: String,
    pub img_file: Option<String>,
    pub params: Option<HashMap<String, serde_json::Value>>,
}

/// 聚合视频生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnionVideoGenerationRequest {
    pub model: String,
    pub prompt: String,
    pub img_url: Option<String>,
    pub duration: Option<u32>,
    pub params: Option<HashMap<String, serde_json::Value>>,
}

/// 获取运行节点参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetRunningNodeParams {
    pub node_id: Option<String>,
}

/// ComfyUI 任务请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComfyUITaskRequest {
    pub workflow: serde_json::Value,
    pub params: Option<HashMap<String, serde_json::Value>>,
}

/// ComfyUI 任务状态参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComfyUITaskStatusParams {
    pub task_id: String,
}

/// ComfyUI 同步执行请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComfyUISyncExecuteRequest {
    pub workflow: serde_json::Value,
    pub max_wait_time: Option<u32>,
}

/// Hedra 文件上传请求（前端到后端）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HedraFileUploadRequest {
    pub file_path: String,
    pub purpose: Option<String>, // 'image', 'audio', 'video', 'voice'
}

/// Hedra 文件上传 API 请求（后端到 API）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HedraFileUploadApiRequest {
    pub file_data: Vec<u8>,
    pub filename: String,
    pub purpose: Option<String>,
}

/// Hedra 任务提交请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HedraTaskSubmitRequest {
    pub audio_file: String,
    pub img_file: String,
    #[serde(default)]
    pub prompt: String,
    #[serde(default = "default_resolution")]
    pub resolution: String,
    #[serde(default = "default_aspect_ratio")]
    pub aspect_ratio: String,
    pub params: Option<HashMap<String, serde_json::Value>>,
}

fn default_resolution() -> String {
    "720p".to_string()
}

fn default_aspect_ratio() -> String {
    "1:1".to_string()
}

/// Hedra 任务状态参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HedraTaskStatusParams {
    pub task_id: String,
}

/// Hedra 任务状态响应（原始格式）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HedraTaskStatusResponse {
    pub status: bool,
    pub data: Option<serde_json::Value>,
    pub msg: String,
}

impl HedraTaskStatusResponse {
    /// 转换为标准的 TaskStatusResponse 格式
    pub fn to_task_status_response(&self, task_id: String) -> TaskStatusResponse {
        // 解析 msg 字段来获取状态和进度信息
        let (status_str, progress) = self.parse_msg();

        TaskStatusResponse {
            task_id,
            status: status_str,
            progress,
            result: self.data.clone(),
            error: if self.status { None } else { Some(self.msg.clone()) },
            created_at: None,
            updated_at: None,
        }
    }

    /// 解析 msg 字段获取状态和进度
    fn parse_msg(&self) -> (String, Option<f32>) {
        // msg 格式示例: "task status: processing -> process:0.0%" 或 "task status: complete -> process:100.0%"
        if self.msg.contains("processing") {
            let progress = if let Some(percent_pos) = self.msg.find("process:") {
                let progress_str = &self.msg[percent_pos + 8..];
                if let Some(percent_end) = progress_str.find('%') {
                    progress_str[..percent_end].parse::<f32>().ok()
                } else {
                    None
                }
            } else {
                None
            };
            ("processing".to_string(), progress)
        } else if self.msg.contains("complete") || self.msg.contains("completed") || self.msg.contains("success") {
            let progress = if let Some(percent_pos) = self.msg.find("process:") {
                let progress_str = &self.msg[percent_pos + 8..];
                if let Some(percent_end) = progress_str.find('%') {
                    progress_str[..percent_end].parse::<f32>().ok()
                } else {
                    Some(100.0)
                }
            } else {
                Some(100.0)
            };
            ("success".to_string(), progress)
        } else if self.msg.contains("failed") || self.msg.contains("error") {
            ("failed".to_string(), None)
        } else {
            ("unknown".to_string(), None)
        }
    }
}

/// FFMPEG 任务请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FFMPEGTaskRequest {
    pub input_url: String,
    pub output_format: String,
    pub params: Option<HashMap<String, serde_json::Value>>,
}

/// FFMPEG 任务状态参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FFMPEGTaskStatusParams {
    pub task_id: String,
}

/// 视频模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoTemplate {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub config: serde_json::Value,
    pub created_at: String,
    pub updated_at: String,
}

/// 模板列表请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateListRequest {
    pub page: Option<u32>,
    pub page_size: Option<u32>,
    pub search: Option<String>,
}

/// 模板列表响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateListResponse {
    pub templates: Vec<VideoTemplate>,
    pub total: u32,
    pub page: u32,
    pub page_size: u32,
}

/// 创建模板请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateTemplateRequest {
    pub name: String,
    pub description: Option<String>,
    pub config: serde_json::Value,
}

/// 更新模板请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateTemplateRequest {
    pub id: String,
    pub name: Option<String>,
    pub description: Option<String>,
    pub config: Option<serde_json::Value>,
}

/// 检查任务类型参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CheckTaskTypeParams {
    pub task_type: String,
}

/// S3 文件上传请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct S3FileUploadRequest {
    pub file_data: Vec<u8>,
    pub filename: String,
    pub content_type: Option<String>,
}

/// COS 文件上传请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct COSFileUploadRequest {
    pub file_data: Vec<u8>,
    pub filename: String,
    pub content_type: Option<String>,
}

/// BowongTextVideoAgent 服务配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BowongTextVideoAgentConfig {
    pub base_url: String,
    pub api_key: String,
    pub timeout: Option<u64>,
    pub retry_attempts: Option<u32>,
    pub enable_cache: Option<bool>,
    pub max_concurrency: Option<u32>,
}

impl Default for BowongTextVideoAgentConfig {
    fn default() -> Self {
        Self {
            base_url: "https://api.bowong.com".to_string(),
            api_key: String::new(),
            timeout: Some(30),
            retry_attempts: Some(3),
            enable_cache: Some(true),
            max_concurrency: Some(8),
        }
    }
}

/// 自定义反序列化函数，处理字符串或布尔值
fn deserialize_string_or_bool<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
{
    use serde::de::{self, Visitor};
    use std::fmt;

    struct StringOrBoolVisitor;

    impl<'de> Visitor<'de> for StringOrBoolVisitor {
        type Value = String;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a string or boolean")
        }

        fn visit_str<E>(self, value: &str) -> Result<String, E>
        where
            E: de::Error,
        {
            Ok(value.to_string())
        }

        fn visit_string<E>(self, value: String) -> Result<String, E>
        where
            E: de::Error,
        {
            Ok(value)
        }

        fn visit_bool<E>(self, value: bool) -> Result<String, E>
        where
            E: de::Error,
        {
            Ok(value.to_string())
        }
    }

    deserializer.deserialize_any(StringOrBoolVisitor)
}

/// 自定义反序列化函数，处理可选的字符串或布尔值
fn deserialize_optional_string_or_bool<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
    D: Deserializer<'de>,
{
    use serde::de::{self, Visitor};
    use std::fmt;

    struct OptionalStringOrBoolVisitor;

    impl<'de> Visitor<'de> for OptionalStringOrBoolVisitor {
        type Value = Option<String>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("an optional string or boolean")
        }

        fn visit_none<E>(self) -> Result<Option<String>, E>
        where
            E: de::Error,
        {
            Ok(None)
        }

        fn visit_some<D>(self, deserializer: D) -> Result<Option<String>, D::Error>
        where
            D: Deserializer<'de>,
        {
            deserialize_string_or_bool(deserializer).map(Some)
        }

        fn visit_str<E>(self, value: &str) -> Result<Option<String>, E>
        where
            E: de::Error,
        {
            Ok(Some(value.to_string()))
        }

        fn visit_string<E>(self, value: String) -> Result<Option<String>, E>
        where
            E: de::Error,
        {
            Ok(Some(value))
        }

        fn visit_bool<E>(self, value: bool) -> Result<Option<String>, E>
        where
            E: de::Error,
        {
            Ok(Some(value.to_string()))
        }
    }

    deserializer.deserialize_option(OptionalStringOrBoolVisitor)
}
