use tauri::command;
use std::sync::{Arc, Mutex};
use std::path::PathBuf;
use tracing::{info, error, warn};
use lazy_static::lazy_static;

use crate::data::models::thumbnail::{
    ThumbnailConfig, TimelineConfig, BatchThumbnailTask,
    ThumbnailGenerationOptions, VideoFile
};
use crate::business::services::batch_thumbnail_processor::BatchThumbnailProcessor;

lazy_static! {
    static ref THUMBNAIL_PROCESSOR: Arc<Mutex<Option<Arc<BatchThumbnailProcessor>>>> = 
        Arc::new(Mutex::new(None));
}

/// 获取或创建批量缩略图处理器实例
fn get_or_create_processor() -> Arc<BatchThumbnailProcessor> {
    let mut processor_guard = THUMBNAIL_PROCESSOR.lock().unwrap();
    
    if processor_guard.is_none() {
        let options = ThumbnailGenerationOptions::default();
        *processor_guard = Some(Arc::new(BatchThumbnailProcessor::new(options)));
        info!("创建新的批量缩略图处理器实例");
    }
    
    processor_guard.as_ref().unwrap().clone()
}

/// 批量缩略图生成请求
#[derive(Debug, serde::Deserialize)]
pub struct BatchThumbnailRequest {
    pub video_paths: Vec<String>,
    pub config: ThumbnailConfig,
    pub timeline_config: Option<TimelineConfig>,
}

/// 文件夹扫描请求
#[derive(Debug, serde::Deserialize)]
pub struct FolderScanRequest {
    pub folder_path: String,
    pub config: ThumbnailConfig,
    pub timeline_config: Option<TimelineConfig>,
}

/// 缩略图预览请求
#[derive(Debug, serde::Deserialize)]
pub struct ThumbnailPreviewRequest {
    pub video_path: String,
    pub timestamp: f64,
    pub width: u32,
    pub height: u32,
}

/// 启动批量缩略图生成
/// 接受视频文件路径列表和配置，返回任务ID
#[command]
pub async fn start_batch_thumbnail_generation(
    request: BatchThumbnailRequest,
) -> Result<String, String> {
    info!(
        video_count = request.video_paths.len(),
        config = ?request.config,
        "启动批量缩略图生成"
    );

    let processor = get_or_create_processor();
    
    let video_paths: Vec<PathBuf> = request.video_paths
        .into_iter()
        .map(PathBuf::from)
        .collect();

    processor
        .start_batch_generation(video_paths, request.config, request.timeline_config)
        .await
        .map_err(|e| {
            error!(error = %e, "启动批量缩略图生成失败");
            e.to_string()
        })
}

/// 扫描文件夹并启动批量生成
/// 扫描指定文件夹中的所有视频文件并启动批量生成任务
#[command]
pub async fn scan_folder_and_generate_thumbnails(
    request: FolderScanRequest,
) -> Result<String, String> {
    info!(
        folder_path = %request.folder_path,
        config = ?request.config,
        "扫描文件夹并启动批量缩略图生成"
    );

    let processor = get_or_create_processor();
    
    processor
        .scan_and_create_task(&request.folder_path, request.config, request.timeline_config)
        .await
        .map_err(|e| {
            error!(
                folder_path = %request.folder_path,
                error = %e,
                "扫描文件夹并启动批量生成失败"
            );
            e.to_string()
        })
}

/// 获取任务状态
/// 根据任务ID获取批量生成任务的详细状态信息
#[command]
pub async fn get_thumbnail_task_status(
    task_id: String,
) -> Result<BatchThumbnailTask, String> {
    let processor = get_or_create_processor();
    
    processor
        .get_task_status(&task_id)
        .map_err(|e| {
            warn!(task_id = %task_id, error = %e, "获取任务状态失败");
            e.to_string()
        })
}

/// 取消缩略图生成任务
/// 取消指定的批量生成任务
#[command]
pub async fn cancel_thumbnail_task(
    task_id: String,
) -> Result<bool, String> {
    info!(task_id = %task_id, "取消缩略图生成任务");

    let processor = get_or_create_processor();
    
    processor
        .cancel_task(&task_id)
        .await
        .map_err(|e| {
            error!(task_id = %task_id, error = %e, "取消任务失败");
            e.to_string()
        })
}

/// 暂停缩略图生成任务
/// 暂停指定的批量生成任务
#[command]
pub async fn pause_thumbnail_task(
    task_id: String,
) -> Result<bool, String> {
    info!(task_id = %task_id, "暂停缩略图生成任务");

    let processor = get_or_create_processor();
    
    processor
        .pause_task(&task_id)
        .await
        .map_err(|e| {
            error!(task_id = %task_id, error = %e, "暂停任务失败");
            e.to_string()
        })
}

/// 恢复缩略图生成任务
/// 恢复已暂停的批量生成任务
#[command]
pub async fn resume_thumbnail_task(
    task_id: String,
) -> Result<bool, String> {
    info!(task_id = %task_id, "恢复缩略图生成任务");

    let processor = get_or_create_processor();
    
    processor
        .resume_task(&task_id)
        .await
        .map_err(|e| {
            error!(task_id = %task_id, error = %e, "恢复任务失败");
            e.to_string()
        })
}

/// 获取所有任务列表
/// 获取所有批量生成任务的列表
#[command]
pub async fn get_all_thumbnail_tasks() -> Result<Vec<BatchThumbnailTask>, String> {
    let processor = get_or_create_processor();
    Ok(processor.get_all_tasks())
}

/// 清理已完成的任务
/// 清理所有已完成、失败或取消的任务
#[command]
pub async fn cleanup_completed_thumbnail_tasks() -> Result<usize, String> {
    let processor = get_or_create_processor();
    let removed_count = processor.cleanup_completed_tasks();
    
    info!(removed_count = removed_count, "清理已完成的缩略图任务");
    Ok(removed_count)
}

/// 选择视频文件夹
/// 打开文件夹选择对话框，返回选中的文件夹路径
#[command]
pub async fn select_video_folder() -> Result<Option<String>, String> {
    // 这里需要在实际的Tauri应用上下文中调用
    // 暂时返回None，实际实现需要在前端调用文件夹选择对话框
    warn!("select_video_folder 需要在前端实现文件夹选择对话框");
    Ok(None)
}

/// 扫描文件夹中的视频文件
/// 扫描指定文件夹，返回其中的视频文件列表
#[command]
pub async fn scan_video_files_for_thumbnails(
    folder_path: String,
) -> Result<Vec<VideoFile>, String> {
    info!(folder_path = %folder_path, "扫描文件夹中的视频文件");

    // 创建临时的生成器服务来扫描文件
    let options = ThumbnailGenerationOptions::default();
    let generator = crate::business::services::thumbnail_generator_service::ThumbnailGeneratorService::new(options);

    generator
        .scan_video_files(&folder_path)
        .map_err(|e| {
            error!(
                folder_path = %folder_path,
                error = %e,
                "扫描视频文件失败"
            );
            e.to_string()
        })
}

/// 生成缩略图预览
/// 为指定视频在指定时间戳生成预览缩略图，返回base64编码的图片数据
#[command]
pub async fn preview_thumbnail(
    request: ThumbnailPreviewRequest,
) -> Result<String, String> {
    info!(
        video_path = %request.video_path,
        timestamp = request.timestamp,
        size = format!("{}x{}", request.width, request.height),
        "生成缩略图预览"
    );

    use crate::infrastructure::ffmpeg::FFmpegService;
    use std::fs;
    use base64::{Engine as _, engine::general_purpose};

    // 创建临时输出文件
    let temp_dir = std::env::temp_dir();
    let temp_filename = format!("preview_{}_{}.jpg", 
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_millis(),
        uuid::Uuid::new_v4().to_string()
    );
    let temp_path = temp_dir.join(temp_filename);
    let temp_path_str = temp_path.to_string_lossy().to_string();

    // 生成缩略图
    match FFmpegService::generate_thumbnail(
        &request.video_path,
        &temp_path_str,
        request.timestamp,
        request.width,
        request.height,
    ) {
        Ok(_) => {
            // 读取文件并转换为base64
            match fs::read(&temp_path) {
                Ok(image_data) => {
                    let base64_data = general_purpose::STANDARD.encode(&image_data);
                    let data_url = format!("data:image/jpeg;base64,{}", base64_data);
                    
                    // 清理临时文件
                    let _ = fs::remove_file(&temp_path);
                    
                    Ok(data_url)
                }
                Err(e) => {
                    error!(
                        temp_path = %temp_path_str,
                        error = %e,
                        "读取预览缩略图文件失败"
                    );
                    let _ = fs::remove_file(&temp_path);
                    Err(format!("读取预览缩略图失败: {}", e))
                }
            }
        }
        Err(e) => {
            error!(
                video_path = %request.video_path,
                error = %e,
                "生成预览缩略图失败"
            );
            Err(format!("生成预览缩略图失败: {}", e))
        }
    }
}
