use tauri::{State, AppHandle, Emitter};
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use uuid::Uuid;

use crate::data::models::image_editing::{
    ImageEditingConfig, ImageEditingTask, BatchImageEditingTask, 
    ImageEditingParams, ImageEditingTaskStatus,
};
use crate::infrastructure::image_editing_service::ImageEditingService;

/// 图像编辑服务状态管理
pub struct ImageEditingState {
    service: Arc<Mutex<ImageEditingService>>,
    tasks: Arc<Mutex<HashMap<String, ImageEditingTask>>>,
    batch_tasks: Arc<Mutex<HashMap<String, BatchImageEditingTask>>>,
}

impl ImageEditingState {
    pub fn new() -> Self {
        Self {
            service: Arc::new(Mutex::new(ImageEditingService::new())),
            tasks: Arc::new(Mutex::new(HashMap::new())),
            batch_tasks: Arc::new(Mutex::new(HashMap::new())),
        }
    }
}

/// 设置API配置
#[tauri::command]
pub async fn set_image_editing_config(
    state: State<'_, ImageEditingState>,
    config: ImageEditingConfig,
) -> Result<(), String> {
    let new_service = ImageEditingService::with_config(config);

    if let Ok(mut current_service) = state.service.lock() {
        *current_service = new_service;
    }

    Ok(())
}

/// 设置API密钥
#[tauri::command]
pub async fn set_image_editing_api_key(
    state: State<'_, ImageEditingState>,
    api_key: String,
) -> Result<(), String> {
    if let Ok(mut service) = state.service.lock() {
        service.set_api_key(api_key);
    }
    
    Ok(())
}

/// 编辑单张图像
#[tauri::command]
pub async fn edit_single_image(
    state: State<'_, ImageEditingState>,
    input_path: String,
    output_path: String,
    prompt: String,
    params: ImageEditingParams,
) -> Result<String, String> {
    let input_path = Path::new(&input_path);
    let output_path = Path::new(&output_path);

    // 克隆服务以避免跨await持有锁
    let service = {
        let service_guard = state.service.lock().map_err(|e| format!("获取服务失败: {}", e))?;
        service_guard.clone()
    };

    match service.edit_single_image(input_path, output_path, &prompt, &params).await {
        Ok(_response) => {
            // 返回任务ID或结果信息
            Ok(format!("图像编辑完成，输出路径: {}", output_path.display()))
        }
        Err(e) => Err(format!("图像编辑失败: {}", e)),
    }
}

/// 创建图像编辑任务
#[tauri::command]
pub async fn create_image_editing_task(
    state: State<'_, ImageEditingState>,
    input_path: String,
    output_path: String,
    prompt: String,
    params: ImageEditingParams,
) -> Result<String, String> {
    let input_path = Path::new(&input_path);
    let output_path = Path::new(&output_path);

    // 克隆服务以避免跨await持有锁
    let service = {
        let service_guard = state.service.lock().map_err(|e| format!("获取服务失败: {}", e))?;
        service_guard.clone()
    };

    match service.create_edit_task(input_path, output_path, &prompt, &params).await {
        Ok(task) => {
            let task_id = task.id.clone();

            // 存储任务
            if let Ok(mut tasks) = state.tasks.lock() {
                tasks.insert(task_id.clone(), task);
            }

            Ok(task_id)
        }
        Err(e) => Err(format!("创建任务失败: {}", e)),
    }
}

/// 执行图像编辑任务
#[tauri::command]
pub async fn execute_image_editing_task(
    state: State<'_, ImageEditingState>,
    task_id: String,
) -> Result<(), String> {
    // 克隆服务以避免跨await持有锁
    let service = {
        let service_guard = state.service.lock().map_err(|e| format!("获取服务失败: {}", e))?;
        service_guard.clone()
    };

    // 获取任务
    let mut task = {
        let tasks = state.tasks.lock().map_err(|e| format!("获取任务失败: {}", e))?;
        tasks.get(&task_id).cloned().ok_or_else(|| "任务不存在".to_string())?
    };

    // 执行任务
    match service.execute_task(&mut task).await {
        Ok(_) => {
            // 更新任务状态
            if let Ok(mut tasks) = state.tasks.lock() {
                tasks.insert(task_id, task);
            }
            Ok(())
        }
        Err(e) => {
            // 更新失败状态
            if let Ok(mut tasks) = state.tasks.lock() {
                tasks.insert(task_id, task);
            }
            Err(format!("执行任务失败: {}", e))
        }
    }
}

/// 获取任务状态
#[tauri::command]
pub async fn get_image_editing_task_status(
    state: State<'_, ImageEditingState>,
    task_id: String,
) -> Result<ImageEditingTask, String> {
    let tasks = state.tasks.lock().map_err(|e| format!("获取任务失败: {}", e))?;
    
    tasks.get(&task_id)
        .cloned()
        .ok_or_else(|| "任务不存在".to_string())
}

/// 批量编辑图像
#[tauri::command]
pub async fn edit_batch_images(
    app: AppHandle,
    state: State<'_, ImageEditingState>,
    input_folder: String,
    output_folder: String,
    prompt: String,
    params: ImageEditingParams,
) -> Result<String, String> {
    let input_folder = Path::new(&input_folder);
    let output_folder = Path::new(&output_folder);

    // 生成任务ID
    let task_id = Uuid::new_v4().to_string();

    // 立即创建批量任务并存储到状态中
    let mut batch_task = BatchImageEditingTask::new(
        task_id.clone(),
        input_folder.to_string_lossy().to_string(),
        output_folder.to_string_lossy().to_string(),
        prompt.clone(),
        crate::data::models::image_editing::ImageEditingRequest {
            model: "doubao-seededit-3-0-i2i-250628".to_string(),
            prompt: prompt.clone(),
            image: String::new(),
            response_format: Some(params.response_format.clone()),
            size: Some(params.size.clone()),
            seed: Some(params.seed),
            guidance_scale: Some(params.guidance_scale),
            watermark: Some(params.watermark),
        },
    );

    // 设置任务状态为处理中
    batch_task.status = ImageEditingTaskStatus::Processing;

    // 立即存储批量任务，这样前端就能获取到
    {
        let mut batch_tasks = state.batch_tasks.lock().map_err(|e| format!("获取任务存储失败: {}", e))?;
        batch_tasks.insert(task_id.clone(), batch_task.clone());
    }

    // 克隆服务以避免跨await持有锁
    let service = {
        let service_guard = state.service.lock().map_err(|e| format!("获取服务失败: {}", e))?;
        service_guard.clone()
    };

    // 克隆必要的数据用于异步任务
    let batch_tasks_clone = state.batch_tasks.clone();
    let task_id_clone = task_id.clone();

    // 创建任务状态更新回调
    let app_clone = app.clone();
    let update_callback = Box::new(move |updated_task: BatchImageEditingTask| {
        if let Ok(mut batch_tasks) = batch_tasks_clone.lock() {
            batch_tasks.insert(task_id_clone.clone(), updated_task.clone());
        }

        // 发送Tauri事件通知前端
        if let Err(e) = app_clone.emit("batch-task-updated", &updated_task) {
            println!("发送任务更新事件失败: {}", e);
        }
    });

    // 异步执行批量处理
    let service_clone = service.clone();
    let input_folder_clone = input_folder.to_path_buf();
    let output_folder_clone = output_folder.to_path_buf();
    let prompt_clone = prompt.clone();
    let params_clone = params.clone();
    let task_id_for_spawn = task_id.clone();
    let batch_tasks_for_spawn = state.batch_tasks.clone();
    let app_for_spawn = app.clone();

    tokio::spawn(async move {
        match service_clone.edit_batch_images_with_callback(
            &input_folder_clone,
            &output_folder_clone,
            &prompt_clone,
            &params_clone,
            Some(update_callback),
        ).await {
            Ok(final_task) => {
                // 存储最终任务状态
                if let Ok(mut batch_tasks) = batch_tasks_for_spawn.lock() {
                    batch_tasks.insert(task_id_for_spawn.clone(), final_task.clone());
                }

                // 发送最终完成事件
                if let Err(e) = app_for_spawn.emit("batch-task-completed", &final_task) {
                    println!("发送任务完成事件失败: {}", e);
                }
            }
            Err(e) => {
                // 处理失败，更新任务状态
                let mut failed_task = None;
                if let Ok(mut batch_tasks) = batch_tasks_for_spawn.lock() {
                    if let Some(task) = batch_tasks.get_mut(&task_id_for_spawn) {
                        task.status = ImageEditingTaskStatus::Failed;
                        task.updated_at = chrono::Utc::now();
                        failed_task = Some(task.clone());
                    }
                }

                // 发送失败事件
                if let Some(task) = failed_task {
                    if let Err(e) = app_for_spawn.emit("batch-task-failed", &task) {
                        println!("发送任务失败事件失败: {}", e);
                    }
                }

                println!("批量编辑失败: {}", e);
            }
        }
    });

    Ok(task_id)
}

/// 创建批量编辑任务
#[tauri::command]
pub async fn create_batch_editing_task(
    state: State<'_, ImageEditingState>,
    input_folder: String,
    output_folder: String,
    prompt: String,
    params: ImageEditingParams,
) -> Result<String, String> {
    let task_id = Uuid::new_v4().to_string();
    
    // 创建批量任务（不立即执行）
    let batch_task = BatchImageEditingTask::new(
        task_id.clone(),
        input_folder,
        output_folder,
        prompt,
        crate::data::models::image_editing::ImageEditingRequest {
            model: "doubao-seededit-3-0-i2i-250628".to_string(),
            prompt: String::new(),
            image: String::new(),
            response_format: Some(params.response_format.clone()),
            size: Some(params.size.clone()),
            seed: Some(params.seed),
            guidance_scale: Some(params.guidance_scale),
            watermark: Some(params.watermark),
        },
    );
    
    // 存储批量任务
    if let Ok(mut batch_tasks) = state.batch_tasks.lock() {
        batch_tasks.insert(task_id.clone(), batch_task);
    }
    
    Ok(task_id)
}

/// 获取批量任务状态
#[tauri::command]
pub async fn get_batch_editing_task_status(
    state: State<'_, ImageEditingState>,
    task_id: String,
) -> Result<BatchImageEditingTask, String> {
    let batch_tasks = state.batch_tasks.lock().map_err(|e| format!("获取任务失败: {}", e))?;
    
    batch_tasks.get(&task_id)
        .cloned()
        .ok_or_else(|| "批量任务不存在".to_string())
}

/// 获取所有任务列表
#[tauri::command]
pub async fn get_all_image_editing_tasks(
    state: State<'_, ImageEditingState>,
) -> Result<Vec<ImageEditingTask>, String> {
    let tasks = state.tasks.lock().map_err(|e| format!("获取任务失败: {}", e))?;
    
    Ok(tasks.values().cloned().collect())
}

/// 获取所有批量任务列表
#[tauri::command]
pub async fn get_all_batch_editing_tasks(
    state: State<'_, ImageEditingState>,
) -> Result<Vec<BatchImageEditingTask>, String> {
    let batch_tasks = state.batch_tasks.lock().map_err(|e| format!("获取任务失败: {}", e))?;
    
    Ok(batch_tasks.values().cloned().collect())
}

/// 清除已完成的任务
#[tauri::command]
pub async fn clear_completed_tasks(
    state: State<'_, ImageEditingState>,
) -> Result<(), String> {
    // 清除单个任务
    if let Ok(mut tasks) = state.tasks.lock() {
        tasks.retain(|_, task| !matches!(task.status, ImageEditingTaskStatus::Completed | ImageEditingTaskStatus::Failed));
    }
    
    // 清除批量任务
    if let Ok(mut batch_tasks) = state.batch_tasks.lock() {
        batch_tasks.retain(|_, task| !matches!(task.status, ImageEditingTaskStatus::Completed | ImageEditingTaskStatus::Failed));
    }
    
    Ok(())
}

/// 取消任务
#[tauri::command]
pub async fn cancel_image_editing_task(
    state: State<'_, ImageEditingState>,
    task_id: String,
) -> Result<(), String> {
    if let Ok(mut tasks) = state.tasks.lock() {
        if let Some(task) = tasks.get_mut(&task_id) {
            if matches!(task.status, ImageEditingTaskStatus::Pending | ImageEditingTaskStatus::Processing) {
                task.status = ImageEditingTaskStatus::Cancelled;
                task.updated_at = chrono::Utc::now();
            }
        }
    }
    
    Ok(())
}
