use anyhow::{Result, anyhow};
use std::sync::Arc;
use std::time::Instant;
use tracing::{info, warn, error, debug};

use crate::data::models::watermark::{
    BatchWatermarkTask, WatermarkOperation, BatchTaskStatus, BatchProgress,
    WatermarkProcessingResult, WatermarkConfig, WatermarkRemovalConfig,
    WatermarkDetectionConfig
};
use crate::data::repositories::material_repository::MaterialRepository;
use crate::business::services::{
    watermark_detection_service::WatermarkDetectionService,
    watermark_removal_service::WatermarkRemovalService,
    watermark_addition_service::WatermarkAdditionService,
    task_manager::TASK_MANAGER,
};
// use crate::infrastructure::event_bus::EventBusManager;
use crate::infrastructure::monitoring::PERFORMANCE_MONITOR;

/// 批量水印处理器
/// 遵循 Tauri 开发规范的异步业务逻辑层设计
pub struct BatchWatermarkProcessor;

impl BatchWatermarkProcessor {
    /// 启动批量水印处理任务
    pub async fn start_batch_task(
        task: BatchWatermarkTask,
        repository: Arc<MaterialRepository>,
    ) -> Result<()> {
        let _timer = PERFORMANCE_MONITOR.start_operation("batch_watermark_processing");
        let start_time = Instant::now();

        info!(
            task_id = %task.task_id,
            operation = ?task.operation,
            material_count = task.material_ids.len(),
            "开始批量水印处理任务"
        );

        // 将任务添加到任务管理器
        TASK_MANAGER.add_task(task.clone())?;

        // 更新任务状态为运行中
        TASK_MANAGER.update_task_status(&task.task_id, BatchTaskStatus::Running)?;

        // TODO: 发布任务开始事件

        let mut progress = BatchProgress {
            total_items: task.material_ids.len() as u32,
            processed_items: 0,
            failed_items: 0,
            current_item: None,
            progress_percentage: 0.0,
            estimated_remaining_ms: None,
            errors: Vec::new(),
            detection_results: Vec::new(),
            processing_results: Vec::new(),
        };

        let mut results = Vec::new();

        // 处理每个素材
        for (index, material_id) in task.material_ids.iter().enumerate() {
            progress.current_item = Some(material_id.clone());
            progress.progress_percentage = (index as f32 / task.material_ids.len() as f32) * 100.0;

            // 更新任务管理器中的进度
            TASK_MANAGER.update_task_progress(&task.task_id, progress.clone())?;

            // TODO: 发布进度更新事件

            debug!(
                task_id = %task.task_id,
                material_id = %material_id,
                progress = progress.progress_percentage,
                "处理素材"
            );

            // 处理单个素材
            let result = Self::process_single_material(
                material_id,
                &task.operation,
                &task.config,
                repository.clone(),
            ).await;

            match result {
                Ok(processing_result) => {
                    if processing_result.success {
                        progress.processed_items += 1;

                        // 如果是检测操作，提取检测结果
                        if task.operation == WatermarkOperation::Detect {
                            if let Some(metadata) = &processing_result.metadata {
                                if let Ok(detection_result) = serde_json::from_value::<crate::data::models::watermark::WatermarkDetectionResult>(metadata.clone()) {
                                    progress.detection_results.push(detection_result);
                                }
                            }
                        }

                        // 添加处理结果
                        progress.processing_results.push(processing_result.clone());

                        info!(
                            task_id = %task.task_id,
                            material_id = %material_id,
                            "素材处理成功"
                        );
                    } else {
                        progress.failed_items += 1;
                        if let Some(error) = &processing_result.error_message {
                            progress.errors.push(format!("{}: {}", material_id, error));
                        }
                        warn!(
                            task_id = %task.task_id,
                            material_id = %material_id,
                            error = ?processing_result.error_message,
                            "素材处理失败"
                        );
                    }
                    results.push(processing_result);
                }
                Err(e) => {
                    progress.failed_items += 1;
                    progress.errors.push(format!("{}: {}", material_id, e));
                    error!(
                        task_id = %task.task_id,
                        material_id = %material_id,
                        error = %e,
                        "素材处理异常"
                    );
                }
            }

            // 计算预估剩余时间
            if index > 0 {
                let elapsed = start_time.elapsed().as_millis() as u64;
                let avg_time_per_item = elapsed / (index + 1) as u64;
                let remaining_items = task.material_ids.len() - index - 1;
                progress.estimated_remaining_ms = Some(avg_time_per_item * remaining_items as u64);
            }

            // 更新处理后的进度
            progress.progress_percentage = ((index + 1) as f32 / task.material_ids.len() as f32) * 100.0;
            TASK_MANAGER.update_task_progress(&task.task_id, progress.clone())?;
        }

        // 完成处理
        progress.current_item = None;
        progress.progress_percentage = 100.0;
        progress.estimated_remaining_ms = Some(0);

        let final_status = if progress.failed_items == 0 {
            BatchTaskStatus::Completed
        } else if progress.processed_items == 0 {
            BatchTaskStatus::Failed
        } else {
            BatchTaskStatus::Completed // 部分成功也算完成
        };

        // 更新最终状态
        TASK_MANAGER.update_task_status(&task.task_id, final_status.clone())?;
        TASK_MANAGER.update_task_progress(&task.task_id, progress.clone())?;

        let processing_time = start_time.elapsed().as_millis() as u64;

        // TODO: 发布任务完成事件

        info!(
            task_id = %task.task_id,
            processed_items = progress.processed_items,
            failed_items = progress.failed_items,
            processing_time_ms = processing_time,
            "批量水印处理任务完成"
        );

        Ok(())
    }

    /// 处理单个素材
    async fn process_single_material(
        material_id: &str,
        operation: &WatermarkOperation,
        config: &serde_json::Value,
        repository: Arc<MaterialRepository>,
    ) -> Result<WatermarkProcessingResult> {
        // 获取素材信息
        let material = repository.get_by_id(material_id)?
            .ok_or_else(|| anyhow!("素材不存在: {}", material_id))?;

        let input_path = &material.original_path;
        let output_dir = Self::get_output_directory(&material.project_id, operation);
        std::fs::create_dir_all(&output_dir)?;

        let output_filename = Self::generate_output_filename(&material.name, operation);
        let output_path = format!("{}/{}", output_dir, output_filename);

        match operation {
            WatermarkOperation::Detect => {
                let detection_config: WatermarkDetectionConfig = serde_json::from_value(config.clone())?;
                
                let detection_result = if format!("{:?}", material.material_type).to_lowercase().contains("video") {
                    WatermarkDetectionService::detect_watermarks_in_video(
                        material_id,
                        input_path,
                        &detection_config,
                        repository.clone(),
                    ).await?
                } else {
                    WatermarkDetectionService::detect_watermarks_in_image(
                        material_id,
                        input_path,
                        &detection_config,
                    ).await?
                };

                // 保存检测结果到数据库
                Self::save_detection_result(&detection_result, &repository).await?;

                Ok(WatermarkProcessingResult {
                    material_id: material_id.to_string(),
                    operation: operation.clone(),
                    success: true,
                    output_path: None, // 检测不产生输出文件
                    processing_time_ms: detection_result.processing_time_ms,
                    error_message: None,
                    metadata: Some(serde_json::to_value(detection_result)?),
                })
            }
            WatermarkOperation::Remove => {
                let removal_config: WatermarkRemovalConfig = serde_json::from_value(config.clone())?;
                
                if format!("{:?}", material.material_type).to_lowercase().contains("video") {
                    WatermarkRemovalService::remove_watermarks_from_video(
                        material_id,
                        input_path,
                        &output_path,
                        &removal_config,
                        repository.clone(),
                    ).await
                } else {
                    WatermarkRemovalService::remove_watermarks_from_image(
                        material_id,
                        input_path,
                        &output_path,
                        &removal_config,
                    ).await
                }
            }
            WatermarkOperation::Add => {
                let watermark_config: WatermarkConfig = serde_json::from_value(config.clone())?;
                let watermark_path = Self::get_watermark_path_from_config(&watermark_config)?;
                
                if format!("{:?}", material.material_type).to_lowercase().contains("video") {
                    WatermarkAdditionService::add_watermark_to_video(
                        material_id,
                        input_path,
                        &output_path,
                        &watermark_path,
                        &watermark_config,
                        repository.clone(),
                    ).await
                } else {
                    WatermarkAdditionService::add_watermark_to_image(
                        material_id,
                        input_path,
                        &output_path,
                        &watermark_path,
                        &watermark_config,
                    ).await
                }
            }
            WatermarkOperation::DetectAndRemove => {
                // 先检测，再移除
                let detection_config: WatermarkDetectionConfig = serde_json::from_value(
                    config.get("detection").unwrap_or(&serde_json::Value::Null).clone()
                )?;
                let removal_config: WatermarkRemovalConfig = serde_json::from_value(
                    config.get("removal").unwrap_or(&serde_json::Value::Null).clone()
                )?;

                // 执行检测
                let detection_result = if format!("{:?}", material.material_type).to_lowercase().contains("video") {
                    WatermarkDetectionService::detect_watermarks_in_video(
                        material_id,
                        input_path,
                        &detection_config,
                        repository.clone(),
                    ).await?
                } else {
                    WatermarkDetectionService::detect_watermarks_in_image(
                        material_id,
                        input_path,
                        &detection_config,
                    ).await?
                };

                // 保存检测结果
                Self::save_detection_result(&detection_result, &repository).await?;

                // 如果检测到水印，则执行移除
                if !detection_result.detections.is_empty() {
                    if format!("{:?}", material.material_type).to_lowercase().contains("video") {
                        WatermarkRemovalService::remove_watermarks_from_video(
                            material_id,
                            input_path,
                            &output_path,
                            &removal_config,
                            repository.clone(),
                        ).await
                    } else {
                        WatermarkRemovalService::remove_watermarks_from_image(
                            material_id,
                            input_path,
                            &output_path,
                            &removal_config,
                        ).await
                    }
                } else {
                    Ok(WatermarkProcessingResult {
                        material_id: material_id.to_string(),
                        operation: operation.clone(),
                        success: true,
                        output_path: None,
                        processing_time_ms: detection_result.processing_time_ms,
                        error_message: None,
                        metadata: Some(serde_json::json!({
                            "message": "未检测到水印，无需移除"
                        })),
                    })
                }
            }
            WatermarkOperation::Replace => {
                // TODO: 实现替换逻辑（检测 + 移除 + 添加）
                Err(anyhow!("替换操作尚未实现"))
            }
        }
    }



    /// 保存检测结果
    async fn save_detection_result(
        result: &crate::data::models::watermark::WatermarkDetectionResult,
        _repository: &MaterialRepository,
    ) -> Result<()> {
        // TODO: 实现检测结果保存逻辑
        debug!(
            material_id = %result.material_id,
            detection_count = result.detections.len(),
            "保存检测结果"
        );
        Ok(())
    }

    /// 获取输出目录
    fn get_output_directory(project_id: &str, operation: &WatermarkOperation) -> String {
        let operation_name = match operation {
            WatermarkOperation::Detect => "detection",
            WatermarkOperation::Remove => "watermark_removed",
            WatermarkOperation::Add => "watermark_added",
            WatermarkOperation::DetectAndRemove => "watermark_removed",
            WatermarkOperation::Replace => "watermark_replaced",
        };
        
        format!("projects/{}/output/{}", project_id, operation_name)
    }

    /// 生成输出文件名
    fn generate_output_filename(original_filename: &str, operation: &WatermarkOperation) -> String {
        let operation_suffix = match operation {
            WatermarkOperation::Detect => return original_filename.to_string(), // 检测不产生文件
            WatermarkOperation::Remove => "_no_watermark",
            WatermarkOperation::Add => "_watermarked",
            WatermarkOperation::DetectAndRemove => "_no_watermark",
            WatermarkOperation::Replace => "_watermark_replaced",
        };

        if let Some(dot_index) = original_filename.rfind('.') {
            let (name, ext) = original_filename.split_at(dot_index);
            format!("{}{}{}", name, operation_suffix, ext)
        } else {
            format!("{}{}", original_filename, operation_suffix)
        }
    }

    /// 从配置中获取水印路径
    fn get_watermark_path_from_config(_config: &WatermarkConfig) -> Result<String> {
        // TODO: 根据水印类型和配置获取实际的水印文件路径
        // 这里需要与水印模板管理系统集成
        Ok("watermarks/default.png".to_string())
    }
}
