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

use crate::data::models::watermark::{
    WatermarkConfig, WatermarkType, WatermarkPosition, WatermarkAnimation,
    AnimationType, BlendMode, QualityLevel, WatermarkProcessingResult,
    WatermarkOperation, DynamicPositionRule, Corner
};
use crate::data::repositories::material_repository::MaterialRepository;
use crate::infrastructure::ffmpeg_watermark::FFmpegWatermark;
use crate::infrastructure::monitoring::PERFORMANCE_MONITOR;

/// 水印添加服务
/// 遵循 Tauri 开发规范的业务逻辑层设计
pub struct WatermarkAdditionService;

impl WatermarkAdditionService {
    /// 为视频添加水印
    pub async fn add_watermark_to_video(
        material_id: &str,
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
        _repository: Arc<MaterialRepository>,
    ) -> Result<WatermarkProcessingResult> {
        let _timer = PERFORMANCE_MONITOR.start_operation("watermark_addition_video");
        let start_time = Instant::now();

        info!(
            material_id = %material_id,
            input_path = %input_path,
            output_path = %output_path,
            watermark_path = %watermark_path,
            watermark_type = ?config.watermark_type,
            "开始为视频添加水印"
        );

        // 验证输入文件存在
        if !Path::new(input_path).exists() {
            return Err(anyhow!("输入视频文件不存在: {}", input_path));
        }

        if !Path::new(watermark_path).exists() {
            return Err(anyhow!("水印文件不存在: {}", watermark_path));
        }

        // 确保输出目录存在
        if let Some(parent) = Path::new(output_path).parent() {
            std::fs::create_dir_all(parent)?;
        }

        let result = match config.watermark_type {
            WatermarkType::Image => {
                Self::add_image_watermark_to_video(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
            WatermarkType::Text => {
                Self::add_text_watermark_to_video(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
            WatermarkType::Vector => {
                Self::add_vector_watermark_to_video(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
            WatermarkType::Animated => {
                Self::add_animated_watermark_to_video(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
        };

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

        let processing_result = match result {
            Ok(_) => {
                info!(
                    material_id = %material_id,
                    processing_time_ms = processing_time,
                    "视频水印添加成功"
                );

                WatermarkProcessingResult {
                    material_id: material_id.to_string(),
                    operation: WatermarkOperation::Add,
                    success: true,
                    output_path: Some(output_path.to_string()),
                    processing_time_ms: processing_time,
                    error_message: None,
                    metadata: None,
                }
            }
            Err(e) => {
                error!(
                    material_id = %material_id,
                    error = %e,
                    processing_time_ms = processing_time,
                    "视频水印添加失败"
                );

                WatermarkProcessingResult {
                    material_id: material_id.to_string(),
                    operation: WatermarkOperation::Add,
                    success: false,
                    output_path: None,
                    processing_time_ms: processing_time,
                    error_message: Some(e.to_string()),
                    metadata: None,
                }
            }
        };

        Ok(processing_result)
    }

    /// 为图片添加水印
    pub async fn add_watermark_to_image(
        material_id: &str,
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
    ) -> Result<WatermarkProcessingResult> {
        let _timer = PERFORMANCE_MONITOR.start_operation("watermark_addition_image");
        let start_time = Instant::now();

        info!(
            material_id = %material_id,
            input_path = %input_path,
            output_path = %output_path,
            watermark_path = %watermark_path,
            watermark_type = ?config.watermark_type,
            "开始为图片添加水印"
        );

        // 验证输入文件存在
        if !Path::new(input_path).exists() {
            return Err(anyhow!("输入图片文件不存在: {}", input_path));
        }

        if !Path::new(watermark_path).exists() {
            return Err(anyhow!("水印文件不存在: {}", watermark_path));
        }

        // 确保输出目录存在
        if let Some(parent) = Path::new(output_path).parent() {
            std::fs::create_dir_all(parent)?;
        }

        let result = match config.watermark_type {
            WatermarkType::Image => {
                Self::add_image_watermark_to_image(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
            WatermarkType::Text => {
                Self::add_text_watermark_to_image(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
            WatermarkType::Vector => {
                Self::add_vector_watermark_to_image(
                    input_path,
                    output_path,
                    watermark_path,
                    config,
                ).await
            }
            WatermarkType::Animated => {
                // 动态水印不适用于静态图片
                Err(anyhow!("动态水印不能应用于静态图片"))
            }
        };

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

        let processing_result = match result {
            Ok(_) => {
                info!(
                    material_id = %material_id,
                    processing_time_ms = processing_time,
                    "图片水印添加成功"
                );

                WatermarkProcessingResult {
                    material_id: material_id.to_string(),
                    operation: WatermarkOperation::Add,
                    success: true,
                    output_path: Some(output_path.to_string()),
                    processing_time_ms: processing_time,
                    error_message: None,
                    metadata: None,
                }
            }
            Err(e) => {
                error!(
                    material_id = %material_id,
                    error = %e,
                    processing_time_ms = processing_time,
                    "图片水印添加失败"
                );

                WatermarkProcessingResult {
                    material_id: material_id.to_string(),
                    operation: WatermarkOperation::Add,
                    success: false,
                    output_path: None,
                    processing_time_ms: processing_time,
                    error_message: Some(e.to_string()),
                    metadata: None,
                }
            }
        };

        Ok(processing_result)
    }

    /// 为视频添加图片水印
    async fn add_image_watermark_to_video(
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为视频添加图片水印");

        // 获取视频信息
        let video_info = FFmpegWatermark::get_video_info(input_path)?;
        let video_width = video_info.width.unwrap_or(1920) as f32;
        let video_height = video_info.height.unwrap_or(1080) as f32;

        // 计算水印位置
        let position = Self::calculate_watermark_position(
            &config.position,
            video_width,
            video_height,
            config.scale,
        );

        // 构建overlay滤镜
        let overlay_filter = Self::build_overlay_filter(
            &position,
            config.opacity,
            config.scale,
            config.rotation,
            &config.blend_mode,
            config.animation.as_ref(),
        );

        let quality_args = Self::get_quality_args(&config.quality_level);

        let mut args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-i", watermark_path,
            "-filter_complex", &overlay_filter,
        ];

        args.extend_from_slice(&quality_args);
        args.extend_from_slice(&["-c:a", "copy", "-y", output_path]);

        FFmpegWatermark::execute_command(&args)?;
        Ok(())
    }

    /// 为视频添加文字水印
    async fn add_text_watermark_to_video(
        input_path: &str,
        output_path: &str,
        text_content: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为视频添加文字水印");

        // 获取视频信息
        let video_info = FFmpegWatermark::get_video_info(input_path)?;
        let video_width = video_info.width.unwrap_or(1920) as f32;
        let video_height = video_info.height.unwrap_or(1080) as f32;

        // 计算文字位置
        let position = Self::calculate_watermark_position(
            &config.position,
            video_width,
            video_height,
            config.scale,
        );

        // 构建文字滤镜
        let text_filter = Self::build_text_filter(
            text_content,
            &position,
            config.opacity,
            config.scale,
            config.rotation,
        );

        let quality_args = Self::get_quality_args(&config.quality_level);

        let mut args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-vf", &text_filter,
        ];

        args.extend_from_slice(&quality_args);
        args.extend_from_slice(&["-c:a", "copy", "-y", output_path]);

        FFmpegWatermark::execute_command(&args)?;
        Ok(())
    }

    /// 为视频添加矢量水印
    async fn add_vector_watermark_to_video(
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为视频添加矢量水印");

        // SVG需要先转换为PNG
        let temp_png = Self::convert_svg_to_png(watermark_path, config.scale).await?;

        let result = Self::add_image_watermark_to_video(
            input_path,
            output_path,
            &temp_png,
            config,
        ).await;

        // 清理临时文件
        let _ = std::fs::remove_file(&temp_png);

        result
    }

    /// 为视频添加动态水印
    async fn add_animated_watermark_to_video(
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为视频添加动态水印");

        // 获取视频信息
        let video_info = FFmpegWatermark::get_video_info(input_path)?;
        let video_width = video_info.width.unwrap_or(1920) as f32;
        let video_height = video_info.height.unwrap_or(1080) as f32;

        // 计算水印位置
        let position = Self::calculate_watermark_position(
            &config.position,
            video_width,
            video_height,
            config.scale,
        );

        // 构建动态overlay滤镜
        let overlay_filter = Self::build_animated_overlay_filter(
            &position,
            config.opacity,
            config.scale,
            config.rotation,
            &config.blend_mode,
            config.animation.as_ref(),
        );

        let quality_args = Self::get_quality_args(&config.quality_level);

        let mut args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-i", watermark_path,
            "-filter_complex", &overlay_filter,
        ];

        args.extend_from_slice(&quality_args);
        args.extend_from_slice(&["-c:a", "copy", "-y", output_path]);

        FFmpegWatermark::execute_command(&args)?;
        Ok(())
    }

    /// 为图片添加图片水印
    async fn add_image_watermark_to_image(
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为图片添加图片水印");

        // TODO: 获取图片尺寸
        let image_width = 1920.0; // 临时值
        let image_height = 1080.0; // 临时值

        // 计算水印位置
        let position = Self::calculate_watermark_position(
            &config.position,
            image_width,
            image_height,
            config.scale,
        );

        // 构建overlay滤镜
        let overlay_filter = format!(
            "overlay={}:{}:alpha={}",
            position.0,
            position.1,
            config.opacity
        );

        let args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-i", watermark_path,
            "-filter_complex", &overlay_filter,
            "-y", output_path,
        ];

        FFmpegWatermark::execute_command(&args)?;
        Ok(())
    }

    /// 为图片添加文字水印
    async fn add_text_watermark_to_image(
        input_path: &str,
        output_path: &str,
        text_content: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为图片添加文字水印");

        // TODO: 获取图片尺寸
        let image_width = 1920.0; // 临时值
        let image_height = 1080.0; // 临时值

        // 计算文字位置
        let position = Self::calculate_watermark_position(
            &config.position,
            image_width,
            image_height,
            config.scale,
        );

        // 构建文字滤镜
        let text_filter = Self::build_text_filter(
            text_content,
            &position,
            config.opacity,
            config.scale,
            config.rotation,
        );

        let args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-vf", &text_filter,
            "-y", output_path,
        ];

        FFmpegWatermark::execute_command(&args)?;
        Ok(())
    }

    /// 为图片添加矢量水印
    async fn add_vector_watermark_to_image(
        input_path: &str,
        output_path: &str,
        watermark_path: &str,
        config: &WatermarkConfig,
    ) -> Result<()> {
        debug!("为图片添加矢量水印");

        // SVG需要先转换为PNG
        let temp_png = Self::convert_svg_to_png(watermark_path, config.scale).await?;

        let result = Self::add_image_watermark_to_image(
            input_path,
            output_path,
            &temp_png,
            config,
        ).await;

        // 清理临时文件
        let _ = std::fs::remove_file(&temp_png);

        result
    }

    /// 计算水印位置
    fn calculate_watermark_position(
        position: &WatermarkPosition,
        video_width: f32,
        video_height: f32,
        scale: f32,
    ) -> (f32, f32) {
        let watermark_width = 200.0 * scale; // 假设水印宽度
        let watermark_height = 100.0 * scale; // 假设水印高度

        match position {
            WatermarkPosition::TopLeft => (10.0, 10.0),
            WatermarkPosition::TopCenter => ((video_width - watermark_width) / 2.0, 10.0),
            WatermarkPosition::TopRight => (video_width - watermark_width - 10.0, 10.0),
            WatermarkPosition::MiddleLeft => (10.0, (video_height - watermark_height) / 2.0),
            WatermarkPosition::Center => (
                (video_width - watermark_width) / 2.0,
                (video_height - watermark_height) / 2.0,
            ),
            WatermarkPosition::MiddleRight => (
                video_width - watermark_width - 10.0,
                (video_height - watermark_height) / 2.0,
            ),
            WatermarkPosition::BottomLeft => (10.0, video_height - watermark_height - 10.0),
            WatermarkPosition::BottomCenter => (
                (video_width - watermark_width) / 2.0,
                video_height - watermark_height - 10.0,
            ),
            WatermarkPosition::BottomRight => (
                video_width - watermark_width - 10.0,
                video_height - watermark_height - 10.0,
            ),
            WatermarkPosition::Custom { x, y } => (
                x * video_width,
                y * video_height,
            ),
            WatermarkPosition::Dynamic(rule) => {
                Self::calculate_dynamic_position(rule, video_width, video_height, scale)
            }
        }
    }

    /// 计算动态位置
    fn calculate_dynamic_position(
        rule: &DynamicPositionRule,
        video_width: f32,
        video_height: f32,
        scale: f32,
    ) -> (f32, f32) {
        // TODO: 实现动态位置计算逻辑
        // 这里需要集成人脸检测、文字检测等功能
        
        // 临时实现：根据角落偏好选择位置
        if let Some(corner) = rule.corner_preference.first() {
            let margin = rule.min_distance_from_edge as f32;
            let watermark_width = 200.0 * scale;
            let watermark_height = 100.0 * scale;

            match corner {
                Corner::TopLeft => (margin, margin),
                Corner::TopRight => (video_width - watermark_width - margin, margin),
                Corner::BottomLeft => (margin, video_height - watermark_height - margin),
                Corner::BottomRight => (
                    video_width - watermark_width - margin,
                    video_height - watermark_height - margin,
                ),
            }
        } else {
            // 默认右下角
            (video_width - 210.0, video_height - 110.0)
        }
    }

    /// 构建overlay滤镜
    fn build_overlay_filter(
        position: &(f32, f32),
        opacity: f32,
        scale: f32,
        rotation: f32,
        _blend_mode: &BlendMode,
        animation: Option<&WatermarkAnimation>,
    ) -> String {
        let mut filter_parts = Vec::new();

        // 缩放
        if scale != 1.0 {
            filter_parts.push(format!("[1:v]scale=iw*{}:ih*{}", scale, scale));
        }

        // 旋转
        if rotation != 0.0 {
            filter_parts.push(format!("rotate={}*PI/180", rotation));
        }

        // 透明度
        if opacity != 1.0 {
            filter_parts.push(format!("format=rgba,colorchannelmixer=aa={}", opacity));
        }

        let watermark_filter = if filter_parts.is_empty() {
            "[1:v]".to_string()
        } else {
            format!("[1:v]{}", filter_parts.join(","))
        };

        // overlay位置
        let overlay_expr = if let Some(anim) = animation {
            Self::build_animated_position_expression(position, anim)
        } else {
            format!("{}:{}", position.0, position.1)
        };

        format!("{}[wm];[0:v][wm]overlay={}", watermark_filter, overlay_expr)
    }

    /// 构建动态overlay滤镜
    fn build_animated_overlay_filter(
        position: &(f32, f32),
        opacity: f32,
        scale: f32,
        rotation: f32,
        blend_mode: &BlendMode,
        animation: Option<&WatermarkAnimation>,
    ) -> String {
        // 与普通overlay类似，但添加动画表达式
        Self::build_overlay_filter(position, opacity, scale, rotation, blend_mode, animation)
    }

    /// 构建文字滤镜
    fn build_text_filter(
        text: &str,
        position: &(f32, f32),
        opacity: f32,
        scale: f32,
        _rotation: f32,
    ) -> String {
        let font_size = (24.0 * scale) as u32;
        let alpha = (opacity * 255.0) as u32;

        format!(
            "drawtext=text='{}':x={}:y={}:fontsize={}:fontcolor=white@{}",
            text.replace("'", "\\'"),
            position.0,
            position.1,
            font_size,
            alpha
        )
    }

    /// 构建动画位置表达式
    fn build_animated_position_expression(
        base_position: &(f32, f32),
        animation: &WatermarkAnimation,
    ) -> String {
        match animation.animation_type {
            AnimationType::FadeIn => {
                format!("{}:{}:alpha='if(lt(t,{}),t/{},1)'", 
                    base_position.0, 
                    base_position.1,
                    animation.duration_ms as f32 / 1000.0,
                    animation.duration_ms as f32 / 1000.0
                )
            }
            AnimationType::SlideIn => {
                format!("'{}+100*max(0,1-t/{})':{}",
                    base_position.0,
                    animation.duration_ms as f32 / 1000.0,
                    base_position.1
                )
            }
            _ => format!("{}:{}", base_position.0, base_position.1),
        }
    }

    /// 转换SVG为PNG
    async fn convert_svg_to_png(svg_path: &str, _scale: f32) -> Result<String> {
        // TODO: 实现SVG到PNG的转换
        // 可以使用librsvg或其他SVG渲染库
        
        // 临时实现：直接返回SVG路径（FFmpeg可能支持SVG）
        Ok(svg_path.to_string())
    }

    /// 获取质量参数
    fn get_quality_args(quality_level: &QualityLevel) -> Vec<&'static str> {
        match quality_level {
            QualityLevel::Low => vec!["-c:v", "libx264", "-preset", "ultrafast", "-crf", "28"],
            QualityLevel::Medium => vec!["-c:v", "libx264", "-preset", "fast", "-crf", "23"],
            QualityLevel::High => vec!["-c:v", "libx264", "-preset", "slow", "-crf", "18"],
            QualityLevel::Lossless => vec!["-c:v", "libx264", "-preset", "veryslow", "-crf", "0"],
        }
    }
}
