use anyhow::{Result, anyhow};
use std::sync::Arc;
use tokio::sync::Mutex;
use std::collections::HashMap;
use tracing::{info, warn, error, debug};
use std::sync::OnceLock;

use crate::data::models::template::{
    Template, TemplateMaterial, ImportStatus, UploadStatus, ImportProgress,
    ImportTemplateRequest
};
use crate::business::services::draft_parser::{DraftContentParser, ParseResult};
use crate::business::services::cloud_upload_service::CloudUploadService;
use crate::infrastructure::database::Database;

// 全局进度存储
static GLOBAL_PROGRESS_MAP: OnceLock<Arc<Mutex<HashMap<String, ImportProgress>>>> = OnceLock::new();

/// 获取全局进度存储
fn get_global_progress_map() -> &'static Arc<Mutex<HashMap<String, ImportProgress>>> {
    GLOBAL_PROGRESS_MAP.get_or_init(|| {
        Arc::new(Mutex::new(HashMap::new()))
    })
}

/// 模板导入服务
/// 遵循 Tauri 开发规范的业务逻辑设计原则
pub struct TemplateImportService {
    database: Arc<Database>,
    upload_service: CloudUploadService,
    progress_map: Arc<Mutex<HashMap<String, ImportProgress>>>,
}

/// 导入事件类型
#[derive(Debug, Clone)]
pub enum ImportEvent {
    Started { template_id: String, template_name: String },
    Parsing { template_id: String },
    Uploading { template_id: String, current: u32, total: u32 },
    Processing { template_id: String },
    Completed { template_id: String },
    Failed { template_id: String, error: String },
    Progress { template_id: String, progress: ImportProgress },
}

/// 导入事件回调
pub type ImportEventCallback = Box<dyn Fn(ImportEvent) + Send + Sync>;

impl TemplateImportService {
    /// 创建新的模板导入服务实例
    pub fn new(database: Arc<Database>) -> Self {
        Self {
            database,
            upload_service: CloudUploadService::new(),
            progress_map: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    /// 使用自定义上传服务创建实例
    pub fn with_upload_service(database: Arc<Database>, upload_service: CloudUploadService) -> Self {
        Self {
            database,
            upload_service,
            progress_map: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    /// 导入单个模板
    pub async fn import_template(
        &self,
        request: ImportTemplateRequest,
        callback: Option<ImportEventCallback>,
    ) -> Result<String> {
        let template_name = request.template_name.as_deref().unwrap_or("未命名");
        let project_id = request.project_id.as_deref().unwrap_or("无");
        info!(
            template_name = %template_name,
            file_path = %request.file_path,
            project_id = %project_id,
            auto_upload = %request.auto_upload,
            "开始导入模板"
        );
        // 第一步：解析剪映草稿文件
        info!("开始解析剪映草稿文件: {}", request.file_path);
        let parse_result = match self.parse_draft_file(&request, &callback).await {
            Ok(result) => {
                info!(
                    materials_count = %result.template.materials.len(),
                    tracks_count = %result.template.tracks.len(),
                    missing_files_count = %result.missing_files.len(),
                    warnings_count = %result.warnings.len(),
                    "草稿文件解析成功"
                );
                if !result.missing_files.is_empty() {
                    warn!("发现缺失文件: {:?}", result.missing_files);
                }
                if !result.warnings.is_empty() {
                    warn!("解析警告: {:?}", result.warnings);
                }
                result
            }
            Err(e) => {
                error!("草稿文件解析失败: {}", e);
                return Err(e);
            }
        };
        let mut template = parse_result.template;

        // 添加详细的解析结果日志
        info!(
            template_id = %template.id,
            template_name = %template.name,
            materials_count = %template.materials.len(),
            tracks_count = %template.tracks.len(),
            missing_files_count = %parse_result.missing_files.len(),
            warnings_count = %parse_result.warnings.len(),
            "草稿文件解析完成"
        );

        // 如果有警告，记录详细信息
        if !parse_result.warnings.is_empty() {
            for warning in &parse_result.warnings {
                warn!("解析警告: {}", warning);
            }
        }

        // 如果有缺失文件，记录详细信息
        if !parse_result.missing_files.is_empty() {
            for missing_file in &parse_result.missing_files {
                warn!("缺失文件: {}", missing_file);
            }
        }

        // 初始化进度跟踪
        let progress = ImportProgress {
            template_id: template.id.clone(),
            template_name: template.name.clone(),
            status: ImportStatus::Parsing,
            total_materials: template.materials.len() as u32,
            uploaded_materials: 0,
            failed_materials: 0,
            current_operation: "解析完成，准备上传素材".to_string(),
            error_message: None,
            progress_percentage: 10.0,
        };
        self.update_progress(&template.id, progress.clone()).await;
        
        if let Some(callback) = &callback {
            callback(ImportEvent::Progress { 
                template_id: template.id.clone(), 
                progress: progress.clone() 
            });
        }

        // 第二步：上传素材文件（如果启用自动上传）
        if request.auto_upload {
            info!("开始上传素材文件");
            match self.upload_materials(&mut template, &callback).await {
                Ok(_) => {
                    let uploaded_count = template.materials.iter()
                        .filter(|m| matches!(m.upload_status, UploadStatus::Completed))
                        .count();
                    let skipped_count = template.materials.iter()
                        .filter(|m| matches!(m.upload_status, UploadStatus::Skipped))
                        .count();
                    info!(
                        uploaded_count = %uploaded_count,
                        skipped_count = %skipped_count,
                        total_count = %template.materials.len(),
                        "素材上传完成"
                    );
                }
                Err(e) => {
                    error!("素材上传失败: {}", e);
                    return Err(e);
                }
            }
        } else {
            info!("跳过素材上传，将所有素材标记为跳过");
            // 如果不自动上传，将所有素材标记为跳过
            for material in &mut template.materials {
                material.update_upload_status(UploadStatus::Skipped, None);
            }
        }

        // 第三步：保存到数据库
        info!(
            template_id = %template.id,
            template_name = %template.name,
            "开始保存模板到数据库"
        );
        template.update_import_status(ImportStatus::Processing);
        match self.save_template_to_database(&template, &callback).await {
            Ok(_) => {
                info!(
                    template_id = %template.id,
                    template_name = %template.name,
                    "模板保存到数据库成功"
                );
            }
            Err(e) => {
                error!(
                    template_id = %template.id,
                    template_name = %template.name,
                    error = %e,
                    "模板保存到数据库失败"
                );
                return Err(e);
            }
        }

        // 第四步：完成导入
        template.update_import_status(ImportStatus::Completed);
        self.update_template_status(&template.id, ImportStatus::Completed).await?;

        info!(
            template_id = %template.id,
            template_name = %template.name,
            duration_ms = %template.duration,
            "模板导入完成"
        );

        let final_progress = ImportProgress {
            template_id: template.id.clone(),
            template_name: template.name.clone(),
            status: ImportStatus::Completed,
            total_materials: template.materials.len() as u32,
            uploaded_materials: template.materials.iter()
                .filter(|m| matches!(m.upload_status, UploadStatus::Completed | UploadStatus::Skipped))
                .count() as u32,
            failed_materials: template.materials.iter()
                .filter(|m| matches!(m.upload_status, UploadStatus::Failed))
                .count() as u32,
            current_operation: "导入完成".to_string(),
            error_message: None,
            progress_percentage: 100.0,
        };
        self.update_progress(&template.id, final_progress.clone()).await;

        if let Some(callback) = &callback {
            callback(ImportEvent::Completed { template_id: template.id.clone() });
            callback(ImportEvent::Progress { 
                template_id: template.id.clone(), 
                progress: final_progress 
            });
        }

        Ok(template.id)
    }

    /// 获取导入进度
    pub async fn get_import_progress(&self, template_id: &str) -> Option<ImportProgress> {
        // 优先从全局存储获取，如果没有再从本地获取
        let global_progress_map = get_global_progress_map();
        let global_map = global_progress_map.lock().await;
        if let Some(progress) = global_map.get(template_id) {
            return Some(progress.clone());
        }

        // 如果全局存储没有，从本地获取
        let progress_map = self.progress_map.lock().await;
        progress_map.get(template_id).cloned()
    }

    /// 清除导入进度
    pub async fn clear_import_progress(&self, template_id: &str) {
        // 从全局存储清除
        let global_progress_map = get_global_progress_map();
        let mut global_map = global_progress_map.lock().await;
        global_map.remove(template_id);

        // 从本地存储清除
        let mut progress_map = self.progress_map.lock().await;
        progress_map.remove(template_id);
    }

    /// 取消导入
    pub async fn cancel_import(&self, template_id: &str) -> Result<()> {
        // 更新状态为失败
        self.update_template_status(template_id, ImportStatus::Failed).await?;
        
        // 清理进度信息
        let mut progress_map = self.progress_map.lock().await;
        progress_map.remove(template_id);
        
        Ok(())
    }

    /// 解析剪映草稿文件
    async fn parse_draft_file(
        &self,
        request: &ImportTemplateRequest,
        callback: &Option<ImportEventCallback>,
    ) -> Result<ParseResult> {
        if let Some(callback) = callback {
            callback(ImportEvent::Started { 
                template_id: "parsing".to_string(), 
                template_name: request.template_name.clone().unwrap_or_else(|| "未命名模板".to_string())
            });
        }

        let parse_result = DraftContentParser::parse_file(
            &request.file_path,
            request.template_name.clone(),
        )?;

        // 验证解析结果
        let validation_errors = DraftContentParser::validate_result(&parse_result);
        if !validation_errors.is_empty() {
            return Err(anyhow!("模板验证失败: {}", validation_errors.join(", ")));
        }

        Ok(ParseResult {
            template: parse_result.template,
            missing_files: parse_result.missing_files,
            warnings: parse_result.warnings,
        })
    }

    /// 上传素材文件
    async fn upload_materials(
        &self,
        template: &mut Template,
        callback: &Option<ImportEventCallback>,
    ) -> Result<()> {
        template.update_import_status(ImportStatus::Uploading);
        
        if let Some(callback) = callback {
            callback(ImportEvent::Uploading { 
                template_id: template.id.clone(),
                current: 0,
                total: template.materials.len() as u32,
            });
        }

        let total_materials = template.materials.len();
        let mut uploaded_count = 0;

        for (index, material) in template.materials.iter_mut().enumerate() {
            // 更新文件存在状态
            material.update_file_exists();

            // 跳过没有文件路径的素材（如文本、画布等）
            if material.original_path.is_empty() || !material.file_exists {
                material.upload_success = false;
                material.update_upload_status(UploadStatus::Skipped, None);
                continue;
            }

            // 只上传视频/音频/图片文件，跳过其他类型
            if !Self::should_upload_material(material) {
                material.update_upload_status(UploadStatus::Skipped, None);
                debug!(
                    material_name = %material.name,
                    material_type = ?material.material_type,
                    "跳过非媒体文件上传"
                );
                continue;
            }

            // 更新进度
            let progress = ImportProgress {
                template_id: template.id.clone(),
                template_name: template.name.clone(),
                status: ImportStatus::Uploading,
                total_materials: total_materials as u32,
                uploaded_materials: uploaded_count,
                failed_materials: 0, // 不再跟踪失败数量，因为失败会被标记为跳过
                current_operation: format!("上传素材: {}", material.name),
                error_message: None,
                progress_percentage: 20.0 + (index as f64 / total_materials as f64) * 60.0,
            };
            self.update_progress(&template.id, progress.clone()).await;

            if let Some(callback) = callback {
                callback(ImportEvent::Progress { 
                    template_id: template.id.clone(), 
                    progress 
                });
            }

            // 上传文件
            material.update_upload_status(UploadStatus::Uploading, None);
            
            debug!(
                material_name = %material.name,
                file_path = %material.original_path,
                "开始上传素材文件"
            );

            match self.upload_service.upload_file(&material.original_path, None, None).await {
                Ok(upload_result) => {
                    if upload_result.success {
                        material.update_upload_status(
                            UploadStatus::Completed,
                            upload_result.remote_url.clone()
                        );
                        material.update_upload_success(true);
                        material.file_size = Some(upload_result.file_size);
                        uploaded_count += 1;
                        info!(
                            material_name = %material.name,
                            file_size = %upload_result.file_size,
                            remote_url = ?upload_result.remote_url,
                            "素材上传成功"
                        );
                    } else {
                        // 上传失败时标记为跳过，不影响整体导入
                        material.update_upload_success(false);
                        material.update_upload_status(UploadStatus::Skipped, None);
                        warn!(
                            material_name = %material.name,
                            error = ?upload_result.error_message,
                            "素材上传失败，已跳过"
                        );
                    }
                }
                Err(e) => {
                    // 上传异常时标记为跳过，不影响整体导入
                    material.update_upload_success(false);
                    material.update_upload_status(UploadStatus::Skipped, None);
                    warn!(
                        material_name = %material.name,
                        error = %e,
                        "素材上传异常，已跳过"
                    );
                }
            }

            if let Some(callback) = callback {
                callback(ImportEvent::Uploading { 
                    template_id: template.id.clone(),
                    current: (index + 1) as u32,
                    total: total_materials as u32,
                });
            }
        }

        Ok(())
    }

    /// 判断素材是否应该上传
    fn should_upload_material(material: &TemplateMaterial) -> bool {
        use crate::data::models::template::TemplateMaterialType;

        match material.material_type {
            TemplateMaterialType::Video => true,
            TemplateMaterialType::Audio => true,
            TemplateMaterialType::Image => true,
            // 跳过文本、特效、画布等类型
            TemplateMaterialType::Text => false,
            TemplateMaterialType::Effect => false,
            TemplateMaterialType::Canvas => false,
            TemplateMaterialType::Sticker => false,
            TemplateMaterialType::Other(_) => false,
        }
    }

    /// 保存模板到数据库
    async fn save_template_to_database(
        &self,
        template: &Template,
        callback: &Option<ImportEventCallback>,
    ) -> Result<()> {
        if let Some(callback) = callback {
            callback(ImportEvent::Processing { template_id: template.id.clone() });
        }

        let progress = ImportProgress {
            template_id: template.id.clone(),
            template_name: template.name.clone(),
            status: ImportStatus::Processing,
            total_materials: template.materials.len() as u32,
            uploaded_materials: template.materials.iter()
                .filter(|m| matches!(m.upload_status, UploadStatus::Completed | UploadStatus::Skipped))
                .count() as u32,
            failed_materials: template.materials.iter()
                .filter(|m| matches!(m.upload_status, UploadStatus::Failed))
                .count() as u32,
            current_operation: "保存到数据库".to_string(),
            error_message: None,
            progress_percentage: 90.0,
        };
        self.update_progress(&template.id, progress.clone()).await;

        if let Some(callback) = callback {
            callback(ImportEvent::Progress {
                template_id: template.id.clone(),
                progress
            });
        }

        // 使用模板服务保存到数据库
        use crate::business::services::template_service::TemplateService;
        let template_service = TemplateService::new(self.database.clone());
        template_service.save_template(template).await?;

        Ok(())
    }

    /// 更新模板状态
    async fn update_template_status(&self, template_id: &str, status: ImportStatus) -> Result<()> {
        use rusqlite::params;

        let conn = self.database.get_connection();
        let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?;

        let status_str = format!("{:?}", status);

        conn.execute(
            "UPDATE templates SET import_status = ?, updated_at = datetime('now') WHERE id = ?",
            params![status_str, template_id],
        ).map_err(|e| anyhow!("更新模板状态失败: {}", e))?;

        info!(
            template_id = %template_id,
            status = %status_str,
            "模板状态已更新到数据库"
        );

        Ok(())
    }

    /// 更新进度信息
    async fn update_progress(&self, template_id: &str, progress: ImportProgress) {
        // 同时更新本地和全局进度存储
        let mut local_progress_map = self.progress_map.lock().await;
        local_progress_map.insert(template_id.to_string(), progress.clone());

        let global_progress_map = get_global_progress_map();
        let mut global_map = global_progress_map.lock().await;
        global_map.insert(template_id.to_string(), progress);
    }
}
