use anyhow::{anyhow, Result};
use reqwest::Client;
use std::time::Duration;
use crate::data::models::video_generation::{
    DifyApiConfig, DifyApiRequest, DifyApiResponse, DifyInputs, VideoGenerationResult
};

/// 视频生成服务
/// 基于Dify API实现视频生成功能
pub struct VideoGenerationService {
    client: Client,
    config: DifyApiConfig,
}

impl VideoGenerationService {
    /// 创建新的视频生成服务实例
    pub fn new() -> Self {
        let client = Client::builder()
            .timeout(Duration::from_secs(300)) // 5分钟超时
            .build()
            .expect("Failed to create HTTP client");

        Self {
            client,
            config: DifyApiConfig::default(),
        }
    }

    /// 使用自定义配置创建视频生成服务
    pub fn with_config(config: DifyApiConfig) -> Self {
        let client = Client::builder()
            .timeout(Duration::from_secs(300))
            .build()
            .expect("Failed to create HTTP client");

        Self { client, config }
    }

    /// 生成视频
    pub async fn generate_video(
        &self,
        product: String,
        scene: String,
        model_desc: String,
        image_url: String,
        template: String,
        duplicate: u32,
    ) -> Result<VideoGenerationResult> {
        println!("🎬 开始生成视频...");
        println!("产品: {}", product);
        println!("场景: {}", scene);
        println!("模特: {}", model_desc);
        println!("图片: {}", image_url);
        println!("模板: {}", template);
        println!("数量: {}", duplicate);

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

        // 构建请求数据
        let request_data = DifyApiRequest {
            inputs: DifyInputs {
                product: product.clone(),
                scene: scene.clone(),
                model: model_desc.clone(),
                image: image_url.clone(),
                duplicate,
                template: template.clone(),
            },
            response_mode: "blocking".to_string(),
            user: "mixvideo-desktop".to_string(),
        };

        // 发送请求
        let url = format!("{}/v1/workflows/run", self.config.host);
        let response = self
            .client
            .post(&url)
            .header("Authorization", format!("Bearer {}", self.config.api_key))
            .header("Content-Type", "application/json")
            .json(&request_data)
            .send()
            .await
            .map_err(|e| anyhow!("请求失败: {}", e))?;

        let status = response.status();
        let response_text = response
            .text()
            .await
            .map_err(|e| anyhow!("读取响应失败: {}", e))?;

        println!("📡 API响应状态: {}", status);
        println!("📡 API响应内容: {}", response_text);

        if !status.is_success() {
            return Err(anyhow!("API请求失败: {} - {}", status, response_text));
        }

        // 解析响应
        let api_response: DifyApiResponse = serde_json::from_str(&response_text)
            .map_err(|e| anyhow!("解析响应失败: {} - 响应内容: {}", e, response_text))?;

        if let Some(error) = api_response.error {
            return Err(anyhow!("API返回错误: {}", error));
        }

        let data = api_response
            .data
            .ok_or_else(|| anyhow!("API响应中缺少data字段"))?;

        let video_urls = data.outputs.output;
        if video_urls.is_empty() {
            return Err(anyhow!("API未返回任何视频URL"));
        }

        let generation_time = start_time.elapsed().as_millis() as u64;

        println!("✅ 视频生成成功!");
        println!("🎥 生成的视频数量: {}", video_urls.len());
        println!("⏱️ 生成耗时: {}ms", generation_time);

        // 处理视频路径（如果是file://协议，直接使用本地路径）
        let video_paths = self.process_video_paths(&video_urls).await?;

        Ok(VideoGenerationResult {
            video_urls,
            video_paths,
            generation_time,
            api_response: Some(response_text),
        })
    }

    /// 处理视频路径（支持file://协议和HTTP URL）
    async fn process_video_paths(&self, video_urls: &[String]) -> Result<Vec<String>> {
        let mut video_paths = Vec::new();

        for url in video_urls.iter() {
            if url.starts_with("file://") {
                // 如果是file://协议，提取本地路径
                let local_path = url.replace("file://", "").replace("file:///", "");
                println!("📁 使用本地视频文件: {}", local_path);
                video_paths.push(local_path);
            } else if url.starts_with("http://") || url.starts_with("https://") {
                // 如果是HTTP URL，尝试下载
                match self.download_single_video(url, video_paths.len()).await {
                    Ok(path) => {
                        println!("📥 视频下载成功: {}", path);
                        video_paths.push(path);
                    }
                    Err(e) => {
                        println!("⚠️ 视频下载失败: {} - {}", url, e);
                        // 下载失败时使用原URL作为路径
                        video_paths.push(url.clone());
                    }
                }
            } else {
                // 其他情况直接使用原路径
                println!("📄 使用原始路径: {}", url);
                video_paths.push(url.clone());
            }
        }

        Ok(video_paths)
    }

    /// 下载视频到本地（保留原方法以备后用）
    async fn download_videos(&self, video_urls: &[String]) -> Result<Vec<String>> {
        let mut video_paths = Vec::new();

        for (index, url) in video_urls.iter().enumerate() {
            match self.download_single_video(url, index).await {
                Ok(path) => {
                    println!("📥 视频下载成功: {}", path);
                    video_paths.push(path);
                }
                Err(e) => {
                    println!("⚠️ 视频下载失败: {} - {}", url, e);
                    // 下载失败时使用原URL作为路径
                    video_paths.push(url.clone());
                }
            }
        }

        Ok(video_paths)
    }

    /// 下载单个视频文件
    async fn download_single_video(&self, url: &str, index: usize) -> Result<String> {
        // 创建下载目录
        let download_dir = std::env::current_dir()?.join("downloads").join("videos");
        std::fs::create_dir_all(&download_dir)?;

        // 生成文件名
        let timestamp = chrono::Utc::now().format("%Y%m%d_%H%M%S").to_string();
        let filename = format!("video_{}_{}.mp4", timestamp, index);
        let file_path = download_dir.join(&filename);

        // 下载文件
        let response = self
            .client
            .get(url)
            .send()
            .await
            .map_err(|e| anyhow!("下载请求失败: {}", e))?;

        if !response.status().is_success() {
            return Err(anyhow!("下载失败: {}", response.status()));
        }

        let bytes = response
            .bytes()
            .await
            .map_err(|e| anyhow!("读取视频数据失败: {}", e))?;

        std::fs::write(&file_path, bytes)
            .map_err(|e| anyhow!("保存视频文件失败: {}", e))?;

        Ok(file_path.to_string_lossy().to_string())
    }

    /// 验证图片URL是否可访问
    pub async fn validate_image_url(&self, url: &str) -> Result<bool> {
        match self.client.head(url).send().await {
            Ok(response) => Ok(response.status().is_success()),
            Err(_) => Ok(false),
        }
    }

    /// 获取API配置
    pub fn get_config(&self) -> &DifyApiConfig {
        &self.config
    }

    /// 更新API配置
    pub fn update_config(&mut self, config: DifyApiConfig) {
        self.config = config;
    }

    /// 测试API连接
    pub async fn test_connection(&self) -> Result<bool> {
        let url = format!("{}/health", self.config.host);
        match self.client.get(&url).send().await {
            Ok(response) => Ok(response.status().is_success()),
            Err(_) => Ok(false),
        }
    }
}

impl Default for VideoGenerationService {
    fn default() -> Self {
        Self::new()
    }
}

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

    #[tokio::test]
    async fn test_video_generation_service_creation() {
        let service = VideoGenerationService::new();
        assert_eq!(service.config.host, "https://dify.bowongai.com");
        assert_eq!(service.config.api_key, "app-Lm10XUBJKnE1bnG6VPfiD1se");
    }

    #[tokio::test]
    async fn test_custom_config() {
        let custom_config = DifyApiConfig {
            host: "https://custom.api.com".to_string(),
            api_key: "custom-key".to_string(),
        };
        let service = VideoGenerationService::with_config(custom_config.clone());
        assert_eq!(service.config.host, custom_config.host);
        assert_eq!(service.config.api_key, custom_config.api_key);
    }

    #[tokio::test]
    async fn test_validate_image_url() {
        let service = VideoGenerationService::new();
        // 测试一个公开的图片URL
        let result = service.validate_image_url("https://httpbin.org/status/200").await;
        assert!(result.is_ok());
    }
}
