use tauri::State;
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(
    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);

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

    match service.edit_batch_images(input_folder, output_folder, &prompt, &params, None).await {
        Ok(batch_task) => {
            let task_id = batch_task.id.clone();

            // 存储批量任务
            if let Ok(mut batch_tasks) = state.batch_tasks.lock() {
                batch_tasks.insert(task_id.clone(), batch_task);
            }

            Ok(task_id)
        }
        Err(e) => Err(format!("批量编辑失败: {}", e)),
    }
}

/// 创建批量编辑任务
#[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(())
}
