use anyhow::{Result, anyhow};
use std::path::Path;
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::{info, warn, error};
use tauri::{AppHandle, Emitter};

use crate::config::AppConfig;
use crate::data::models::outfit_photo_generation::{
    OutfitPhotoGeneration, OutfitPhotoGenerationRequest, OutfitPhotoGenerationResponse,
    GenerationStatus, WorkflowProgress, WorkflowConfig
};
use crate::data::repositories::outfit_photo_generation_repository::OutfitPhotoGenerationRepository;
use crate::data::repositories::model_repository::ModelRepository;
use crate::business::services::comfyui_service::ComfyUIService;
use crate::business::services::cloud_upload_service::CloudUploadService;
use crate::infrastructure::database::Database;

/// 穿搭照片生成服务
/// 遵循 Tauri 开发规范的业务逻辑设计原则
pub struct OutfitPhotoGenerationService {
    repository: OutfitPhotoGenerationRepository,
    model_repository: ModelRepository,
    config: Arc<Mutex<AppConfig>>,
    cloud_upload_service: Arc<CloudUploadService>,
}

impl OutfitPhotoGenerationService {
    /// 创建新的穿搭照片生成服务实例
    pub fn new(
        database: Arc<Database>,
        config: Arc<Mutex<AppConfig>>,
        cloud_upload_service: Arc<CloudUploadService>,
    ) -> Result<Self> {
        let repository = OutfitPhotoGenerationRepository::new(database.clone())?;
        let model_repository = ModelRepository::new(database);

        Ok(Self {
            repository,
            model_repository,
            config,
            cloud_upload_service,
        })
    }

    /// 创建穿搭照片生成任务
    pub async fn create_generation_task(
        &self,
        request: OutfitPhotoGenerationRequest,
    ) -> Result<OutfitPhotoGeneration> {
        let mut generation = OutfitPhotoGeneration::new(
            request.project_id,
            request.model_id,
            request.product_image_path,
            request.prompt,
        );

        generation.negative_prompt = request.negative_prompt;

        // 保存到数据库
        self.save_generation_record(&generation).await?;

        info!("创建穿搭照片生成任务: {}", generation.id);
        Ok(generation)
    }

    /// 执行穿搭照片生成
    pub async fn execute_generation<F>(
        &self,
        generation_id: &str,
        progress_callback: F,
    ) -> Result<OutfitPhotoGenerationResponse>
    where
        F: FnMut(WorkflowProgress) + Send + 'static,
    {
        let mut generation = self.get_generation_record(generation_id).await?;
        
        // 检查 ComfyUI 是否启用
        let config = self.config.lock().await;
        if !config.is_comfyui_enabled() {
            return Err(anyhow!("ComfyUI 功能未启用"));
        }

        let comfyui_service = ComfyUIService::new(config.get_comfyui_settings().clone());
        drop(config);

        // 更新状态为处理中
        generation.update_status(GenerationStatus::Processing);
        self.update_generation_record(&generation).await?;

        // 检查 ComfyUI 连接
        if !comfyui_service.check_connection().await? {
            generation.set_error("ComfyUI 服务器连接失败".to_string());
            self.update_generation_record(&generation).await?;
            return Ok(self.create_response(&generation));
        }

        // 上传商品图片到云端
        let product_image_url = match self.upload_product_image(&generation.product_image_path).await {
            Ok(url) => {
                generation.product_image_url = Some(url.clone());
                self.update_generation_record(&generation).await?;
                url
            }
            Err(e) => {
                generation.set_error(format!("上传商品图片失败: {}", e));
                self.update_generation_record(&generation).await?;
                return Ok(self.create_response(&generation));
            }
        };

        // 获取模特图片URL
        let model_image_url = match self.get_model_image_url(&generation.model_id).await {
            Ok(url) => url,
            Err(e) => {
                generation.set_error(format!("获取模特图片失败: {}", e));
                self.update_generation_record(&generation).await?;
                return Ok(self.create_response(&generation));
            }
        };

        // 获取工作流配置
        let workflow_config = self.get_default_workflow_config().await?;
        
        // 执行 ComfyUI 工作流并自动上传结果
        let remote_key_prefix = format!("outfit-photos/{}/{}", generation.project_id, generation.id);

        match comfyui_service.execute_workflow_with_upload_indexed_with_prompt_id(
            &self.cloud_upload_service,
            &workflow_config.workflow_file_path,
            &model_image_url,
            &product_image_url,
            &generation.prompt,
            generation.negative_prompt.as_deref(),
            Some(&remote_key_prefix),
            progress_callback,
            None, // product_index
        ).await {
            Ok((prompt_id, upload_results)) => {
                // 保存 ComfyUI prompt_id
                generation.set_comfyui_prompt_id(prompt_id.clone());
                info!("✅ 已保存 ComfyUI prompt_id: {} 到生成记录: {}", prompt_id, generation.id);

                // 处理上传结果
                let mut successful_uploads = 0;

                for upload_result in upload_results {
                    if upload_result.success {
                        if let Some(remote_url) = upload_result.remote_url {
                            generation.result_image_urls.push(remote_url.clone());
                            successful_uploads += 1;
                        }
                    } else {
                        warn!("图片上传失败: {}", upload_result.error_message.unwrap_or_default());
                    }
                }

                if successful_uploads == 0 {
                    generation.set_error("所有图片上传失败".to_string());
                } else {
                    generation.update_status(GenerationStatus::Completed);
                    info!("成功上传 {} 张图片", successful_uploads);
                }
            }
            Err(e) => {
                generation.set_error(format!("ComfyUI 工作流执行或上传失败: {}", e));
            }
        }

        // 更新数据库记录
        self.update_generation_record(&generation).await?;

        Ok(self.create_response(&generation))
    }

    /// 生成穿搭照片（创建任务并执行）
    pub async fn generate_outfit_photo<F>(
        &self,
        request: OutfitPhotoGenerationRequest,
        progress_callback: F,
    ) -> Result<OutfitPhotoGenerationResponse>
    where
        F: FnMut(WorkflowProgress) + Send + 'static,
    {
        // 创建生成任务
        let generation = self.create_generation_task(request).await?;

        // 执行生成任务
        self.execute_generation(&generation.id, progress_callback).await
    }

    /// 批量生成穿搭照片
    ///
    /// ⚠️ 已弃用：此方法使用基于索引的进度回调，在并发场景下可能导致任务状态更新错乱。
    /// 请使用 `generate_batch_with_prompt_id_callback` 方法，它使用基于 prompt_id 的精确匹配。
    #[deprecated(note = "使用 generate_batch_with_prompt_id_callback 替代")]
    pub async fn generate_batch<F>(
        &self,
        requests: Vec<OutfitPhotoGenerationRequest>,
        progress_callback: F,
    ) -> Result<Vec<OutfitPhotoGenerationResponse>>
    where
        F: Fn(usize, WorkflowProgress) + Send + Sync + 'static,
    {
        let mut responses = Vec::new();
        let total_requests = requests.len();

        info!("开始批量生成穿搭照片，共 {} 个请求", total_requests);

        // 将回调包装在 Arc 中以便在循环中共享
        let callback_arc = Arc::new(progress_callback);

        for (index, request) in requests.into_iter().enumerate() {
            info!("处理批量请求 {}/{}", index + 1, total_requests);

            // 为每个请求创建单独的进度回调
            let callback_clone = Arc::clone(&callback_arc);
            let individual_callback = move |progress: WorkflowProgress| {
                callback_clone(index, progress);
            };

            // 执行单个生成请求
            match self.generate_outfit_photo(request, individual_callback).await {
                Ok(response) => {
                    info!("批量请求 {} 完成", index + 1);
                    responses.push(response);
                }
                Err(e) => {
                    warn!("批量请求 {} 失败: {}", index + 1, e);
                    // 创建失败响应
                    responses.push(OutfitPhotoGenerationResponse {
                        id: format!("batch_error_{}", index),
                        status: GenerationStatus::Failed,
                        result_image_urls: vec![],
                        error_message: Some(e.to_string()),
                        generation_time_ms: None,
                    });
                }
            }

            // 批量处理间隔，避免服务器过载
            if index < total_requests - 1 {
                tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
            }
        }

        info!("批量生成完成，成功: {}/{}",
            responses.iter().filter(|r| r.status == GenerationStatus::Completed).count(),
            total_requests
        );

        Ok(responses)
    }

    /// 批量生成穿搭照片（使用基于 prompt_id 的进度回调）
    pub async fn generate_batch_with_prompt_id_callback<F>(
        &self,
        requests: Vec<OutfitPhotoGenerationRequest>,
        progress_callback: F,
    ) -> Result<Vec<OutfitPhotoGenerationResponse>>
    where
        F: Fn(String, WorkflowProgress) + Send + Sync + 'static,
    {
        let mut responses = Vec::new();
        let total_requests = requests.len();

        info!("开始批量生成穿搭照片（基于 prompt_id），共 {} 个请求", total_requests);

        // 将回调包装在 Arc 中以便在循环中共享
        let callback_arc = Arc::new(progress_callback);

        for (index, request) in requests.into_iter().enumerate() {
            info!("处理批量请求 {}/{}", index + 1, total_requests);

            // 为每个请求创建基于 prompt_id 的进度回调
            let callback_clone = Arc::clone(&callback_arc);
            let individual_callback = move |prompt_id: String, progress: WorkflowProgress| {
                callback_clone(prompt_id, progress);
            };

            // 执行单个生成请求（使用新的方法）
            match self.generate_outfit_photo_with_prompt_id_callback(request, individual_callback).await {
                Ok(response) => {
                    info!("批量请求 {} 完成", index + 1);
                    responses.push(response);
                }
                Err(e) => {
                    warn!("批量请求 {} 失败: {}", index + 1, e);
                    // 创建失败响应
                    responses.push(OutfitPhotoGenerationResponse {
                        id: format!("batch_error_{}", index),
                        status: GenerationStatus::Failed,
                        result_image_urls: vec![],
                        error_message: Some(e.to_string()),
                        generation_time_ms: None,
                    });
                }
            }

            // 批量处理间隔，避免服务器过载
            if index < total_requests - 1 {
                tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
            }
        }

        info!("批量生成完成（基于 prompt_id），成功: {}/{}",
            responses.iter().filter(|r| r.status == GenerationStatus::Completed).count(),
            total_requests
        );

        Ok(responses)
    }

    /// 生成穿搭照片（使用基于 prompt_id 的进度回调）
    pub async fn generate_outfit_photo_with_prompt_id_callback<F>(
        &self,
        request: OutfitPhotoGenerationRequest,
        progress_callback: F,
    ) -> Result<OutfitPhotoGenerationResponse>
    where
        F: FnMut(String, WorkflowProgress) + Send + 'static,
    {
        // 创建生成任务
        let generation = self.create_generation_task(request).await?;

        // 执行生成任务（使用基于 prompt_id 的回调）
        self.execute_generation_with_prompt_id_callback(&generation.id, progress_callback).await
    }

    /// 执行穿搭照片生成（使用基于 prompt_id 的进度回调）
    pub async fn execute_generation_with_prompt_id_callback<F>(
        &self,
        generation_id: &str,
        progress_callback: F,
    ) -> Result<OutfitPhotoGenerationResponse>
    where
        F: FnMut(String, WorkflowProgress) + Send + 'static,
    {
        let mut generation = self.get_generation_record(generation_id).await?;

        // 检查 ComfyUI 是否启用
        let config = self.config.lock().await;
        if !config.is_comfyui_enabled() {
            return Err(anyhow!("ComfyUI 功能未启用"));
        }

        let comfyui_service = ComfyUIService::new(config.get_comfyui_settings().clone());
        drop(config);

        // 更新状态为处理中
        generation.update_status(GenerationStatus::Processing);
        self.update_generation_record(&generation).await?;

        // 检查 ComfyUI 连接
        if !comfyui_service.check_connection().await? {
            generation.set_error("ComfyUI 服务器连接失败".to_string());
            self.update_generation_record(&generation).await?;
            return Ok(self.create_response(&generation));
        }

        // 上传商品图片到云端
        let product_image_url = if generation.product_image_path.starts_with("https://") {
            generation.product_image_path.clone()
        } else {
            match self.cloud_upload_service.upload_file(&generation.product_image_path, None, None).await {
                Ok(upload_result) => {
                    if upload_result.success {
                        if let Some(url) = upload_result.remote_url {
                            generation.product_image_url = Some(url.clone());
                            self.update_generation_record(&generation).await?;
                            url
                        } else {
                            generation.set_error("商品图片上传失败：未获得远程URL".to_string());
                            self.update_generation_record(&generation).await?;
                            return Ok(self.create_response(&generation));
                        }
                    } else {
                        generation.set_error(format!("商品图片上传失败: {}",
                            upload_result.error_message.unwrap_or_default()));
                        self.update_generation_record(&generation).await?;
                        return Ok(self.create_response(&generation));
                    }
                }
                Err(e) => {
                    generation.set_error(format!("商品图片上传失败: {}", e));
                    self.update_generation_record(&generation).await?;
                    return Ok(self.create_response(&generation));
                }
            }
        };

        // 获取模特图片URL
        let model_image_url = self.get_model_image_url(&generation.model_id).await?;

        // 获取工作流配置
        let workflow_config = self.get_default_workflow_config().await?;

        // 执行 ComfyUI 工作流并自动上传结果（使用基于 prompt_id 的回调）
        let remote_key_prefix = format!("outfit-photos/{}/{}", generation.project_id, generation.id);

        match comfyui_service.execute_workflow_with_upload_indexed_with_prompt_id_callback(
            &self.cloud_upload_service,
            &workflow_config.workflow_file_path,
            &model_image_url,
            &product_image_url,
            &generation.prompt,
            generation.negative_prompt.as_deref(),
            Some(&remote_key_prefix),
            progress_callback,
            None, // product_index
        ).await {
            Ok((prompt_id, upload_results)) => {
                // 保存 ComfyUI prompt_id
                generation.set_comfyui_prompt_id(prompt_id.clone());
                info!("✅ 已保存 ComfyUI prompt_id: {} 到生成记录: {}", prompt_id, generation.id);

                // 处理上传结果
                let mut successful_uploads = 0;

                for upload_result in upload_results {
                    if upload_result.success {
                        if let Some(remote_url) = upload_result.remote_url {
                            generation.result_image_urls.push(remote_url.clone());
                            successful_uploads += 1;
                        }
                    } else {
                        warn!("图片上传失败: {}", upload_result.error_message.unwrap_or_default());
                    }
                }

                if successful_uploads == 0 {
                    generation.set_error("所有图片上传失败".to_string());
                } else {
                    generation.update_status(GenerationStatus::Completed);
                    info!("成功上传 {} 张图片", successful_uploads);
                }
            }
            Err(e) => {
                generation.set_error(format!("ComfyUI 工作流执行或上传失败: {}", e));
            }
        }

        // 更新数据库记录
        self.update_generation_record(&generation).await?;

        Ok(self.create_response(&generation))
    }

    /// 重新上传失败的图片
    pub async fn retry_failed_uploads(&self, generation_id: &str) -> Result<OutfitPhotoGenerationResponse> {
        // 从数据库获取生成记录
        let mut generation = self.repository.get_by_id(generation_id)?
            .ok_or_else(|| anyhow!("生成记录不存在: {}", generation_id))?;

        if generation.status != GenerationStatus::Failed {
            return Err(anyhow!("只能重试失败的生成记录"));
        }

        info!("开始重试上传失败的图片，生成ID: {}", generation_id);

        // 重置状态
        generation.update_status(GenerationStatus::Processing);
        generation.error_message = None;
        generation.result_image_urls.clear();

        // 更新数据库
        self.update_generation_record(&generation).await?;

        // 这里可以实现重新上传逻辑
        // 由于我们没有保存本地文件路径，这里主要是演示结构
        // 实际实现中可能需要重新执行整个工作流或从本地缓存重新上传

        warn!("重试上传功能需要进一步实现，当前仅更新状态");
        generation.set_error("重试功能待实现".to_string());
        self.update_generation_record(&generation).await?;

        Ok(self.create_response(&generation))
    }

    /// 清理临时文件和失败的生成记录
    pub async fn cleanup_failed_generations(&self, max_age_hours: u64) -> Result<usize> {
        let _cutoff_time = chrono::Utc::now() - chrono::Duration::hours(max_age_hours as i64);

        // 这里可以实现清理逻辑
        // 1. 查找超过指定时间的失败记录
        // 2. 删除相关的临时文件
        // 3. 可选择性删除数据库记录或标记为已清理

        info!("清理 {} 小时前的失败生成记录", max_age_hours);

        // 返回清理的记录数量
        Ok(0)
    }

    /// 上传商品图片到云端
    async fn upload_product_image(&self, image_path: &str) -> Result<String> {
        if !Path::new(image_path).exists() {
            return Err(anyhow!("商品图片文件不存在: {}", image_path));
        }

        let upload_result = self.cloud_upload_service
            .upload_file(image_path, None, None)
            .await?;

        if upload_result.success {
            upload_result.remote_url
                .ok_or_else(|| anyhow!("上传成功但未返回URL"))
        } else {
            Err(anyhow!("上传失败: {}", upload_result.error_message.unwrap_or_default()))
        }
    }

    /// 获取模特图片URL
    async fn get_model_image_url(&self, model_id: &str) -> Result<String> {
        info!("开始获取模特图片URL: {}", model_id);

        // 从数据库获取模特信息
        let model = self.model_repository.get_basic_by_id(model_id)
            .map_err(|e| anyhow!("查询模特信息失败: {}", e))?;

        let model = model.ok_or_else(|| anyhow!("模特不存在: {}", model_id))?;

        // 优先使用头像路径
        if let Some(avatar_path) = &model.avatar_path {
            if !avatar_path.is_empty() {
                info!("使用模特头像路径: {}", avatar_path);
                return Ok(avatar_path.clone());
            }
        }

        // 如果没有头像，获取模特照片
        let photos = self.model_repository.get_photos(model_id)
            .map_err(|e| anyhow!("获取模特照片失败: {}", e))?;

        if photos.is_empty() {
            return Err(anyhow!("模特 {} 没有可用的照片", model_id));
        }

        // 优先选择封面照片
        if let Some(cover_photo) = photos.iter().find(|p| p.is_cover) {
            info!("使用模特封面照片: {}", cover_photo.file_path);
            return Ok(cover_photo.file_path.clone());
        }

        // 如果没有封面照片，使用第一张照片
        let first_photo = &photos[0];
        info!("使用模特第一张照片: {}", first_photo.file_path);
        Ok(first_photo.file_path.clone())
    }

    /// 获取默认工作流配置
    async fn get_default_workflow_config(&self) -> Result<WorkflowConfig> {
        let config = self.config.lock().await;
        let workflow_dir = config.get_comfyui_settings().workflow_directory
            .as_deref()
            .unwrap_or("workflows");
        
        let workflow_path = Path::new(workflow_dir).join("换装-MidJourney.json");
        
        Ok(WorkflowConfig {
            workflow_file_path: workflow_path.to_string_lossy().to_string(),
            ..WorkflowConfig::default()
        })
    }

    /// 处理生成的图片
    async fn process_generated_image(
        &self,
        comfyui_service: &ComfyUIService,
        filename: &str,
        generation: &mut OutfitPhotoGeneration,
    ) -> Result<()> {
        // 从 ComfyUI 下载图片
        let image_data = comfyui_service.download_image(filename, "", "output").await?;

        // 保存到临时文件
        let temp_path = self.save_temp_image(filename, &image_data).await?;

        // 上传到云端
        let upload_result = self.cloud_upload_service
            .upload_file(&temp_path, None, None)
            .await?;

        let remote_url = if upload_result.success {
            upload_result.remote_url
        } else {
            warn!("上传图片失败: {}", upload_result.error_message.unwrap_or_default());
            None
        };

        // 保存本地文件（可选）
        let local_path = self.save_local_image(filename, remote_url.as_deref().unwrap_or("")).await?;

        // 添加到生成记录
        generation.add_result(local_path, remote_url);

        // 清理临时文件
        if let Err(e) = tokio::fs::remove_file(&temp_path).await {
            warn!("清理临时文件失败: {} - {}", temp_path, e);
        }

        Ok(())
    }

    /// 保存临时图片文件
    async fn save_temp_image(&self, filename: &str, image_data: &[u8]) -> Result<String> {
        let temp_dir = std::env::temp_dir();
        let temp_path = temp_dir.join(format!("comfyui_{}", filename));

        tokio::fs::write(&temp_path, image_data).await?;

        Ok(temp_path.to_string_lossy().to_string())
    }

    /// 保存本地图片文件
    async fn save_local_image(&self, filename: &str, _url: &str) -> Result<String> {
        let config = self.config.lock().await;
        let output_dir = config.get_comfyui_settings().output_directory
            .as_deref()
            .unwrap_or("output");

        let local_path = Path::new(output_dir).join(filename);

        // 确保目录存在
        if let Some(parent) = local_path.parent() {
            tokio::fs::create_dir_all(parent).await?;
        }

        Ok(local_path.to_string_lossy().to_string())
    }

    /// 保存生成记录到数据库
    async fn save_generation_record(&self, generation: &OutfitPhotoGeneration) -> Result<()> {
        self.repository.create(generation)
    }

    /// 更新生成记录
    async fn update_generation_record(&self, generation: &OutfitPhotoGeneration) -> Result<()> {
        self.repository.update(generation)
    }

    /// 获取生成记录
    async fn get_generation_record(&self, generation_id: &str) -> Result<OutfitPhotoGeneration> {
        match self.repository.get_by_id(generation_id)? {
            Some(generation) => Ok(generation),
            None => Err(anyhow!("生成记录不存在: {}", generation_id))
        }
    }

    /// 创建响应对象
    fn create_response(&self, generation: &OutfitPhotoGeneration) -> OutfitPhotoGenerationResponse {
        OutfitPhotoGenerationResponse {
            id: generation.id.clone(),
            status: generation.status.clone(),
            result_image_urls: generation.result_image_urls.clone(),
            error_message: generation.error_message.clone(),
            generation_time_ms: generation.generation_time_ms,
        }
    }
}

/// 创建基于 prompt_id 的进度回调函数（用于 OutfitPhotoGeneration）
/// 这个函数用于批量处理场景，通过 prompt_id 精确匹配任务
pub fn create_outfit_photo_prompt_id_based_progress_callback(
    database: Arc<Database>,
    app_handle: AppHandle,
) -> impl Fn(String, WorkflowProgress) + Send + Sync + 'static {
    move |prompt_id: String, progress: WorkflowProgress| {
        let repo = match OutfitPhotoGenerationRepository::new(database.clone()) {
            Ok(repo) => repo,
            Err(e) => {
                error!("❌ 创建 OutfitPhotoGenerationRepository 失败: {}", e);
                return;
            }
        };

        // 根据 prompt_id 查找对应的记录
        match repo.get_by_comfyui_prompt_id(&prompt_id) {
            Ok(Some(generation)) => {
                let generation_id = generation.id.clone();

                // 更新数据库中的进度（OutfitPhotoGeneration 没有 progress 字段，所以我们只发送事件）
                info!("✅ 通过 prompt_id {} 更新生成记录 {} 进度: {}%",
                      prompt_id, generation_id, progress.progress_percentage);

                // 发送进度事件到前端
                let progress_event = serde_json::json!({
                    "type": "outfit_photo_generation_progress",
                    "generation_id": generation_id,
                    "prompt_id": prompt_id,
                    "progress_percentage": progress.progress_percentage,
                    "current_step": progress.current_step,
                    "total_steps": progress.total_steps,
                    "status_message": progress.status_message,
                    "current_node_id": progress.current_node_id
                });

                if let Err(e) = app_handle.emit("outfit_photo_generation_progress", &progress_event) {
                    warn!("发送进度事件失败: {}", e);
                }
            }
            Ok(None) => {
                warn!("⚠️ 未找到 prompt_id {} 对应的生成记录", prompt_id);
            }
            Err(e) => {
                error!("❌ 查找 prompt_id {} 对应生成记录失败: {}", prompt_id, e);
            }
        }
    }
}
