use anyhow::Result;
use reqwest;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use std::sync::Arc;
use tauri::{command, State};
use tracing::{error, info, warn};
use crate::data::models::voice_clone_record::{VoiceCloneRecord, CreateVoiceCloneRecordRequest};
use crate::data::models::speech_generation_record::{SpeechGenerationRecord, CreateSpeechGenerationRecordRequest};
use crate::infrastructure::database::Database;

/// API配置
struct ApiConfig {
    base_url: String,
    bearer_token: String,
}

impl Default for ApiConfig {
    fn default() -> Self {
        Self {
            base_url: "https://bowongai-test--text-video-agent-fastapi-app.modal.run".to_string(),
            bearer_token: "bowong7777".to_string(),
        }
    }
}

// ============= 请求/响应类型定义 =============

#[derive(Debug, Serialize, Deserialize)]
pub struct AudioUploadRequest {
    pub audio_file_path: String,
    pub purpose: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AudioUploadResponse {
    pub status: bool,
    pub msg: String,
    pub data: Option<serde_json::Value>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct VoiceCloneRequest {
    pub text: String,
    pub model: Option<String>,
    pub need_noise_reduction: Option<bool>,
    pub voice_id: Option<String>,
    pub prefix: Option<String>,
    pub audio_file_path: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct VoiceCloneResponse {
    pub status: bool,
    pub msg: String,
    pub data: Option<String>, // 直接是音频URL字符串
    pub extra: Option<VoiceCloneExtra>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct VoiceCloneExtra {
    pub file_id: Option<u64>,
    pub voice_id: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct VoiceCloneData {
    pub voice_id: String,
    pub audio_url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct VoiceInfo {
    pub voice_id: String,
    pub voice_name: Option<String>,
    pub description: Option<Vec<String>>,
    pub created_time: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct GetVoicesResponse {
    pub status: bool,
    pub msg: String,
    pub data: Option<Vec<VoiceInfo>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct SpeechGenerationRequest {
    pub text: String,
    pub voice_id: String,
    pub speed: Option<f64>,
    pub vol: Option<f64>,
    pub emotion: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct SpeechGenerationResponse {
    pub status: bool,
    pub msg: String,
    pub data: Option<String>, // 直接是音频URL字符串
}

#[derive(Debug, Serialize, Deserialize)]
pub struct SpeechGenerationData {
    pub audio_url: String,
    pub duration: Option<f64>,
}

// ============= Tauri命令实现 =============

/// 上传音频文件到302AI
#[command]
pub async fn upload_audio_file(request: AudioUploadRequest) -> Result<AudioUploadResponse, String> {
    info!("上传音频文件: {:?}", request);

    let config = ApiConfig::default();
    let client = reqwest::Client::builder()
        .timeout(Duration::from_secs(120))
        .build()
        .map_err(|e| format!("创建HTTP客户端失败: {}", e))?;

    let url = format!("{}/api/302/hl_router/sync/file/upload", config.base_url);

    // 检查文件是否存在
    if !std::path::Path::new(&request.audio_file_path).exists() {
        return Err(format!("音频文件不存在: {}", request.audio_file_path));
    }

    // 读取音频文件
    let file_content = tokio::fs::read(&request.audio_file_path).await
        .map_err(|e| format!("读取音频文件失败: {}", e))?;

    let filename = std::path::Path::new(&request.audio_file_path)
        .file_name()
        .and_then(|name| name.to_str())
        .unwrap_or("audio.wav");

    // 构建表单数据
    let mut form = reqwest::multipart::Form::new();
    
    let part = reqwest::multipart::Part::bytes(file_content)
        .file_name(filename.to_string());
    form = form.part("audio_file", part);

    // 添加purpose参数
    if let Some(purpose) = &request.purpose {
        form = form.text("purpose", purpose.clone());
    } else {
        form = form.text("purpose", "voice_clone".to_string());
    }

    info!("发送音频上传请求到: {}", url);

    let response = client
        .post(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .multipart(form)
        .send()
        .await
        .map_err(|e| format!("API请求失败: {}", e))?;

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

    info!("API响应状态: {}, 内容: {}", status_code, response_text);

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

    // 解析响应
    match serde_json::from_str::<AudioUploadResponse>(&response_text) {
        Ok(result) => {
            if result.status {
                info!("音频上传成功: {:?}", result);
            } else {
                warn!("音频上传失败: {:?}", result);
            }
            Ok(result)
        }
        Err(e) => {
            error!("解析JSON响应失败: {}", e);
            // 返回默认成功响应
            Ok(AudioUploadResponse {
                status: true,
                msg: "音频上传完成".to_string(),
                data: Some(serde_json::Value::String(response_text)),
            })
        }
    }
}

/// 执行声音克隆
#[command]
pub async fn clone_voice(
    request: VoiceCloneRequest,
    database: State<'_, Arc<Database>>,
) -> Result<VoiceCloneResponse, String> {
    info!("执行声音克隆: {:?}", request);

    let config = ApiConfig::default();
    let client = reqwest::Client::builder()
        .timeout(Duration::from_secs(300)) // 5分钟超时
        .build()
        .map_err(|e| format!("创建HTTP客户端失败: {}", e))?;

    let url = format!("{}/api/302/hl_router/sync/voice/clone", config.base_url);

    // 构建表单数据
    let mut form = reqwest::multipart::Form::new();
    
    // 添加文本参数
    form = form.text("text", request.text.clone());
    
    // 添加可选参数
    if let Some(model) = &request.model {
        form = form.text("model", model.clone());
    } else {
        form = form.text("model", "speech-02-hd".to_string());
    }
    
    if let Some(need_noise_reduction) = request.need_noise_reduction {
        form = form.text("need_noise_reduction", need_noise_reduction.to_string());
    } else {
        form = form.text("need_noise_reduction", "true".to_string());
    }
    
    if let Some(voice_id) = &request.voice_id {
        form = form.text("voice_id", voice_id.clone());
    }
    
    if let Some(prefix) = &request.prefix {
        form = form.text("prefix", prefix.clone());
    } else {
        form = form.text("prefix", "BoWong-".to_string());
    }

    // 如果有音频文件，添加到表单中
    if let Some(audio_file_path) = &request.audio_file_path {
        if std::path::Path::new(audio_file_path).exists() {
            match tokio::fs::read(audio_file_path).await {
                Ok(file_content) => {
                    let filename = std::path::Path::new(audio_file_path)
                        .file_name()
                        .and_then(|name| name.to_str())
                        .unwrap_or("reference.wav");

                    let part = reqwest::multipart::Part::bytes(file_content)
                        .file_name(filename.to_string());

                    form = form.part("audio_file", part);
                    info!("已添加参考音频: {}", filename);
                }
                Err(e) => {
                    error!("读取参考音频失败: {}", e);
                    return Err(format!("读取参考音频失败: {}", e));
                }
            }
        } else {
            warn!("参考音频文件不存在，跳过: {}", audio_file_path);
        }
    }

    info!("发送声音克隆请求到: {}", url);

    let response = client
        .post(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .multipart(form)
        .send()
        .await
        .map_err(|e| format!("API请求失败: {}", e))?;

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

    info!("API响应状态: {}, 内容: {}", status_code, response_text);

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

    // 解析响应
    match serde_json::from_str::<VoiceCloneResponse>(&response_text) {
        Ok(result) => {
            if result.status {
                info!("声音克隆成功: {:?}", result);

                // 保存到本地数据库
                if let (Some(audio_url), Some(extra)) = (&result.data, &result.extra) {
                    if let Some(voice_id) = &extra.voice_id {
                        let create_request = CreateVoiceCloneRecordRequest {
                            voice_id: voice_id.clone(),
                            voice_name: None, // 可以后续添加自定义名称功能
                            clone_text: request.text.clone(),
                            audio_url: audio_url.clone(),
                            file_id: extra.file_id,
                            model: request.model.clone(),
                            need_noise_reduction: request.need_noise_reduction.unwrap_or(true),
                            prefix: request.prefix.clone(),
                            audio_file_path: request.audio_file_path.clone(),
                        };

                        // 使用 database.with_connection 来避免生命周期问题
                        match database.inner().with_connection(|conn| {
                            VoiceCloneRecord::create(conn, create_request)
                        }) {
                            Ok(_) => {
                                info!("声音克隆记录已保存到数据库: {}", voice_id);
                            }
                            Err(e) => {
                                error!("保存声音克隆记录到数据库失败: {}", e);
                            }
                        }
                    }
                }
            } else {
                warn!("声音克隆失败: {:?}", result);
            }
            Ok(result)
        }
        Err(e) => {
            error!("解析JSON响应失败: {}", e);
            // 返回默认成功响应
            Ok(VoiceCloneResponse {
                status: true,
                msg: "声音克隆完成".to_string(),
                data: Some(response_text),
                extra: Some(VoiceCloneExtra {
                    file_id: None,
                    voice_id: Some("generated_voice_id".to_string()),
                }),
            })
        }
    }
}

/// 获取可用音色列表（从本地数据库）
#[command]
pub async fn get_voices(database: State<'_, Arc<Database>>) -> Result<GetVoicesResponse, String> {
    info!("从本地数据库获取音色列表");

    // 使用 database.with_connection 来避免生命周期问题
    match database.inner().with_connection(|conn| {
        VoiceCloneRecord::get_all_active(conn)
    }) {
        Ok(records) => {
            let voices: Vec<VoiceInfo> = records
                .into_iter()
                .map(|record| VoiceInfo {
                    voice_id: record.voice_id,
                    voice_name: record.voice_name,
                    description: None, // 可以后续添加描述功能
                    created_time: Some(record.created_at),
                })
                .collect();

            info!("从数据库获取音色列表成功，共{}个音色", voices.len());
            Ok(GetVoicesResponse {
                status: true,
                msg: format!("成功获取{}个音色", voices.len()),
                data: Some(voices),
            })
        }
        Err(e) => {
            error!("从数据库获取音色列表失败: {}", e);
            Ok(GetVoicesResponse {
                status: false,
                msg: format!("获取音色列表失败: {}", e),
                data: Some(vec![]),
            })
        }
    }
}

/// 生成语音
#[command]
pub async fn generate_speech(
    request: SpeechGenerationRequest,
    database: State<'_, Arc<Database>>,
) -> Result<SpeechGenerationResponse, String> {
    info!("生成语音: {:?}", request);

    // 创建语音生成记录
    let create_request = CreateSpeechGenerationRecordRequest {
        text: request.text.clone(),
        voice_id: request.voice_id.clone(),
        voice_name: None, // 可以后续从音色列表中获取
        speed: request.speed.unwrap_or(1.0) as f32,
        volume: request.vol.unwrap_or(1.0) as f32,
        emotion: request.emotion.clone(),
        audio_url: None,
        local_file_path: None,
    };

    let mut record = SpeechGenerationRecord::new(create_request);
    record.start_generation();

    // 保存初始记录到数据库
    let record_id = record.id.clone();
    match database.inner().with_connection(|conn| {
        record.save(conn)
    }) {
        Ok(_) => {
            info!("语音生成记录已保存到数据库: {}", record_id);
        }
        Err(e) => {
            error!("保存语音生成记录到数据库失败: {}", e);
        }
    }

    let config = ApiConfig::default();
    let client = reqwest::Client::builder()
        .timeout(Duration::from_secs(120))
        .build()
        .map_err(|e| format!("创建HTTP客户端失败: {}", e))?;

    let url = format!("{}/api/302/hl_router/sync/generate/speech", config.base_url);

    // 构建表单数据
    let mut form = reqwest::multipart::Form::new();

    // 添加必需参数
    form = form.text("text", request.text.clone());
    form = form.text("voice_id", request.voice_id.clone());

    // 添加可选参数
    if let Some(speed) = request.speed {
        form = form.text("speed", speed.to_string());
    } else {
        form = form.text("speed", "1.0".to_string());
    }

    if let Some(vol) = request.vol {
        form = form.text("vol", vol.to_string());
    } else {
        form = form.text("vol", "1.0".to_string());
    }

    if let Some(emotion) = &request.emotion {
        form = form.text("emotion", emotion.clone());
    }

    info!("发送语音生成请求到: {}", url);

    let response = client
        .post(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .multipart(form)
        .send()
        .await
        .map_err(|e| format!("API请求失败: {}", e))?;

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

    info!("API响应状态: {}, 内容: {}", status_code, response_text);

    if !status_code.is_success() {
        // 更新记录为失败状态
        record.mark_failed(format!("API请求失败: {} - {}", status_code, response_text));
        let _ = database.inner().with_connection(|conn| {
            record.save(conn)
        });
        return Err(format!("API请求失败: {} - {}", status_code, response_text));
    }

    // 解析响应
    match serde_json::from_str::<SpeechGenerationResponse>(&response_text) {
        Ok(result) => {
            if result.status {
                info!("语音生成成功: {:?}", result);

                // 确保音频URL存在并正确保存
                let audio_url = result.data.clone();
                info!("保存音频URL到记录: {:?}", audio_url);

                if audio_url.is_none() || audio_url.as_ref().unwrap().is_empty() {
                    // 如果API没有返回URL，使用原始响应作为URL（可能是直接返回了音频数据）
                    info!("API未返回音频URL，使用原始响应作为URL");
                    record.complete_generation(Some(response_text.clone()), None);
                } else {
                    // 正常保存API返回的URL
                    record.complete_generation(audio_url, None);
                }
            } else {
                warn!("语音生成失败: {:?}", result);
                // 更新记录为失败状态
                record.mark_failed(result.msg.clone());
            }

            // 保存更新后的记录
            match database.inner().with_connection(|conn| {
                record.save(conn)
            }) {
                Ok(_) => info!("成功保存语音生成记录到数据库"),
                Err(e) => error!("保存语音生成记录到数据库失败: {}", e)
            }

            Ok(result)
        }
        Err(e) => {
            error!("解析JSON响应失败: {}", e);
            // 更新记录为成功状态（因为API返回了数据，只是格式不是JSON）
            info!("使用原始响应作为音频URL");
            record.complete_generation(Some(response_text.clone()), None);

            match database.inner().with_connection(|conn| {
                record.save(conn)
            }) {
                Ok(_) => info!("成功保存语音生成记录到数据库"),
                Err(e) => error!("保存语音生成记录到数据库失败: {}", e)
            }

            // 返回默认成功响应
            Ok(SpeechGenerationResponse {
                status: true,
                msg: "语音生成完成".to_string(),
                data: Some(response_text),
            })
        }
    }
}

/// 下载音频文件到本地
#[command]
pub async fn download_audio(audio_url: String, save_path: String) -> Result<String, String> {
    info!("下载音频文件: {} -> {}", audio_url, save_path);

    let client = reqwest::Client::builder()
        .timeout(Duration::from_secs(60))
        .build()
        .map_err(|e| format!("创建HTTP客户端失败: {}", e))?;

    let response = client
        .get(&audio_url)
        .send()
        .await
        .map_err(|e| format!("下载请求失败: {}", e))?;

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

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

    // 确保目录存在
    if let Some(parent) = std::path::Path::new(&save_path).parent() {
        tokio::fs::create_dir_all(parent).await
            .map_err(|e| format!("创建目录失败: {}", e))?;
    }

    tokio::fs::write(&save_path, bytes).await
        .map_err(|e| format!("保存文件失败: {}", e))?;

    info!("音频文件下载完成: {}", save_path);
    Ok(save_path)
}

/// 下载单个音频文件到指定目录
#[command]
pub async fn download_audio_to_directory(
    record_id: String,
    audio_url: String,
    directory_path: String,
    filename: Option<String>
) -> Result<String, String> {
    info!("下载音频文件到目录: {} -> {}", audio_url, directory_path);

    // 生成文件名
    let file_name = filename.unwrap_or_else(|| {
        format!("speech_{}.wav", record_id)
    });

    let save_path = std::path::Path::new(&directory_path).join(&file_name);
    let save_path_str = save_path.to_string_lossy().to_string();

    // 使用现有的下载函数
    download_audio(audio_url, save_path_str.clone()).await?;

    Ok(save_path_str)
}

/// 批量下载音频文件到指定目录
#[command]
pub async fn batch_download_audio_to_directory(
    records: Vec<serde_json::Value>,
    directory_path: String
) -> Result<Vec<String>, String> {
    info!("批量下载 {} 个音频文件到目录: {}", records.len(), directory_path);

    let mut downloaded_files = Vec::new();
    let mut failed_downloads = Vec::new();

    for (index, record) in records.iter().enumerate() {
        let default_id = format!("unknown_{}", index);
        let record_id = record.get("id")
            .and_then(|v| v.as_str())
            .unwrap_or(&default_id);

        let audio_url = record.get("audio_url")
            .and_then(|v| v.as_str())
            .or_else(|| record.get("local_file_path").and_then(|v| v.as_str()));

        if let Some(url) = audio_url {
            // 生成安全的文件名
            let text = record.get("text")
                .and_then(|v| v.as_str())
                .unwrap_or("speech");

            // 清理文件名，移除非法字符
            let safe_text = text.chars()
                .take(30) // 限制长度
                .filter(|c| c.is_alphanumeric() || *c == ' ' || *c == '-' || *c == '_')
                .collect::<String>()
                .trim()
                .replace(' ', "_");

            let filename = if safe_text.is_empty() {
                format!("speech_{}.wav", record_id)
            } else {
                format!("{}_{}.wav", safe_text, record_id)
            };

            match download_audio_to_directory(
                record_id.to_string(),
                url.to_string(),
                directory_path.clone(),
                Some(filename)
            ).await {
                Ok(file_path) => {
                    info!("成功下载: {}", file_path);
                    downloaded_files.push(file_path);
                }
                Err(e) => {
                    error!("下载失败 {}: {}", record_id, e);
                    failed_downloads.push(format!("{}: {}", record_id, e));
                }
            }
        } else {
            warn!("记录 {} 没有可用的音频URL", record_id);
            failed_downloads.push(format!("{}: 没有可用的音频URL", record_id));
        }
    }

    if !failed_downloads.is_empty() {
        warn!("部分下载失败: {:?}", failed_downloads);
    }

    info!("批量下载完成: 成功 {}, 失败 {}", downloaded_files.len(), failed_downloads.len());
    Ok(downloaded_files)
}

/// 获取语音生成记录列表
#[command]
pub async fn get_speech_generation_records(
    database: State<'_, Arc<Database>>,
    limit: Option<i32>,
) -> Result<Vec<SpeechGenerationRecord>, String> {

    match database.inner().with_connection(|conn| {
        SpeechGenerationRecord::get_all(conn, limit)
    }) {
        Ok(records) => {
            Ok(records)
        }
        Err(e) => {
            error!("获取语音生成记录失败: {}", e);
            Err(format!("获取语音生成记录失败: {}", e))
        }
    }
}

/// 根据音色ID获取语音生成记录
#[command]
pub async fn get_speech_generation_records_by_voice_id(
    database: State<'_, Arc<Database>>,
    voice_id: String,
    limit: Option<i32>,
) -> Result<Vec<SpeechGenerationRecord>, String> {
    info!("根据音色ID获取语音生成记录: {}, limit: {:?}", voice_id, limit);

    match database.inner().with_connection(|conn| {
        SpeechGenerationRecord::get_by_voice_id(conn, &voice_id, limit)
    }) {
        Ok(records) => {
            Ok(records)
        }
        Err(e) => {
            error!("获取音色语音生成记录失败: {}", e);
            Err(format!("获取音色语音生成记录失败: {}", e))
        }
    }
}

/// 删除语音生成记录
#[command]
pub async fn delete_speech_generation_record(
    database: State<'_, Arc<Database>>,
    record_id: String,
) -> Result<(), String> {
    info!("删除语音生成记录: {}", record_id);

    match database.inner().with_connection(|conn| {
        if let Some(record) = SpeechGenerationRecord::get_by_id(conn, &record_id)? {
            record.delete(conn)
        } else {
            Err(rusqlite::Error::QueryReturnedNoRows)
        }
    }) {
        Ok(_) => {
            info!("成功删除语音生成记录: {}", record_id);
            Ok(())
        }
        Err(e) => {
            error!("删除语音生成记录失败: {}", e);
            Err(format!("删除语音生成记录失败: {}", e))
        }
    }
}
