use anyhow::{Result, anyhow};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::fs;
use std::time::Instant;
use tracing::{info, debug};

use crate::data::models::watermark::{
    WatermarkTemplate, WatermarkCategory, WatermarkType
};
use crate::data::repositories::watermark_template_repository::WatermarkTemplateRepository;
use crate::infrastructure::ffmpeg_watermark::FFmpegWatermark;
use crate::infrastructure::monitoring::PERFORMANCE_MONITOR;

/// 水印模板管理服务
/// 遵循 Tauri 开发规范的业务逻辑层设计
pub struct WatermarkTemplateService;

impl WatermarkTemplateService {
    /// 上传并创建水印模板
    pub async fn upload_template(
        repository: Arc<WatermarkTemplateRepository>,
        name: String,
        source_file_path: String,
        category: WatermarkCategory,
        watermark_type: WatermarkType,
        description: Option<String>,
        tags: Vec<String>,
    ) -> Result<WatermarkTemplate> {
        let _timer = PERFORMANCE_MONITOR.start_operation("upload_watermark_template");
        let start_time = Instant::now();

        info!(
            name = %name,
            source_file_path = %source_file_path,
            category = ?category,
            watermark_type = ?watermark_type,
            "开始上传水印模板"
        );

        // 验证源文件存在
        if !Path::new(&source_file_path).exists() {
            return Err(anyhow!("源文件不存在: {}", source_file_path));
        }

        // 检查模板名称是否已存在
        if repository.name_exists(&name, None)? {
            return Err(anyhow!("模板名称已存在: {}", name));
        }

        // 验证文件格式
        Self::validate_file_format(&source_file_path, &watermark_type)?;

        // 创建模板目录
        let template_id = uuid::Uuid::new_v4().to_string();
        let template_dir = Self::get_template_directory(&template_id);
        fs::create_dir_all(&template_dir)?;

        // 复制文件到模板目录
        let file_extension = Path::new(&source_file_path)
            .extension()
            .and_then(|ext| ext.to_str())
            .unwrap_or("unknown");
        let template_filename = format!("template.{}", file_extension);
        let template_file_path = template_dir.join(&template_filename);
        
        fs::copy(&source_file_path, &template_file_path)?;

        // 获取文件信息
        let file_metadata = fs::metadata(&template_file_path)?;
        let file_size = file_metadata.len();

        // 获取图片/视频尺寸
        let (width, height) = Self::get_media_dimensions(&template_file_path.to_string_lossy().to_string())?;

        // 生成缩略图
        let thumbnail_path = Self::generate_thumbnail(
            &template_file_path.to_string_lossy().to_string(),
            &template_dir,
            &watermark_type,
        ).await?;

        // 创建模板对象
        let template = WatermarkTemplate {
            id: template_id,
            name,
            file_path: template_file_path.to_string_lossy().to_string(),
            thumbnail_path: Some(thumbnail_path),
            category,
            watermark_type,
            file_size,
            width,
            height,
            description,
            tags,
            is_active: true,
            created_at: chrono::Utc::now(),
            updated_at: chrono::Utc::now(),
        };

        // 保存到数据库
        repository.create(&template)?;

        let processing_time = start_time.elapsed().as_millis() as u64;
        info!(
            template_id = %template.id,
            processing_time_ms = processing_time,
            "水印模板上传成功"
        );

        Ok(template)
    }

    /// 更新水印模板
    pub async fn update_template(
        repository: Arc<WatermarkTemplateRepository>,
        template_id: String,
        name: Option<String>,
        description: Option<String>,
        tags: Option<Vec<String>>,
        category: Option<WatermarkCategory>,
    ) -> Result<WatermarkTemplate> {
        info!(template_id = %template_id, "开始更新水印模板");

        // 获取现有模板
        let mut template = repository.get_by_id(&template_id)?
            .ok_or_else(|| anyhow!("模板不存在: {}", template_id))?;

        // 检查名称是否冲突
        if let Some(ref new_name) = name {
            if repository.name_exists(new_name, Some(&template_id))? {
                return Err(anyhow!("模板名称已存在: {}", new_name));
            }
            template.name = new_name.clone();
        }

        // 更新其他字段
        if let Some(new_description) = description {
            template.description = Some(new_description);
        }

        if let Some(new_tags) = tags {
            template.tags = new_tags;
        }

        if let Some(new_category) = category {
            template.category = new_category;
        }

        template.updated_at = chrono::Utc::now();

        // 保存更新
        repository.update(&template)?;

        info!(template_id = %template_id, "水印模板更新成功");
        Ok(template)
    }

    /// 删除水印模板
    pub async fn delete_template(
        repository: Arc<WatermarkTemplateRepository>,
        template_id: String,
        hard_delete: bool,
    ) -> Result<()> {
        info!(template_id = %template_id, hard_delete = hard_delete, "开始删除水印模板");

        // 获取模板信息
        let _template = repository.get_by_id(&template_id)?
            .ok_or_else(|| anyhow!("模板不存在: {}", template_id))?;

        if hard_delete {
            // 硬删除：删除文件和数据库记录
            let template_dir = Self::get_template_directory(&template_id);
            if template_dir.exists() {
                fs::remove_dir_all(&template_dir)?;
            }
            repository.delete(&template_id)?;
        } else {
            // 软删除：只标记为非活跃
            repository.soft_delete(&template_id)?;
        }

        info!(template_id = %template_id, "水印模板删除成功");
        Ok(())
    }

    /// 获取模板列表
    pub async fn get_templates(
        repository: Arc<WatermarkTemplateRepository>,
        category: Option<WatermarkCategory>,
        watermark_type: Option<WatermarkType>,
        search_query: Option<String>,
    ) -> Result<Vec<WatermarkTemplate>> {
        debug!("获取水印模板列表");

        let templates = if let Some(query) = search_query {
            repository.search(&query)?
        } else if let Some(cat) = category {
            repository.get_by_category(&cat)?
        } else if let Some(wtype) = watermark_type {
            repository.get_by_type(&wtype)?
        } else {
            repository.get_all()?
        };

        Ok(templates)
    }

    /// 获取模板统计信息
    pub async fn get_template_stats(
        repository: Arc<WatermarkTemplateRepository>,
    ) -> Result<serde_json::Value> {
        debug!("获取水印模板统计信息");
        repository.get_stats()
    }

    /// 验证文件格式
    fn validate_file_format(file_path: &str, watermark_type: &WatermarkType) -> Result<()> {
        let path = Path::new(file_path);
        let extension = path.extension()
            .and_then(|ext| ext.to_str())
            .ok_or_else(|| anyhow!("无法获取文件扩展名"))?
            .to_lowercase();

        let valid_extensions = match watermark_type {
            WatermarkType::Image => vec!["png", "jpg", "jpeg", "bmp", "tiff", "webp"],
            WatermarkType::Vector => vec!["svg"],
            WatermarkType::Animated => vec!["gif", "webp", "apng"],
            WatermarkType::Text => vec!["txt", "json"], // 文字水印配置文件
        };

        if !valid_extensions.contains(&extension.as_str()) {
            return Err(anyhow!(
                "不支持的文件格式: {}，支持的格式: {:?}",
                extension,
                valid_extensions
            ));
        }

        Ok(())
    }

    /// 获取媒体文件尺寸
    fn get_media_dimensions(file_path: &str) -> Result<(Option<u32>, Option<u32>)> {
        let path = Path::new(file_path);
        let extension = path.extension()
            .and_then(|ext| ext.to_str())
            .unwrap_or("")
            .to_lowercase();

        match extension.as_str() {
            "png" | "jpg" | "jpeg" | "bmp" | "tiff" | "webp" | "gif" => {
                // 对于图片文件，可以使用image库获取尺寸
                // 这里先返回None，后续可以集成image库
                Ok((None, None))
            }
            "svg" => {
                // SVG文件需要解析XML获取viewBox或width/height属性
                Ok((None, None))
            }
            _ => Ok((None, None)),
        }
    }

    /// 生成缩略图
    async fn generate_thumbnail(
        file_path: &str,
        output_dir: &Path,
        watermark_type: &WatermarkType,
    ) -> Result<String> {
        let thumbnail_path = output_dir.join("thumbnail.jpg");
        let thumbnail_path_str = thumbnail_path.to_string_lossy().to_string();

        match watermark_type {
            WatermarkType::Image | WatermarkType::Animated => {
                // 对于图片和动画，使用FFmpeg生成缩略图
                FFmpegWatermark::extract_frame_at_timestamp(
                    file_path,
                    0.0, // 第一帧
                    &thumbnail_path_str,
                    200, // 缩略图宽度
                    150, // 缩略图高度
                )?;
            }
            WatermarkType::Vector => {
                // 对于SVG，需要转换为PNG再生成缩略图
                // 这里先复制原文件作为缩略图
                fs::copy(file_path, &thumbnail_path)?;
            }
            WatermarkType::Text => {
                // 对于文字水印，生成一个文字预览图
                Self::generate_text_thumbnail(file_path, &thumbnail_path_str)?;
            }
        }

        Ok(thumbnail_path_str)
    }

    /// 生成文字水印缩略图
    fn generate_text_thumbnail(_text_file_path: &str, output_path: &str) -> Result<()> {
        // TODO: 实现文字水印缩略图生成
        // 可以使用图像库生成包含文字的预览图
        
        // 临时实现：创建一个空的缩略图文件
        fs::write(output_path, b"")?;
        Ok(())
    }

    /// 获取模板目录路径
    fn get_template_directory(template_id: &str) -> PathBuf {
        PathBuf::from("watermarks")
            .join("templates")
            .join(template_id)
    }

    /// 导出模板
    pub async fn export_template(
        repository: Arc<WatermarkTemplateRepository>,
        template_id: String,
        export_path: String,
    ) -> Result<()> {
        info!(template_id = %template_id, export_path = %export_path, "开始导出水印模板");

        // 获取模板信息
        let template = repository.get_by_id(&template_id)?
            .ok_or_else(|| anyhow!("模板不存在: {}", template_id))?;

        // 创建导出目录
        let export_dir = Path::new(&export_path);
        fs::create_dir_all(export_dir)?;

        // 复制模板文件
        let template_file = Path::new(&template.file_path);
        if template_file.exists() {
            let export_file = export_dir.join(template_file.file_name().unwrap());
            fs::copy(template_file, export_file)?;
        }

        // 复制缩略图
        if let Some(ref thumbnail_path) = template.thumbnail_path {
            let thumbnail_file = Path::new(thumbnail_path);
            if thumbnail_file.exists() {
                let export_thumbnail = export_dir.join("thumbnail.jpg");
                fs::copy(thumbnail_file, export_thumbnail)?;
            }
        }

        // 创建模板信息文件
        let template_info = serde_json::json!({
            "id": template.id,
            "name": template.name,
            "category": template.category,
            "watermark_type": template.watermark_type,
            "description": template.description,
            "tags": template.tags,
            "created_at": template.created_at,
            "updated_at": template.updated_at
        });

        let info_file = export_dir.join("template_info.json");
        fs::write(info_file, serde_json::to_string_pretty(&template_info)?)?;

        info!(template_id = %template_id, "水印模板导出成功");
        Ok(())
    }

    /// 导入模板
    pub async fn import_template(
        repository: Arc<WatermarkTemplateRepository>,
        import_path: String,
    ) -> Result<WatermarkTemplate> {
        info!(import_path = %import_path, "开始导入水印模板");

        let import_dir = Path::new(&import_path);
        if !import_dir.is_dir() {
            return Err(anyhow!("导入路径必须是目录: {}", import_path));
        }

        // 读取模板信息文件
        let info_file = import_dir.join("template_info.json");
        if !info_file.exists() {
            return Err(anyhow!("缺少模板信息文件: template_info.json"));
        }

        let info_content = fs::read_to_string(info_file)?;
        let template_info: serde_json::Value = serde_json::from_str(&info_content)?;

        // 提取模板信息
        let name = template_info["name"].as_str()
            .ok_or_else(|| anyhow!("缺少模板名称"))?;
        let category: WatermarkCategory = serde_json::from_value(template_info["category"].clone())?;
        let watermark_type: WatermarkType = serde_json::from_value(template_info["watermark_type"].clone())?;
        let description = template_info["description"].as_str().map(|s| s.to_string());
        let tags: Vec<String> = serde_json::from_value(template_info["tags"].clone())
            .unwrap_or_default();

        // 查找模板文件
        let template_files: Vec<_> = fs::read_dir(import_dir)?
            .filter_map(|entry| entry.ok())
            .filter(|entry| {
                let path = entry.path();
                path.is_file() && 
                path.file_name().unwrap().to_str().unwrap() != "template_info.json" &&
                path.file_name().unwrap().to_str().unwrap() != "thumbnail.jpg"
            })
            .collect();

        if template_files.is_empty() {
            return Err(anyhow!("未找到模板文件"));
        }

        let template_file = &template_files[0];
        let template_file_path = template_file.path().to_string_lossy().to_string();

        // 使用上传功能创建模板
        Self::upload_template(
            repository,
            name.to_string(),
            template_file_path,
            category,
            watermark_type,
            description,
            tags,
        ).await
    }
}
