use tauri::State;
use tracing::{error, info};

use crate::app_state::AppState;
use crate::business::services::volcano_video_service::VolcanoVideoService;
use crate::data::models::video_generation_record::{
    VideoGenerationRecord, CreateVideoGenerationRequest, VideoGenerationQuery
};

/// 创建视频生成任务
/// 遵循 Tauri 开发规范的命令设计模式
#[tauri::command]
pub async fn create_volcano_video_generation(
    state: State<'_, AppState>,
    request: CreateVideoGenerationRequest,
) -> Result<VideoGenerationRecord, String> {
    info!("创建火山云视频生成任务: {}", request.name);

    // 获取数据库连接
    let database = {
        let database_guard = state
            .database
            .lock()
            .map_err(|e| format!("获取数据库失败: {}", e))?;
        database_guard
            .as_ref()
            .ok_or("数据库未初始化")?
            .clone()
    };

    // 创建服务实例
    let service = VolcanoVideoService::new(database);

    // 创建视频生成任务
    match service.create_video_generation(request).await {
        Ok(record) => {
            info!("视频生成任务创建成功: {}", record.id);
            Ok(record)
        }
        Err(e) => {
            error!("创建视频生成任务失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 获取视频生成记录列表
#[tauri::command]
pub async fn get_volcano_video_generations(
    state: State<'_, AppState>,
    query: Option<VideoGenerationQuery>,
) -> Result<Vec<VideoGenerationRecord>, String> {

    // 获取数据库连接
    let database = {
        let database_guard = state
            .database
            .lock()
            .map_err(|e| format!("获取数据库失败: {}", e))?;
        database_guard
            .as_ref()
            .ok_or("数据库未初始化")?
            .clone()
    };

    // 创建服务实例
    let service = VolcanoVideoService::new(database);

    // 使用默认查询参数或提供的参数
    let query = query.unwrap_or_default();

    // 获取记录列表
    match service.get_video_generations(query).await {
        Ok(records) => {
            Ok(records)
        }
        Err(e) => {
            error!("获取视频生成记录列表失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 根据ID获取视频生成记录
#[tauri::command]
pub async fn get_volcano_video_generation_by_id(
    state: State<'_, AppState>,
    id: String,
) -> Result<Option<VideoGenerationRecord>, String> {
    info!("获取视频生成记录: {}", id);

    // 获取数据库连接
    let database = {
        let database_guard = state
            .database
            .lock()
            .map_err(|e| format!("获取数据库失败: {}", e))?;
        database_guard
            .as_ref()
            .ok_or("数据库未初始化")?
            .clone()
    };

    // 创建服务实例
    let service = VolcanoVideoService::new(database);

    // 获取记录
    match service.get_video_generation_by_id(&id).await {
        Ok(record) => {
            if record.is_some() {
                info!("找到视频生成记录: {}", id);
            } else {
                info!("未找到视频生成记录: {}", id);
            }
            Ok(record)
        }
        Err(e) => {
            error!("获取视频生成记录失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 删除视频生成记录
#[tauri::command]
pub async fn delete_volcano_video_generation(
    state: State<'_, AppState>,
    id: String,
) -> Result<(), String> {
    info!("删除视频生成记录: {}", id);

    // 获取数据库连接
    let database = {
        let database_guard = state
            .database
            .lock()
            .map_err(|e| format!("获取数据库失败: {}", e))?;
        database_guard
            .as_ref()
            .ok_or("数据库未初始化")?
            .clone()
    };

    // 创建服务实例
    let service = VolcanoVideoService::new(database);

    // 删除记录
    match service.delete_video_generation(&id).await {
        Ok(()) => {
            info!("视频生成记录删除成功: {}", id);
            Ok(())
        }
        Err(e) => {
            error!("删除视频生成记录失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 批量删除视频生成记录
#[tauri::command]
pub async fn batch_delete_volcano_video_generations(
    state: State<'_, AppState>,
    ids: Vec<String>,
) -> Result<(), String> {
    info!("批量删除视频生成记录: {:?}", ids);

    // 获取数据库连接
    let database = {
        let database_guard = state
            .database
            .lock()
            .map_err(|e| format!("获取数据库失败: {}", e))?;
        database_guard
            .as_ref()
            .ok_or("数据库未初始化")?
            .clone()
    };

    // 创建服务实例
    let service = VolcanoVideoService::new(database);

    // 批量删除记录
    match service.batch_delete_video_generations(ids.clone()).await {
        Ok(()) => {
            info!("批量删除视频生成记录成功: {} 条", ids.len());
            Ok(())
        }
        Err(e) => {
            error!("批量删除视频生成记录失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 下载视频文件
#[tauri::command]
pub async fn download_volcano_video(
    _state: State<'_, AppState>,
    video_url: String,
    save_path: String,
) -> Result<(), String> {
    info!("下载视频文件: {} -> {}", video_url, save_path);

    // 使用reqwest下载文件
    let client = reqwest::Client::new();
    
    match client.get(&video_url).send().await {
        Ok(response) => {
            if response.status().is_success() {
                match response.bytes().await {
                    Ok(bytes) => {
                        match tokio::fs::write(&save_path, bytes).await {
                            Ok(()) => {
                                info!("视频文件下载成功: {}", save_path);
                                Ok(())
                            }
                            Err(e) => {
                                error!("保存视频文件失败: {}", e);
                                Err(format!("保存视频文件失败: {}", e))
                            }
                        }
                    }
                    Err(e) => {
                        error!("读取视频数据失败: {}", e);
                        Err(format!("读取视频数据失败: {}", e))
                    }
                }
            } else {
                let error_msg = format!("下载失败，HTTP状态码: {}", response.status());
                error!("{}", error_msg);
                Err(error_msg)
            }
        }
        Err(e) => {
            error!("下载视频文件失败: {}", e);
            Err(format!("下载视频文件失败: {}", e))
        }
    }
}

/// 下载视频到指定目录（带文件选择对话框）
#[tauri::command]
pub async fn download_video_to_directory(
    app: tauri::AppHandle,
    video_url: String,
    filename: String,
) -> Result<String, String> {
    use tauri_plugin_dialog::DialogExt;

    info!("下载视频到指定目录: {} -> {}", video_url, filename);

    // 获取文件扩展名
    let extension = if filename.ends_with(".mp4") {
        "mp4"
    } else {
        "mp4" // 默认使用mp4
    };

    // 显示保存对话框
    let (tx, rx) = std::sync::mpsc::channel();

    app.dialog().file()
        .set_title("保存视频文件")
        .set_file_name(&filename)
        .add_filter("视频文件", &[extension])
        .add_filter("所有文件", &["*"])
        .save_file(move |file_path| {
            let _ = tx.send(file_path);
        });

    // 等待用户选择
    let file_path = match rx.recv_timeout(std::time::Duration::from_secs(30)) {
        Ok(Some(path)) => path.to_string(),
        Ok(None) => return Err("用户取消了保存操作".to_string()),
        Err(_) => return Err("文件选择对话框超时".to_string()),
    };

    // 创建带有防盗链绕过的HTTP客户端
    let client = reqwest::Client::builder()
        .user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
        .build()
        .map_err(|e| format!("创建HTTP客户端失败: {}", e))?;

    // 构建请求，添加必要的头部信息绕过防盗链
    let request = client
        .get(&video_url)
        .header("Referer", "https://www.volcengine.com/")
        .header("Origin", "https://www.volcengine.com")
        .header("Accept", "video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5")
        .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
        .header("Cache-Control", "no-cache")
        .header("Pragma", "no-cache")
        .header("Sec-Fetch-Dest", "video")
        .header("Sec-Fetch-Mode", "no-cors")
        .header("Sec-Fetch-Site", "cross-site");

    match request.send().await {
        Ok(response) => {
            if response.status().is_success() {
                match response.bytes().await {
                    Ok(bytes) => {
                        // 确保目录存在
                        if let Some(parent) = std::path::Path::new(&file_path).parent() {
                            if let Err(e) = tokio::fs::create_dir_all(parent).await {
                                return Err(format!("创建目录失败: {}", e));
                            }
                        }

                        match tokio::fs::write(&file_path, bytes).await {
                            Ok(()) => {
                                info!("视频文件下载成功: {}", file_path);
                                Ok(file_path)
                            }
                            Err(e) => {
                                error!("保存视频文件失败: {}", e);
                                Err(format!("保存视频文件失败: {}", e))
                            }
                        }
                    }
                    Err(e) => {
                        error!("读取视频数据失败: {}", e);
                        Err(format!("读取视频数据失败: {}", e))
                    }
                }
            } else {
                let error_msg = format!("下载失败，HTTP状态码: {}", response.status());
                error!("{}", error_msg);
                Err(error_msg)
            }
        }
        Err(e) => {
            error!("下载视频文件失败: {}", e);
            Err(format!("下载视频文件失败: {}", e))
        }
    }
}

/// 批量下载视频文件
#[tauri::command]
pub async fn batch_download_volcano_videos(
    _state: State<'_, AppState>,
    downloads: Vec<(String, String)>, // (video_url, save_path) 对
) -> Result<Vec<String>, String> {
    info!("批量下载视频文件: {} 个", downloads.len());

    let mut results = Vec::new();
    let client = reqwest::Client::new();

    for (video_url, save_path) in downloads {
        match client.get(&video_url).send().await {
            Ok(response) => {
                if response.status().is_success() {
                    match response.bytes().await {
                        Ok(bytes) => {
                            match tokio::fs::write(&save_path, bytes).await {
                                Ok(()) => {
                                    info!("视频文件下载成功: {}", save_path);
                                    results.push(format!("成功: {}", save_path));
                                }
                                Err(e) => {
                                    let error_msg = format!("保存失败 {}: {}", save_path, e);
                                    error!("{}", error_msg);
                                    results.push(error_msg);
                                }
                            }
                        }
                        Err(e) => {
                            let error_msg = format!("读取数据失败 {}: {}", video_url, e);
                            error!("{}", error_msg);
                            results.push(error_msg);
                        }
                    }
                } else {
                    let error_msg = format!("下载失败 {} (HTTP {})", video_url, response.status());
                    error!("{}", error_msg);
                    results.push(error_msg);
                }
            }
            Err(e) => {
                let error_msg = format!("请求失败 {}: {}", video_url, e);
                error!("{}", error_msg);
                results.push(error_msg);
            }
        }
    }

    Ok(results)
}

/// 获取视频流的Base64数据，绕过防盗链限制
#[tauri::command]
pub async fn get_video_stream_base64(
    video_url: String,
) -> Result<String, String> {
    info!("获取视频流Base64数据: {}", video_url);

    // 创建带有防盗链绕过的HTTP客户端
    let client = reqwest::Client::builder()
        .user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
        .timeout(std::time::Duration::from_secs(60))
        .build()
        .map_err(|e| format!("创建HTTP客户端失败: {}", e))?;

    // 构建请求，添加必要的头部信息
    let request = client
        .get(&video_url)
        .header("Referer", "https://www.volcengine.com/")
        .header("Origin", "https://www.volcengine.com")
        .header("Accept", "video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5")
        .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
        .header("Cache-Control", "no-cache")
        .header("Pragma", "no-cache")
        .header("Sec-Fetch-Dest", "video")
        .header("Sec-Fetch-Mode", "no-cors")
        .header("Sec-Fetch-Site", "cross-site");

    match request.send().await {
        Ok(response) => {
            if response.status().is_success() {
                match response.bytes().await {
                    Ok(bytes) => {
                        use base64::{Engine as _, engine::general_purpose};
                        let base64_data = general_purpose::STANDARD.encode(&bytes);
                        let data_url = format!("data:video/mp4;base64,{}", base64_data);
                        info!("成功获取视频流Base64数据，大小: {} bytes", bytes.len());
                        Ok(data_url)
                    }
                    Err(e) => {
                        error!("读取视频流数据失败: {}", e);
                        Err(format!("读取视频流数据失败: {}", e))
                    }
                }
            } else {
                let error_msg = format!("获取视频流失败，HTTP状态码: {}", response.status());
                error!("{}", error_msg);
                Err(error_msg)
            }
        }
        Err(e) => {
            error!("获取视频流请求失败: {}", e);
            Err(format!("获取视频流请求失败: {}", e))
        }
    }
}
