use anyhow::{Result, anyhow};
use std::sync::{Arc, Mutex};
use std::path::PathBuf;
use std::collections::HashMap;
use tokio::sync::Semaphore;
use tracing::{info, error};
use chrono::Utc;
use uuid::Uuid;

use crate::data::models::thumbnail::{
    BatchThumbnailTask, ThumbnailConfig, TimelineConfig, TaskStatus,
    BatchProgress, ThumbnailGenerationResult, ThumbnailGenerationOptions
};
use crate::business::services::thumbnail_generator_service::ThumbnailGeneratorService;

/// 批量缩略图处理器
/// 遵循 Tauri 开发规范的服务层设计原则
pub struct BatchThumbnailProcessor {
    generator: Arc<ThumbnailGeneratorService>,
    tasks: Arc<Mutex<HashMap<String, BatchThumbnailTask>>>,
    semaphore: Arc<Semaphore>,
}

impl BatchThumbnailProcessor {
    /// 创建新的批量处理器实例
    pub fn new(options: ThumbnailGenerationOptions) -> Self {
        let max_concurrent = options.max_concurrent as usize;
        
        Self {
            generator: Arc::new(ThumbnailGeneratorService::new(options)),
            tasks: Arc::new(Mutex::new(HashMap::new())),
            semaphore: Arc::new(Semaphore::new(max_concurrent)),
        }
    }

    /// 启动批量缩略图生成任务
    pub async fn start_batch_generation(
        &self,
        video_paths: Vec<PathBuf>,
        config: ThumbnailConfig,
        timeline_config: Option<TimelineConfig>,
    ) -> Result<String> {
        let task_id = Uuid::new_v4().to_string();
        let now = Utc::now();

        info!(
            task_id = %task_id,
            video_count = video_paths.len(),
            "启动批量缩略图生成任务"
        );

        // 创建任务
        let task = BatchThumbnailTask {
            task_id: task_id.clone(),
            video_files: video_paths.clone(),
            config: config.clone(),
            timeline_config: timeline_config.clone(),
            status: TaskStatus::Pending,
            progress: BatchProgress {
                total_files: video_paths.len() as u32,
                processed_files: 0,
                failed_files: 0,
                current_file: None,
                progress_percentage: 0.0,
                estimated_remaining_ms: None,
                processing_speed: None,
                errors: Vec::new(),
                results: Vec::new(),
            },
            created_at: now,
            updated_at: now,
            started_at: None,
            completed_at: None,
        };

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

        // 异步执行批量处理
        let processor = self.clone();
        let task_id_clone = task_id.clone();
        tokio::spawn(async move {
            if let Err(e) = processor.execute_batch_task(&task_id_clone).await {
                error!(
                    task_id = %task_id_clone,
                    error = %e,
                    "批量缩略图生成任务执行失败"
                );
                processor.update_task_status(&task_id_clone, TaskStatus::Failed).await;
            }
        });

        Ok(task_id)
    }

    /// 获取任务状态
    pub fn get_task_status(&self, task_id: &str) -> Result<BatchThumbnailTask> {
        let tasks = self.tasks.lock().unwrap();
        tasks.get(task_id)
            .cloned()
            .ok_or_else(|| anyhow!("任务不存在: {}", task_id))
    }

    /// 取消任务
    pub async fn cancel_task(&self, task_id: &str) -> Result<bool> {
        info!(task_id = %task_id, "取消批量缩略图生成任务");
        
        self.update_task_status(task_id, TaskStatus::Cancelled).await;
        Ok(true)
    }

    /// 暂停任务
    pub async fn pause_task(&self, task_id: &str) -> Result<bool> {
        info!(task_id = %task_id, "暂停批量缩略图生成任务");
        
        self.update_task_status(task_id, TaskStatus::Paused).await;
        Ok(true)
    }

    /// 恢复任务
    pub async fn resume_task(&self, task_id: &str) -> Result<bool> {
        info!(task_id = %task_id, "恢复批量缩略图生成任务");
        
        self.update_task_status(task_id, TaskStatus::Running).await;
        
        // 重新启动任务执行
        let processor = self.clone();
        let task_id_clone = task_id.to_string();
        tokio::spawn(async move {
            if let Err(e) = processor.execute_batch_task(&task_id_clone).await {
                error!(
                    task_id = %task_id_clone,
                    error = %e,
                    "恢复批量缩略图生成任务失败"
                );
                processor.update_task_status(&task_id_clone, TaskStatus::Failed).await;
            }
        });

        Ok(true)
    }

    /// 执行批量任务
    async fn execute_batch_task(&self, task_id: &str) -> Result<()> {
        let start_time = std::time::Instant::now();
        
        // 更新任务状态为运行中
        self.update_task_status(task_id, TaskStatus::Running).await;
        self.update_task_started_time(task_id).await;

        // 获取任务信息
        let (video_files, config, timeline_config) = {
            let tasks = self.tasks.lock().unwrap();
            let task = tasks.get(task_id)
                .ok_or_else(|| anyhow!("任务不存在: {}", task_id))?;
            (
                task.video_files.clone(),
                task.config.clone(),
                task.timeline_config.clone()
            )
        };

        info!(
            task_id = %task_id,
            video_count = video_files.len(),
            "开始执行批量缩略图生成"
        );

        // 并发处理视频文件
        let mut handles: Vec<tokio::task::JoinHandle<Result<Option<bool>, anyhow::Error>>> = Vec::new();
        
        for (index, video_path) in video_files.iter().enumerate() {
            let permit = self.semaphore.clone().acquire_owned().await?;
            let generator = self.generator.clone();
            let config = config.clone();
            let timeline_config = timeline_config.clone();
            let video_path = video_path.clone();
            let task_id = task_id.to_string();
            let processor = self.clone();

            let handle = tokio::spawn(async move {
                let _permit = permit; // 持有许可证直到任务完成
                
                // 检查任务是否被取消或暂停
                if processor.is_task_cancelled_or_paused(&task_id).await {
                    return Ok(None);
                }

                // 更新当前处理文件
                processor.update_current_file(&task_id, &video_path.to_string_lossy()).await;

                let video_path_str = video_path.to_string_lossy().to_string();
                
                // 生成缩略图
                let result = generator.generate_thumbnail(&video_path_str, &config).await;
                
                // 如果配置了时间轴，生成时间轴缩略图
                let timeline_result = if let Some(ref timeline_cfg) = timeline_config {
                    generator.generate_timeline_thumbnail(&video_path_str, timeline_cfg, &config).await
                } else {
                    Ok(String::new())
                };

                match result {
                    Ok(mut thumbnail_result) => {
                        if let Ok(timeline_path) = timeline_result {
                            if !timeline_path.is_empty() {
                                thumbnail_result.timeline_path = Some(timeline_path);
                            }
                        }
                        
                        processor.update_task_progress(&task_id, index, true, Some(thumbnail_result)).await;
                        Ok(Some(true))
                    }
                    Err(e) => {
                        error!(
                            task_id = %task_id,
                            video_path = %video_path_str,
                            error = %e,
                            "视频缩略图生成失败"
                        );
                        
                        let error_result = ThumbnailGenerationResult {
                            video_path: video_path_str,
                            success: false,
                            output_paths: Vec::new(),
                            timeline_path: None,
                            processing_time_ms: 0,
                            error_message: Some(e.to_string()),
                            metadata: Default::default(),
                        };
                        
                        processor.update_task_progress(&task_id, index, false, Some(error_result)).await;
                        Ok(Some(false))
                    }
                }
            });

            handles.push(handle);
        }

        // 等待所有任务完成
        let mut success_count = 0;
        let mut failed_count = 0;

        for handle in handles {
            match handle.await {
                Ok(Ok(Some(true))) => success_count += 1,
                Ok(Ok(Some(false))) => failed_count += 1,
                Ok(Ok(None)) => {
                    // 任务被取消或暂停
                    info!(task_id = %task_id, "任务被取消或暂停");
                    return Ok(());
                }
                Ok(Err(e)) => {
                    error!(task_id = %task_id, error = %e, "任务执行错误");
                    failed_count += 1;
                }
                Err(e) => {
                    error!(task_id = %task_id, error = %e, "任务句柄错误");
                    failed_count += 1;
                }
            }
        }

        let processing_time = start_time.elapsed();
        
        // 更新任务完成状态
        self.update_task_completed_time(task_id).await;
        
        if failed_count == 0 {
            self.update_task_status(task_id, TaskStatus::Completed).await;
        } else if success_count == 0 {
            self.update_task_status(task_id, TaskStatus::Failed).await;
        } else {
            self.update_task_status(task_id, TaskStatus::Completed).await;
        }

        info!(
            task_id = %task_id,
            success_count = success_count,
            failed_count = failed_count,
            processing_time_ms = processing_time.as_millis(),
            "批量缩略图生成任务完成"
        );

        Ok(())
    }

    /// 扫描文件夹并创建批量任务
    pub async fn scan_and_create_task(
        &self,
        folder_path: &str,
        config: ThumbnailConfig,
        timeline_config: Option<TimelineConfig>,
    ) -> Result<String> {
        info!(folder_path = %folder_path, "扫描文件夹创建批量缩略图任务");

        // 扫描视频文件
        let video_files = self.generator.scan_video_files(folder_path)?;

        if video_files.is_empty() {
            return Err(anyhow!("文件夹中没有找到视频文件: {}", folder_path));
        }

        let video_paths: Vec<PathBuf> = video_files.into_iter()
            .filter(|f| f.is_valid)
            .map(|f| f.path)
            .collect();

        if video_paths.is_empty() {
            return Err(anyhow!("文件夹中没有找到有效的视频文件: {}", folder_path));
        }

        info!(
            folder_path = %folder_path,
            valid_video_count = video_paths.len(),
            "扫描完成，创建批量任务"
        );

        self.start_batch_generation(video_paths, config, timeline_config).await
    }

    /// 获取所有任务列表
    pub fn get_all_tasks(&self) -> Vec<BatchThumbnailTask> {
        let tasks = self.tasks.lock().unwrap();
        tasks.values().cloned().collect()
    }

    /// 清理已完成的任务
    pub fn cleanup_completed_tasks(&self) -> usize {
        let mut tasks = self.tasks.lock().unwrap();
        let initial_count = tasks.len();

        tasks.retain(|_, task| {
            !matches!(task.status, TaskStatus::Completed | TaskStatus::Failed | TaskStatus::Cancelled)
        });

        let removed_count = initial_count - tasks.len();

        if removed_count > 0 {
            info!(removed_count = removed_count, "清理已完成的任务");
        }

        removed_count
    }

    /// 更新任务状态
    async fn update_task_status(&self, task_id: &str, status: TaskStatus) {
        let mut tasks = self.tasks.lock().unwrap();
        if let Some(task) = tasks.get_mut(task_id) {
            task.status = status;
            task.updated_at = Utc::now();
        }
    }

    /// 更新任务开始时间
    async fn update_task_started_time(&self, task_id: &str) {
        let mut tasks = self.tasks.lock().unwrap();
        if let Some(task) = tasks.get_mut(task_id) {
            task.started_at = Some(Utc::now());
            task.updated_at = Utc::now();
        }
    }

    /// 更新任务完成时间
    async fn update_task_completed_time(&self, task_id: &str) {
        let mut tasks = self.tasks.lock().unwrap();
        if let Some(task) = tasks.get_mut(task_id) {
            task.completed_at = Some(Utc::now());
            task.updated_at = Utc::now();
        }
    }

    /// 更新当前处理文件
    async fn update_current_file(&self, task_id: &str, current_file: &str) {
        let mut tasks = self.tasks.lock().unwrap();
        if let Some(task) = tasks.get_mut(task_id) {
            task.progress.current_file = Some(current_file.to_string());
            task.updated_at = Utc::now();
        }
    }

    /// 更新任务进度
    async fn update_task_progress(
        &self,
        task_id: &str,
        _file_index: usize,
        success: bool,
        result: Option<ThumbnailGenerationResult>,
    ) {
        let mut tasks = self.tasks.lock().unwrap();
        if let Some(task) = tasks.get_mut(task_id) {
            if success {
                task.progress.processed_files += 1;
            } else {
                task.progress.failed_files += 1;
                if let Some(ref result) = result {
                    if let Some(ref error) = result.error_message {
                        task.progress.errors.push(error.clone());
                    }
                }
            }

            if let Some(result) = result {
                task.progress.results.push(result);
            }

            // 计算进度百分比
            let total_processed = task.progress.processed_files + task.progress.failed_files;
            task.progress.progress_percentage =
                (total_processed as f32 / task.progress.total_files as f32) * 100.0;

            // 估算剩余时间
            if total_processed > 0 && task.started_at.is_some() {
                let elapsed = Utc::now().signed_duration_since(task.started_at.unwrap());
                let elapsed_ms = elapsed.num_milliseconds() as u64;
                let avg_time_per_file = elapsed_ms / total_processed as u64;
                let remaining_files = task.progress.total_files - total_processed;
                task.progress.estimated_remaining_ms = Some(avg_time_per_file * remaining_files as u64);

                // 计算处理速度
                if elapsed_ms > 0 {
                    task.progress.processing_speed = Some(
                        (total_processed as f32 * 1000.0) / elapsed_ms as f32
                    );
                }
            }

            task.updated_at = Utc::now();
        }
    }

    /// 检查任务是否被取消或暂停
    async fn is_task_cancelled_or_paused(&self, task_id: &str) -> bool {
        let tasks = self.tasks.lock().unwrap();
        if let Some(task) = tasks.get(task_id) {
            matches!(task.status, TaskStatus::Cancelled | TaskStatus::Paused)
        } else {
            true // 任务不存在，视为已取消
        }
    }
}

impl Clone for BatchThumbnailProcessor {
    fn clone(&self) -> Self {
        Self {
            generator: self.generator.clone(),
            tasks: self.tasks.clone(),
            semaphore: self.semaphore.clone(),
        }
    }
}

// 为ThumbnailMetadata实现Default
impl Default for crate::data::models::thumbnail::ThumbnailMetadata {
    fn default() -> Self {
        Self {
            video_duration: 0.0,
            video_resolution: (0, 0),
            thumbnail_count: 0,
            total_file_size: 0,
            timestamps_used: Vec::new(),
        }
    }
}
