use anyhow::{Result, anyhow};
use std::sync::Arc;
use tokio::sync::{Mutex, Semaphore};
use std::collections::{HashMap, VecDeque};
use std::path::{Path, PathBuf};
// use tokio::fs; // 暂时不需要

use crate::data::models::template::{BatchImportRequest, ImportTemplateRequest, ImportProgress};
use crate::business::services::template_import_service::TemplateImportService;
use crate::infrastructure::database::Database;

/// 导入队列项
#[derive(Debug, Clone)]
pub struct ImportQueueItem {
    pub id: String,
    pub file_path: String,
    pub template_name: Option<String>,
    pub project_id: Option<String>,
    pub auto_upload: bool,
    pub status: QueueItemStatus,
    pub error_message: Option<String>,
    pub created_at: chrono::DateTime<chrono::Utc>,
}

/// 队列项状态
#[derive(Debug, Clone, PartialEq)]
pub enum QueueItemStatus {
    Pending,    // 等待处理
    Processing, // 处理中
    Completed,  // 完成
    Failed,     // 失败
    Cancelled,  // 取消
}

/// 批量导入进度
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BatchImportProgress {
    pub total_items: usize,
    pub completed_items: usize,
    pub failed_items: usize,
    pub current_item: Option<String>,
    pub overall_progress: f64, // 0.0 - 100.0
    pub is_running: bool,
}

/// 导入队列管理器
/// 遵循 Tauri 开发规范的业务逻辑设计原则
pub struct ImportQueueManager {
    database: Arc<Database>,
    import_service: TemplateImportService,
    queue: Arc<Mutex<VecDeque<ImportQueueItem>>>,
    progress_map: Arc<Mutex<HashMap<String, ImportProgress>>>,
    batch_progress: Arc<Mutex<BatchImportProgress>>,
    semaphore: Arc<Semaphore>,
    is_running: Arc<Mutex<bool>>,
}

/// 批量导入事件
#[derive(Debug, Clone)]
pub enum BatchImportEvent {
    Started { total_items: usize },
    ItemStarted { item_id: String, file_path: String },
    ItemCompleted { item_id: String, template_id: String },
    ItemFailed { item_id: String, error: String },
    Progress { progress: BatchImportProgress },
    Completed { total: usize, completed: usize, failed: usize },
}

/// 批量导入事件回调
pub type BatchImportEventCallback = Box<dyn Fn(BatchImportEvent) + Send + Sync>;

impl ImportQueueManager {
    /// 创建新的导入队列管理器
    pub fn new(database: Arc<Database>, max_concurrent: usize) -> Self {
        let import_service = TemplateImportService::new(database.clone());
        
        Self {
            database,
            import_service,
            queue: Arc::new(Mutex::new(VecDeque::new())),
            progress_map: Arc::new(Mutex::new(HashMap::new())),
            batch_progress: Arc::new(Mutex::new(BatchImportProgress {
                total_items: 0,
                completed_items: 0,
                failed_items: 0,
                current_item: None,
                overall_progress: 0.0,
                is_running: false,
            })),
            semaphore: Arc::new(Semaphore::new(max_concurrent)),
            is_running: Arc::new(Mutex::new(false)),
        }
    }

    /// 扫描文件夹并添加到队列
    pub async fn scan_and_queue_folder(
        &self,
        request: BatchImportRequest,
    ) -> Result<Vec<ImportQueueItem>> {
        let folder_path = Path::new(&request.folder_path);
        
        if !folder_path.exists() || !folder_path.is_dir() {
            return Err(anyhow!("指定的文件夹不存在或不是目录: {}", request.folder_path));
        }

        let mut items = Vec::new();
        let mut queue = self.queue.lock().await;

        // 递归扫描文件夹
        let draft_files = self.scan_draft_files(folder_path).await?;
        
        for file_path in draft_files {
            let item = ImportQueueItem {
                id: uuid::Uuid::new_v4().to_string(),
                file_path: file_path.to_string_lossy().to_string(),
                template_name: None, // 将从文件名推断
                project_id: request.project_id.clone(),
                auto_upload: request.auto_upload,
                status: QueueItemStatus::Pending,
                error_message: None,
                created_at: chrono::Utc::now(),
            };
            
            queue.push_back(item.clone());
            items.push(item);
        }

        Ok(items)
    }

    /// 添加单个文件到队列
    pub async fn add_to_queue(&self, request: ImportTemplateRequest) -> Result<String> {
        let item = ImportQueueItem {
            id: uuid::Uuid::new_v4().to_string(),
            file_path: request.file_path,
            template_name: request.template_name,
            project_id: request.project_id,
            auto_upload: request.auto_upload,
            status: QueueItemStatus::Pending,
            error_message: None,
            created_at: chrono::Utc::now(),
        };

        let item_id = item.id.clone();
        let mut queue = self.queue.lock().await;
        queue.push_back(item);

        Ok(item_id)
    }

    /// 开始批量处理队列
    pub async fn start_batch_processing(
        &self,
        callback: Option<BatchImportEventCallback>,
    ) -> Result<()> {
        let mut is_running = self.is_running.lock().await;
        if *is_running {
            return Err(anyhow!("批量导入已在进行中"));
        }
        *is_running = true;
        drop(is_running);

        let queue_len = {
            let queue = self.queue.lock().await;
            queue.len()
        };

        if queue_len == 0 {
            return Err(anyhow!("队列为空，没有需要处理的项目"));
        }

        // 初始化批量进度
        {
            let mut batch_progress = self.batch_progress.lock().await;
            *batch_progress = BatchImportProgress {
                total_items: queue_len,
                completed_items: 0,
                failed_items: 0,
                current_item: None,
                overall_progress: 0.0,
                is_running: true,
            };
        }

        if let Some(callback) = &callback {
            callback(BatchImportEvent::Started { total_items: queue_len });
        }

        // 启动处理任务
        let manager = self.clone();

        tokio::spawn(async move {
            manager.process_queue_items(callback).await;
        });

        Ok(())
    }

    /// 停止批量处理
    pub async fn stop_batch_processing(&self) -> Result<()> {
        let mut is_running = self.is_running.lock().await;
        *is_running = false;
        
        let mut batch_progress = self.batch_progress.lock().await;
        batch_progress.is_running = false;
        
        Ok(())
    }

    /// 获取队列状态
    pub async fn get_queue_status(&self) -> (usize, usize, usize, usize) {
        let queue = self.queue.lock().await;
        let total = queue.len();
        let pending = queue.iter().filter(|item| item.status == QueueItemStatus::Pending).count();
        let processing = queue.iter().filter(|item| item.status == QueueItemStatus::Processing).count();
        let completed = queue.iter().filter(|item| item.status == QueueItemStatus::Completed).count();
        
        (total, pending, processing, completed)
    }

    /// 获取批量导入进度
    pub async fn get_batch_progress(&self) -> BatchImportProgress {
        let batch_progress = self.batch_progress.lock().await;
        batch_progress.clone()
    }

    /// 清空队列
    pub async fn clear_queue(&self) -> Result<()> {
        let mut queue = self.queue.lock().await;
        queue.clear();
        
        let mut progress_map = self.progress_map.lock().await;
        progress_map.clear();
        
        Ok(())
    }

    /// 处理队列项目
    async fn process_queue_items(&self, callback: Option<BatchImportEventCallback>) {
        let mut completed_count = 0;
        let mut failed_count = 0;
        let total_count = {
            let queue = self.queue.lock().await;
            queue.len()
        };

        loop {
            // 检查是否应该停止
            let should_stop = {
                let is_running = self.is_running.lock().await;
                !*is_running
            };
            
            if should_stop {
                break;
            }

            // 获取下一个待处理项目
            let next_item = {
                let mut queue = self.queue.lock().await;
                queue.iter_mut()
                    .find(|item| item.status == QueueItemStatus::Pending)
                    .map(|item| {
                        item.status = QueueItemStatus::Processing;
                        item.clone()
                    })
            };

            let item = match next_item {
                Some(item) => item,
                None => break, // 没有更多待处理项目
            };

            // 获取信号量许可
            let permit = self.semaphore.acquire().await.unwrap();

            // 更新当前处理项目
            {
                let mut batch_progress = self.batch_progress.lock().await;
                batch_progress.current_item = Some(item.file_path.clone());
            }

            if let Some(callback) = &callback {
                callback(BatchImportEvent::ItemStarted { 
                    item_id: item.id.clone(), 
                    file_path: item.file_path.clone() 
                });
            }

            // 处理单个项目
            let import_request = ImportTemplateRequest {
                file_path: item.file_path.clone(),
                template_name: item.template_name.clone(),
                project_id: item.project_id.clone(),
                auto_upload: item.auto_upload,
            };

            let result = self.import_service.import_template(import_request, None).await;

            // 更新项目状态
            {
                let mut queue = self.queue.lock().await;
                if let Some(queue_item) = queue.iter_mut().find(|i| i.id == item.id) {
                    match &result {
                        Ok(template_id) => {
                            queue_item.status = QueueItemStatus::Completed;
                            completed_count += 1;
                            
                            if let Some(callback) = &callback {
                                callback(BatchImportEvent::ItemCompleted { 
                                    item_id: item.id.clone(), 
                                    template_id: template_id.clone() 
                                });
                            }
                        }
                        Err(e) => {
                            queue_item.status = QueueItemStatus::Failed;
                            queue_item.error_message = Some(e.to_string());
                            failed_count += 1;
                            
                            if let Some(callback) = &callback {
                                callback(BatchImportEvent::ItemFailed { 
                                    item_id: item.id.clone(), 
                                    error: e.to_string() 
                                });
                            }
                        }
                    }
                }
            }

            // 更新批量进度
            {
                let mut batch_progress = self.batch_progress.lock().await;
                batch_progress.completed_items = completed_count;
                batch_progress.failed_items = failed_count;
                batch_progress.overall_progress = 
                    ((completed_count + failed_count) as f64 / total_count as f64) * 100.0;
                
                if let Some(callback) = &callback {
                    callback(BatchImportEvent::Progress { 
                        progress: batch_progress.clone() 
                    });
                }
            }

            drop(permit); // 释放信号量许可
        }

        // 完成批量处理
        {
            let mut batch_progress = self.batch_progress.lock().await;
            batch_progress.is_running = false;
            batch_progress.current_item = None;
        }

        {
            let mut is_running = self.is_running.lock().await;
            *is_running = false;
        }

        if let Some(callback) = &callback {
            callback(BatchImportEvent::Completed { 
                total: total_count, 
                completed: completed_count, 
                failed: failed_count 
            });
        }
    }

    /// 扫描文件夹中的draft_content.json文件
    async fn scan_draft_files(&self, folder_path: &Path) -> Result<Vec<PathBuf>> {
        let folder_path = folder_path.to_path_buf();

        tokio::task::spawn_blocking(move || {
            Self::scan_draft_files_sync(&folder_path)
        }).await?
    }

    /// 同步版本的文件扫描，避免递归async问题
    pub fn scan_draft_files_sync(folder_path: &Path) -> Result<Vec<PathBuf>> {
        let mut draft_files = Vec::new();

        if !folder_path.exists() || !folder_path.is_dir() {
            return Ok(draft_files);
        }

        let entries = std::fs::read_dir(folder_path)?;

        for entry in entries {
            let entry = entry?;
            let path = entry.path();

            if path.is_file() && path.file_name() == Some(std::ffi::OsStr::new("draft_content.json")) {
                draft_files.push(path);
            } else if path.is_dir() {
                // 递归扫描子文件夹
                let sub_files = Self::scan_draft_files_sync(&path)?;
                draft_files.extend(sub_files);
            }
        }

        Ok(draft_files)
    }
}

impl Clone for ImportQueueManager {
    fn clone(&self) -> Self {
        Self {
            database: self.database.clone(),
            import_service: TemplateImportService::new(self.database.clone()),
            queue: self.queue.clone(),
            progress_map: self.progress_map.clone(),
            batch_progress: self.batch_progress.clone(),
            semaphore: self.semaphore.clone(),
            is_running: self.is_running.clone(),
        }
    }
}
