use tauri::{command, State};
use tracing::{info, error};
use std::sync::Arc;

use crate::app_state::AppState;
use crate::data::models::batch_processing::*;
use crate::business::services::batch_processing_service::BatchProcessingService;

/// 创建批量处理任务
#[command]
pub async fn create_batch_task(
    request: CreateBatchTaskRequest,
    state: State<'_, AppState>,
) -> Result<BatchProcessingTask, String> {
    info!("创建批量处理任务: {}", request.name);

    // 获取批量处理服务
    let batch_service = get_batch_service(&state)?;

    // 创建批量任务
    match batch_service.create_batch_task(request).await {
        Ok(task) => {
            info!("批量任务创建成功，ID: {}", task.id);
            Ok(task)
        }
        Err(e) => {
            error!("创建批量任务失败: {}", e);
            Err(format!("创建批量任务失败: {}", e))
        }
    }
}

/// 开始批量处理
#[command]
pub async fn start_batch_processing(
    task_id: String,
    state: State<'_, AppState>,
) -> Result<(), String> {
    info!("开始批量处理任务: {}", task_id);

    // 获取批量处理服务
    let batch_service = get_batch_service(&state)?;

    // 开始处理
    match batch_service.start_batch_processing(&task_id).await {
        Ok(_) => {
            info!("批量处理任务已启动: {}", task_id);
            Ok(())
        }
        Err(e) => {
            error!("启动批量处理失败: {}", e);
            Err(format!("启动批量处理失败: {}", e))
        }
    }
}

/// 获取批量任务信息
#[command]
pub async fn get_batch_task(
    task_id: String,
    state: State<'_, AppState>,
) -> Result<Option<BatchProcessingTask>, String> {
    info!("获取批量任务信息: {}", task_id);

    // 获取批量处理服务
    let batch_service = get_batch_service(&state)?;

    // 获取任务
    let task = batch_service.get_batch_task(&task_id);
    Ok(task)
}

/// 获取所有批量任务
#[command]
pub async fn get_all_batch_tasks(
    state: State<'_, AppState>,
) -> Result<Vec<BatchProcessingTask>, String> {
    info!("获取所有批量任务");

    // 获取批量处理服务
    let batch_service = get_batch_service(&state)?;

    // 获取所有任务
    let tasks = batch_service.get_all_batch_tasks();
    info!("获取到 {} 个批量任务", tasks.len());
    Ok(tasks)
}

/// 获取批量处理进度
#[command]
pub async fn get_batch_progress(
    task_id: String,
    state: State<'_, AppState>,
) -> Result<Option<BatchProcessingProgress>, String> {
    info!("获取批量处理进度: {}", task_id);

    // 获取批量处理服务
    let batch_service = get_batch_service(&state)?;

    // 获取进度
    let progress = batch_service.get_batch_progress(&task_id);
    Ok(progress)
}

/// 取消批量任务
#[command]
pub async fn cancel_batch_task(
    task_id: String,
    state: State<'_, AppState>,
) -> Result<(), String> {
    info!("取消批量任务: {}", task_id);

    // 获取批量处理服务
    let batch_service = get_batch_service(&state)?;

    // 取消任务
    match batch_service.cancel_batch_task(&task_id) {
        Ok(_) => {
            info!("批量任务已取消: {}", task_id);
            Ok(())
        }
        Err(e) => {
            error!("取消批量任务失败: {}", e);
            Err(format!("取消批量任务失败: {}", e))
        }
    }
}

/// 选择文件夹
#[command]
pub async fn select_folder(
    title: Option<String>,
) -> Result<Option<String>, String> {
    use tauri::api::dialog::blocking::FileDialogBuilder;

    let dialog_title = title.unwrap_or_else(|| "选择文件夹".to_string());
    
    match FileDialogBuilder::new()
        .set_title(&dialog_title)
        .pick_folder() {
        Some(path) => Ok(Some(path.to_string_lossy().to_string())),
        None => Ok(None),
    }
}

/// 扫描文件夹预览
#[command]
pub async fn scan_folder_preview(
    folder_path: String,
    file_extensions: Vec<String>,
    recursive: bool,
) -> Result<Vec<String>, String> {
    use std::path::Path;
    use tokio::fs;

    info!("扫描文件夹预览: {}", folder_path);

    let path = Path::new(&folder_path);
    if !path.exists() || !path.is_dir() {
        return Err("文件夹不存在或不是有效目录".to_string());
    }

    let mut file_paths = Vec::new();
    
    match scan_directory_for_preview(path, &file_extensions, recursive, &mut file_paths).await {
        Ok(_) => {
            info!("扫描到 {} 个文件", file_paths.len());
            Ok(file_paths)
        }
        Err(e) => {
            error!("扫描文件夹失败: {}", e);
            Err(format!("扫描文件夹失败: {}", e))
        }
    }
}

/// 递归扫描目录（预览用）
async fn scan_directory_for_preview(
    dir_path: &Path,
    extensions: &[String],
    recursive: bool,
    file_paths: &mut Vec<String>,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut entries = fs::read_dir(dir_path).await?;

    while let Some(entry) = entries.next_entry().await? {
        let path = entry.path();
        
        if path.is_file() {
            // 检查文件扩展名
            if let Some(ext) = path.extension() {
                let ext_str = ext.to_string_lossy().to_lowercase();
                if extensions.is_empty() || extensions.iter().any(|e| e.to_lowercase() == ext_str) {
                    file_paths.push(path.to_string_lossy().to_string());
                }
            }
        } else if path.is_dir() && recursive {
            // 递归扫描子目录
            scan_directory_for_preview(&path, extensions, recursive, file_paths).await?;
        }
    }

    Ok(())
}

/// 获取批量处理服务
fn get_batch_service(state: &State<AppState>) -> Result<Arc<BatchProcessingService>, String> {
    // 这里需要从AppState中获取批量处理服务
    // 由于当前AppState可能还没有包含BatchProcessingService，
    // 我们需要先更新AppState结构
    
    // 临时实现：创建一个新的服务实例
    // 在实际应用中，应该从AppState中获取单例服务
    
    let workflow_service = state.get_universal_workflow_service()
        .map_err(|e| format!("获取工作流服务失败: {}", e))?;
    
    let workflow_service_arc = workflow_service.as_ref()
        .ok_or_else(|| "工作流服务未初始化".to_string())?;
    
    // 创建批量处理服务
    let batch_service = BatchProcessingService::new(Arc::clone(workflow_service_arc));
    Ok(Arc::new(batch_service))
}

/// 获取支持的文件扩展名列表
#[command]
pub async fn get_supported_file_extensions() -> Result<Vec<String>, String> {
    // 返回常见的图片文件扩展名
    Ok(vec![
        "jpg".to_string(),
        "jpeg".to_string(),
        "png".to_string(),
        "bmp".to_string(),
        "gif".to_string(),
        "tiff".to_string(),
        "webp".to_string(),
    ])
}

/// 验证输出文件夹
#[command]
pub async fn validate_output_folder(
    folder_path: String,
) -> Result<bool, String> {
    use std::path::Path;
    use tokio::fs;

    let path = Path::new(&folder_path);
    
    // 如果文件夹不存在，尝试创建
    if !path.exists() {
        match fs::create_dir_all(path).await {
            Ok(_) => Ok(true),
            Err(e) => Err(format!("创建输出文件夹失败: {}", e)),
        }
    } else if path.is_dir() {
        Ok(true)
    } else {
        Err("指定路径不是有效的文件夹".to_string())
    }
}
