use anyhow::Result;
use reqwest;
use serde::{Deserialize, Serialize};
use serde_json;
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use tauri::{command, State, AppHandle, Emitter};
use tracing::{error, info};

use crate::business::services::image_generation_service::ImageGenerationService as DbImageGenerationService;
use crate::data::models::image_generation_record::ImageGenerationRecord;
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 PromptCheckResponse {
    pub is_valid: bool,
    pub message: String,
    pub suggestions: Option<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ImageGenerationRequest {
    pub prompt: String,
    pub reference_image_path: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ImageGenerationResponse {
    pub task_id: String,
    pub status: String,
    pub message: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TaskStatus {
    #[serde(rename = "pending")]
    PENDING,
    #[serde(rename = "processing")]
    PROCESSING,
    #[serde(rename = "completed")]
    COMPLETED,
    #[serde(rename = "failed")]
    FAILED,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TaskStatusResponse {
    #[serde(default)]
    pub task_id: String,
    #[serde(default)]
    pub status: String,
    #[serde(default)]
    pub progress: f32,
    #[serde(default)]
    pub result_url: Option<String>,
    #[serde(default)]
    pub result_urls: Vec<String>,
    #[serde(default)]
    pub error_message: Option<String>,
    #[serde(default)]
    pub created_at: String,
    #[serde(default)]
    pub updated_at: String,
}

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

#[command]
pub async fn check_image_prompt(prompt: String) -> Result<PromptCheckResponse, String> {
    info!("检查提示词: {}", prompt);

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

    let url = format!("{}/api/mj/prompt/check", config.base_url);
    let mut params = HashMap::new();
    params.insert("prompt", prompt.as_str());

    info!("发送提示词检查请求到: {}", url);

    let response = client
        .get(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .query(&params)
        .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() {
        // 如果API失败，返回默认的通过状态
        return Ok(PromptCheckResponse {
            is_valid: true,
            message: "提示词检查完成（API暂不可用）".to_string(),
            suggestions: None,
        });
    }

    // 解析JSON响应
    match serde_json::from_str::<serde_json::Value>(&response_text) {
        Ok(json_value) => {
            info!("解析的JSON结构: {:#}", json_value);

            let is_valid = json_value.get("is_valid")
                .and_then(|v| v.as_bool())
                .unwrap_or(true); // 默认认为有效

            let message = json_value.get("message")
                .or_else(|| json_value.get("msg"))
                .and_then(|v| v.as_str())
                .unwrap_or(if is_valid { "提示词检查通过" } else { "提示词需要优化" })
                .to_string();

            let suggestions = json_value.get("suggestions")
                .and_then(|v| v.as_array())
                .map(|arr| {
                    arr.iter()
                        .filter_map(|item| item.as_str().map(|s| s.to_string()))
                        .collect()
                });

            let result = PromptCheckResponse {
                is_valid,
                message,
                suggestions,
            };

            info!("解析后的检查结果: {:?}", result);
            Ok(result)
        }
        Err(e) => {
            error!("解析JSON响应失败: {}", e);
            // 如果解析失败，返回默认的通过状态
            Ok(PromptCheckResponse {
                is_valid: true,
                message: "提示词检查完成".to_string(),
                suggestions: None,
            })
        }
    }
}

#[command]
pub async fn submit_image_generation_task(request: ImageGenerationRequest) -> Result<ImageGenerationResponse, String> {
    info!("提交图片生成任务: {:?}", request);

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

    let url = format!("{}/api/302/mj/async/generate/image", config.base_url);

    // 构建表单数据（prompt作为query参数，不在表单中）
    let mut form = reqwest::multipart::Form::new();

    // 如果有参考图片，添加到表单中
    if let Some(ref image_path) = request.reference_image_path {
        if std::path::Path::new(image_path).exists() {
            match tokio::fs::read(image_path).await {
                Ok(file_content) => {
                    let filename = std::path::Path::new(image_path)
                        .file_name()
                        .and_then(|name| name.to_str())
                        .unwrap_or("reference.jpg");

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

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

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

    let response = client
        .post(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .query(&[("prompt", &request.prompt)])
        .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));
    }

    // 解析JSON响应
    match serde_json::from_str::<serde_json::Value>(&response_text) {
        Ok(json_value) => {
            info!("解析的JSON结构: {:#}", json_value);

            let task_id = if let Some(data_obj) = json_value.get("data").and_then(|v| v.as_object()) {
                // data是对象，尝试从data.id获取
                data_obj.get("id")
                    .and_then(|v| v.as_str())
                    .unwrap_or("")
                    .to_string()
            } else if let Some(data_str) = json_value.get("data").and_then(|v| v.as_str()) {
                // data是字符串，直接使用
                data_str.to_string()
            } else {
                // 尝试从根级别的task_id获取
                json_value.get("task_id")
                    .and_then(|v| v.as_str())
                    .unwrap_or("")
                    .to_string()
            };

            let status = json_value.get("status")
                .and_then(|v| v.as_str())
                .unwrap_or("success")
                .to_string();

            let message = json_value.get("message")
                .or_else(|| json_value.get("msg"))
                .and_then(|v| v.as_str())
                .unwrap_or("任务提交成功")
                .to_string();

            let result = ImageGenerationResponse {
                task_id,
                status,
                message,
            };

            info!("解析后的提交结果: {:?}", result);
            Ok(result)
        }
        Err(e) => {
            error!("解析JSON响应失败: {}", e);
            Err(format!("API响应格式错误: {}", response_text))
        }
    }
}

#[command]
pub async fn query_image_generation_status(task_id: String) -> Result<TaskStatusResponse, String> {
    info!("查询图片生成状态: {}", task_id);

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

    let url = format!("{}/api/302/mj/async/query/status", config.base_url);
    let mut params = HashMap::new();
    params.insert("task_id", task_id.as_str());

    info!("发送状态查询请求到: {}", url);

    let response = client
        .get(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .query(&params)
        .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));
    }

    // 解析JSON响应
    match serde_json::from_str::<serde_json::Value>(&response_text) {
        Ok(json_value) => {
            info!("解析的JSON结构: {:#}", json_value);

            // 根据实际API响应格式解析
            let task_id_result = if let Some(data_str) = json_value.get("data").and_then(|v| v.as_str()) {
                // data是字符串，表示task_id
                data_str.to_string()
            } else {
                // data可能是数组或其他格式
                json_value.get("task_id")
                    .and_then(|v| v.as_str())
                    .unwrap_or(&task_id)
                    .to_string()
            };

            // 获取消息内容
            let msg = json_value.get("msg")
                .and_then(|v| v.as_str())
                .unwrap_or("");

            // 根据status和msg确定任务状态
            let status_str = if let Some(status_bool) = json_value.get("status").and_then(|v| v.as_bool()) {
                if status_bool {
                    "completed"
                } else {
                    // 根据msg内容判断具体状态
                    if msg.contains("ON_QUEUE") {
                        "pending"
                    } else if msg.contains("PROCESSING") || msg.contains("progress") {
                        "processing"
                    } else if msg.contains("FAILED") || msg.contains("ERROR") {
                        "failed"
                    } else {
                        "processing"
                    }
                }
            } else {
                "processing"
            }.to_string();

            // 解析进度
            let progress = if status_str == "completed" {
                1.0
            } else if !msg.is_empty() {
                // 解析 "ON_QUEUE--> progress: 23%" 格式
                if let Some(progress_part) = msg.split("progress: ").nth(1) {
                    if let Some(percent_str) = progress_part.split('%').next() {
                        percent_str.parse::<f32>().ok().map(|p| p / 100.0).unwrap_or(0.0)
                    } else {
                        0.0
                    }
                } else {
                    0.0
                }
            } else {
                0.0
            };

            // 处理结果URL
            let (result_url, result_urls) = if let Some(data_array) = json_value.get("data").and_then(|v| v.as_array()) {
                // data是数组，表示图片URL列表
                let urls: Vec<String> = data_array.iter()
                    .filter_map(|v| v.as_str().map(|s| s.to_string()))
                    .collect();
                let first_url = urls.first().cloned();
                (first_url, urls)
            } else {
                (None, vec![])
            };

            let error_message = if status_str == "failed" {
                Some(msg.to_string())
            } else {
                None
            };

            let result = TaskStatusResponse {
                task_id: task_id_result,
                status: status_str,
                progress,
                result_url,
                result_urls,
                error_message,
                created_at: "".to_string(),
                updated_at: "".to_string(),
            };

            info!("解析后的状态结果: {:?}", result);
            Ok(result)
        }
        Err(e) => {
            error!("解析JSON响应失败: {}", e);
            // 返回失败状态
            Ok(TaskStatusResponse {
                task_id,
                status: "failed".to_string(),
                progress: 0.0,
                result_url: None,
                result_urls: vec![],
                error_message: Some(format!("API响应格式错误: {}", response_text)),
                created_at: "".to_string(),
                updated_at: "".to_string(),
            })
        }
    }
}

#[command]
pub async fn upload_file_to_cloud(file_path: String) -> Result<FileUploadResponse, String> {
    use std::path::Path;
    use crate::business::services::cloud_upload_service::CloudUploadService;

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

    // 使用真正的云端上传服务
    let cloud_service = CloudUploadService::new();

    // 生成远程文件名
    let file_name = Path::new(&file_path)
        .file_name()
        .and_then(|n| n.to_str())
        .unwrap_or("file");

    let remote_key = format!("auto-form-uploads/{}", file_name);

    match cloud_service.upload_file(&file_path, Some(remote_key), None).await {
        Ok(upload_result) => {
            if upload_result.success {
                // 获取云端URL并转换为CDN格式
                let url = if let Some(remote_url) = upload_result.remote_url {
                    convert_s3_to_cdn_url(&remote_url)
                } else if let Some(urn) = upload_result.urn {
                    convert_s3_to_cdn_url(&urn)
                } else {
                    format!("https://example.com/uploaded/{}", file_name)
                };

                Ok(FileUploadResponse {
                    status: true,
                    msg: "上传成功".to_string(),
                    data: Some(url),
                })
            } else {
                let error_msg = upload_result.error_message
                    .unwrap_or_else(|| "上传失败".to_string());
                Err(error_msg)
            }
        }
        Err(e) => {
            Err(format!("上传失败: {}", e))
        }
    }
}

#[command]
pub async fn create_image_generation_record(
    database: State<'_, Arc<Database>>,
    prompt: String,
    reference_image_path: Option<String>
) -> Result<ImageGenerationRecord, String> {
    info!("创建图片生成记录: {}", prompt);
    
    let service = DbImageGenerationService::new(database.inner().clone());
    
    match service.create_record(prompt, reference_image_path) {
        Ok(record) => {
            info!("图片生成记录创建成功: {}", record.id);
            Ok(record)
        }
        Err(e) => {
            error!("创建图片生成记录失败: {}", e);
            Err(format!("创建图片生成记录失败: {}", e))
        }
    }
}

#[command]
pub async fn start_image_generation_task(
    database: State<'_, Arc<Database>>,
    record_id: String,
    task_id: String
) -> Result<(), String> {
    info!("开始图片生成任务: {} -> {}", record_id, task_id);
    
    let service = DbImageGenerationService::new(database.inner().clone());
    
    match service.start_generation(&record_id, task_id) {
        Ok(_) => {
            info!("图片生成任务开始成功");
            Ok(())
        }
        Err(e) => {
            error!("开始图片生成任务失败: {}", e);
            Err(format!("开始图片生成任务失败: {}", e))
        }
    }
}

#[command]
pub async fn update_image_generation_progress_by_task_id(
    database: State<'_, Arc<Database>>,
    task_id: String,
    progress: f32
) -> Result<(), String> {
    let service = DbImageGenerationService::new(database.inner().clone());
    
    match service.update_progress_by_task_id(&task_id, progress) {
        Ok(_) => Ok(()),
        Err(e) => {
            error!("根据任务ID更新图片生成进度失败: {}", e);
            Err(format!("根据任务ID更新图片生成进度失败: {}", e))
        }
    }
}

#[command]
pub async fn complete_image_generation_by_task_id(
    database: State<'_, Arc<Database>>,
    task_id: String,
    result_urls: Vec<String>
) -> Result<(), String> {
    info!("根据任务ID完成图片生成: {} -> {} 张图片", task_id, result_urls.len());
    
    let service = DbImageGenerationService::new(database.inner().clone());
    
    match service.complete_generation_by_task_id(&task_id, result_urls) {
        Ok(_) => {
            info!("图片生成任务完成成功");
            Ok(())
        }
        Err(e) => {
            error!("根据任务ID完成图片生成失败: {}", e);
            Err(format!("根据任务ID完成图片生成失败: {}", e))
        }
    }
}

#[command]
pub async fn fail_image_generation_by_task_id(
    database: State<'_, Arc<Database>>,
    task_id: String,
    error_message: String
) -> Result<(), String> {
    error!("根据任务ID设置图片生成失败: {} -> {}", task_id, error_message);
    
    let service = DbImageGenerationService::new(database.inner().clone());
    
    match service.fail_generation_by_task_id(&task_id, error_message) {
        Ok(_) => Ok(()),
        Err(e) => {
            error!("根据任务ID设置图片生成失败状态失败: {}", e);
            Err(format!("根据任务ID设置图片生成失败状态失败: {}", e))
        }
    }
}

#[command]
pub async fn get_all_image_generation_records(
    database: State<'_, Arc<Database>>,
    limit: Option<i32>
) -> Result<Vec<ImageGenerationRecord>, String> {
    let service = DbImageGenerationService::new(database.inner().clone());
    
    match service.get_all_records(limit) {
        Ok(records) => {
            info!("获取到 {} 条图片生成记录", records.len());
            Ok(records)
        }
        Err(e) => {
            error!("获取图片生成记录列表失败: {}", e);
            Err(format!("获取图片生成记录列表失败: {}", e))
        }
    }
}

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

    let service = DbImageGenerationService::new(database.inner().clone());

    match service.delete_record(&record_id) {
        Ok(_) => {
            info!("图片生成记录删除成功");
            Ok(())
        }
        Err(e) => {
            error!("删除图片生成记录失败: {}", e);
            Err(format!("删除图片生成记录失败: {}", e))
        }
    }
}

/// 启动后台任务监控
#[command]
pub async fn start_background_task_monitoring(
    app: AppHandle,
    database: State<'_, Arc<Database>>,
    task_id: String,
    record_id: String
) -> Result<(), String> {
    info!("启动后台任务监控: {} -> {}", record_id, task_id);

    let app_handle = app.clone();
    let db = database.inner().clone();
    let task_id_clone = task_id.clone();
    let record_id_clone = record_id.clone();

    // 在后台线程中运行监控
    tokio::spawn(async move {
        let config = ApiConfig::default();
        let client = reqwest::Client::builder()
            .timeout(Duration::from_secs(30))
            .build()
            .unwrap();

        let service = DbImageGenerationService::new(db);
        let mut last_progress = 0.0;

        loop {
            // 查询API状态
            match query_task_status_internal(&client, &config, &task_id_clone).await {
                Ok(status) => {
                    // 只有进度变化时才更新和推送事件
                    if (status.progress - last_progress).abs() > 0.01 ||
                       status.status == "completed" ||
                       status.status == "failed" {

                        last_progress = status.progress;

                        // 更新数据库
                        let _ = service.update_progress_by_task_id(&task_id_clone, status.progress);

                        // 推送进度事件到前端
                        let _ = app_handle.emit("image-generation-progress", serde_json::json!({
                            "record_id": record_id_clone,
                            "task_id": task_id_clone,
                            "progress": status.progress,
                            "status": status.status
                        }));

                        // 如果任务完成或失败，停止监控
                        if status.status == "completed" {
                            let result_urls = status.result_urls.clone();
                            let _ = service.complete_generation_by_task_id(&task_id_clone, status.result_urls);
                            let _ = app_handle.emit("image-generation-completed", serde_json::json!({
                                "record_id": record_id_clone,
                                "task_id": task_id_clone,
                                "result_urls": result_urls
                            }));
                            break;
                        } else if status.status == "failed" {
                            let error_msg = status.error_message.unwrap_or_else(|| "生成失败".to_string());
                            let _ = service.fail_generation_by_task_id(&task_id_clone, error_msg.clone());
                            let _ = app_handle.emit("image-generation-failed", serde_json::json!({
                                "record_id": record_id_clone,
                                "task_id": task_id_clone,
                                "error": error_msg
                            }));
                            break;
                        }
                    }
                }
                Err(e) => {
                    error!("查询任务状态失败: {}", e);
                    // 继续监控，不中断
                }
            }

            // 等待3秒后再次查询
            tokio::time::sleep(Duration::from_secs(3)).await;
        }

        info!("任务监控结束: {}", task_id_clone);
    });

    Ok(())
}

/// 内部函数：查询任务状态
async fn query_task_status_internal(
    client: &reqwest::Client,
    config: &ApiConfig,
    task_id: &str
) -> Result<TaskStatusResponse, String> {
    let url = format!("{}/api/302/mj/async/query/status", config.base_url);
    let mut params = HashMap::new();
    params.insert("task_id", task_id);

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

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

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

    // 解析JSON响应（复用之前的解析逻辑）
    match serde_json::from_str::<serde_json::Value>(&response_text) {
        Ok(json_value) => {
            let task_id_result = if let Some(data_str) = json_value.get("data").and_then(|v| v.as_str()) {
                data_str.to_string()
            } else {
                json_value.get("task_id")
                    .and_then(|v| v.as_str())
                    .unwrap_or(task_id)
                    .to_string()
            };

            let msg = json_value.get("msg")
                .and_then(|v| v.as_str())
                .unwrap_or("");

            let status_str = if let Some(status_bool) = json_value.get("status").and_then(|v| v.as_bool()) {
                if status_bool {
                    "completed"
                } else {
                    if msg.contains("ON_QUEUE") {
                        "pending"
                    } else if msg.contains("PROCESSING") || msg.contains("progress") {
                        "processing"
                    } else if msg.contains("FAILED") || msg.contains("ERROR") {
                        "failed"
                    } else {
                        "processing"
                    }
                }
            } else {
                "processing"
            }.to_string();

            let progress = if status_str == "completed" {
                1.0
            } else if !msg.is_empty() {
                if let Some(progress_part) = msg.split("progress: ").nth(1) {
                    if let Some(percent_str) = progress_part.split('%').next() {
                        percent_str.parse::<f32>().ok().map(|p| p / 100.0).unwrap_or(0.0)
                    } else {
                        0.0
                    }
                } else {
                    0.0
                }
            } else {
                0.0
            };

            let (result_url, result_urls) = if let Some(data_array) = json_value.get("data").and_then(|v| v.as_array()) {
                let urls: Vec<String> = data_array.iter()
                    .filter_map(|v| v.as_str().map(|s| s.to_string()))
                    .collect();
                let first_url = urls.first().cloned();
                (first_url, urls)
            } else {
                (None, vec![])
            };

            let error_message = if status_str == "failed" {
                Some(msg.to_string())
            } else {
                None
            };

            Ok(TaskStatusResponse {
                task_id: task_id_result,
                status: status_str,
                progress,
                result_url,
                result_urls,
                error_message,
                created_at: "".to_string(),
                updated_at: "".to_string(),
            })
        }
        Err(e) => {
            Err(format!("解析JSON响应失败: {}", e))
        }
    }
}

/// 将S3 URL转换为CDN URL
fn convert_s3_to_cdn_url(s3_url: &str) -> String {
    if s3_url.starts_with("s3://ap-northeast-2/modal-media-cache/") {
        // 将 s3://ap-northeast-2/modal-media-cache/ 替换为 https://cdn.roasmax.cn/
        s3_url.replace("s3://ap-northeast-2/modal-media-cache/", "https://cdn.roasmax.cn/")
    } else if s3_url.starts_with("s3://") {
        // 处理其他 s3:// 格式，转换为通用CDN格式
        s3_url.replace("s3://", "https://cdn.roasmax.cn/")
    } else if s3_url.contains("amazonaws.com") {
        // 如果是完整的S3 HTTPS URL，提取key部分
        if let Some(key_start) = s3_url.find(".com/") {
            let key = &s3_url[key_start + 5..];
            format!("https://cdn.roasmax.cn/{}", key)
        } else {
            s3_url.to_string()
        }
    } else {
        // 如果不是预期的S3格式，返回原URL
        s3_url.to_string()
    }
}
