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::{
    WatermarkRemovalConfig, RemovalMethod, QualityLevel, BoundingBox,
    WatermarkProcessingResult, WatermarkOperation
};
use crate::data::repositories::material_repository::MaterialRepository;
use crate::infrastructure::ffmpeg_watermark::FFmpegWatermark;
use crate::infrastructure::monitoring::PERFORMANCE_MONITOR;

/// 水印移除服务
/// 遵循 Tauri 开发规范的业务逻辑层设计
pub struct WatermarkRemovalService;

impl WatermarkRemovalService {
    /// 移除视频中的水印
    pub async fn remove_watermarks_from_video(
        material_id: &str,
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
        _repository: Arc<MaterialRepository>,
    ) -> Result<WatermarkProcessingResult> {
        let _timer = PERFORMANCE_MONITOR.start_operation("watermark_removal_video");
        let start_time = Instant::now();

        info!(
            material_id = %material_id,
            input_path = %input_path,
            output_path = %output_path,
            method = ?config.method,
            "开始移除视频水印"
        );

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

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

        let result = match config.method {
            RemovalMethod::Blurring => {
                Self::remove_by_blurring(input_path, output_path, config).await
            }
            RemovalMethod::Cropping => {
                Self::remove_by_cropping(input_path, output_path, config).await
            }
            RemovalMethod::Masking => {
                Self::remove_by_masking(input_path, output_path, config).await
            }
            RemovalMethod::Inpainting => {
                Self::remove_by_inpainting(input_path, output_path, config).await
            }
            RemovalMethod::ContentAware => {
                Self::remove_by_content_aware(input_path, output_path, config).await
            }
            RemovalMethod::Clone => {
                Self::remove_by_clone(input_path, output_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::Remove,
                    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::Remove,
                    success: false,
                    output_path: None,
                    processing_time_ms: processing_time,
                    error_message: Some(e.to_string()),
                    metadata: None,
                }
            }
        };

        Ok(processing_result)
    }

    /// 移除图片中的水印
    pub async fn remove_watermarks_from_image(
        material_id: &str,
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<WatermarkProcessingResult> {
        let _timer = PERFORMANCE_MONITOR.start_operation("watermark_removal_image");
        let start_time = Instant::now();

        info!(
            material_id = %material_id,
            input_path = %input_path,
            output_path = %output_path,
            method = ?config.method,
            "开始移除图片水印"
        );

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

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

        let result = match config.method {
            RemovalMethod::Blurring => {
                Self::remove_image_by_blurring(input_path, output_path, config).await
            }
            RemovalMethod::Cropping => {
                Self::remove_image_by_cropping(input_path, output_path, config).await
            }
            RemovalMethod::Masking => {
                Self::remove_image_by_masking(input_path, output_path, config).await
            }
            RemovalMethod::Inpainting => {
                Self::remove_image_by_inpainting(input_path, output_path, config).await
            }
            RemovalMethod::ContentAware => {
                Self::remove_image_by_content_aware(input_path, output_path, config).await
            }
            RemovalMethod::Clone => {
                Self::remove_image_by_clone(input_path, output_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::Remove,
                    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::Remove,
                    success: false,
                    output_path: None,
                    processing_time_ms: processing_time,
                    error_message: Some(e.to_string()),
                    metadata: None,
                }
            }
        };

        Ok(processing_result)
    }

    /// 通过模糊处理移除水印
    async fn remove_by_blurring(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("使用模糊处理移除水印");

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

        // 构建FFmpeg命令
        let mut args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
        ];

        // 添加模糊滤镜
        let filter = if let Some(regions) = &config.target_regions {
            // 对指定区域进行模糊处理
            Self::build_region_blur_filter(regions, blur_radius)
        } else {
            // 全局模糊
            format!("boxblur={}:1", blur_radius)
        };
        args.extend_from_slice(&["-vf", &filter]);

        // 添加质量参数
        args.extend_from_slice(&quality_args);
        args.extend_from_slice(&["-c:a", "copy", "-y", output_path]);

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

    /// 通过裁剪移除水印
    async fn remove_by_cropping(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("使用裁剪移除水印");

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

        let margin = config.crop_margin.unwrap_or(50);
        let quality_args = Self::get_quality_args(&config.quality_level);

        // 计算裁剪区域（移除边缘区域）
        let crop_width = width.saturating_sub(margin * 2);
        let crop_height = height.saturating_sub(margin * 2);
        let crop_x = margin;
        let crop_y = margin;

        let crop_filter = format!("crop={}:{}:{}:{}", crop_width, crop_height, crop_x, crop_y);

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

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

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

    /// 通过遮罩覆盖移除水印
    async fn remove_by_masking(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("使用遮罩覆盖移除水印");

        // TODO: 实现遮罩覆盖逻辑
        // 这里需要根据检测到的水印区域生成遮罩
        
        // 临时实现：使用简单的颜色填充
        let quality_args = Self::get_quality_args(&config.quality_level);

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

        let filter = if let Some(regions) = &config.target_regions {
            Some(Self::build_region_mask_filter(regions))
        } else {
            None
        };

        if let Some(ref filter_str) = filter {
            args.extend_from_slice(&["-vf", filter_str]);
        }

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

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

    /// 通过AI修复移除水印
    async fn remove_by_inpainting(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("使用AI修复移除水印");

        // TODO: 集成AI修复模型
        // 目前使用简单的模糊处理作为替代
        Self::remove_by_blurring(input_path, output_path, config).await
    }

    /// 通过内容感知填充移除水印
    async fn remove_by_content_aware(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("使用内容感知填充移除水印");

        // TODO: 实现内容感知填充算法
        // 目前使用模糊处理作为替代
        Self::remove_by_blurring(input_path, output_path, config).await
    }

    /// 通过克隆修复移除水印
    async fn remove_by_clone(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("使用克隆修复移除水印");

        // TODO: 实现克隆修复算法
        // 目前使用模糊处理作为替代
        Self::remove_by_blurring(input_path, output_path, config).await
    }

    /// 图片模糊处理
    async fn remove_image_by_blurring(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("对图片使用模糊处理移除水印");

        let blur_radius = config.blur_radius.unwrap_or(10.0);

        let blur_filter = format!("boxblur={}:1", blur_radius);
        let args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-vf", &blur_filter,
            "-y", output_path,
        ];

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

    /// 图片裁剪处理
    async fn remove_image_by_cropping(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("对图片使用裁剪移除水印");

        // TODO: 获取图片尺寸并计算裁剪区域
        let margin = config.crop_margin.unwrap_or(50);

        let crop_filter = format!("crop=iw-{}:ih-{}:{}:{}", margin * 2, margin * 2, margin, margin);
        let args = vec![
            "-hide_banner",
            "-loglevel", "error",
            "-i", input_path,
            "-vf", &crop_filter,
            "-y", output_path,
        ];

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

    /// 图片遮罩处理
    async fn remove_image_by_masking(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("对图片使用遮罩移除水印");

        // TODO: 实现图片遮罩处理
        Self::remove_image_by_blurring(input_path, output_path, config).await
    }

    /// 图片AI修复
    async fn remove_image_by_inpainting(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("对图片使用AI修复移除水印");

        // TODO: 实现图片AI修复
        Self::remove_image_by_blurring(input_path, output_path, config).await
    }

    /// 图片内容感知填充
    async fn remove_image_by_content_aware(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("对图片使用内容感知填充移除水印");

        // TODO: 实现图片内容感知填充
        Self::remove_image_by_blurring(input_path, output_path, config).await
    }

    /// 图片克隆修复
    async fn remove_image_by_clone(
        input_path: &str,
        output_path: &str,
        config: &WatermarkRemovalConfig,
    ) -> Result<()> {
        debug!("对图片使用克隆修复移除水印");

        // TODO: 实现图片克隆修复
        Self::remove_image_by_blurring(input_path, output_path, config).await
    }

    /// 构建区域模糊滤镜
    fn build_region_blur_filter(regions: &[BoundingBox], blur_radius: f32) -> String {
        let mut filters = Vec::new();
        
        for (_i, region) in regions.iter().enumerate() {
            let filter = format!(
                "boxblur={}:1:enable='between(t,0,999999)*between(x,{},{})*between(y,{},{})'",
                blur_radius,
                region.x,
                region.x + region.width,
                region.y,
                region.y + region.height
            );
            filters.push(filter);
        }

        filters.join(",")
    }

    /// 构建区域遮罩滤镜
    fn build_region_mask_filter(regions: &[BoundingBox]) -> String {
        let mut filters = Vec::new();
        
        for region in regions {
            let filter = format!(
                "drawbox=x={}:y={}:w={}:h={}:color=black:t=fill",
                region.x,
                region.y,
                region.width,
                region.height
            );
            filters.push(filter);
        }

        filters.join(",")
    }

    /// 获取质量参数
    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"],
        }
    }
}
