//! 编解码模块

use anyhow::Result;
use image::{ImageBuffer, Rgba, RgbaImage};

/// JPEG 编码器
pub struct JpegEncoder {
    quality: u32,
}

impl JpegEncoder {
    pub fn new(quality: u32) -> Self {
        Self {
            quality: quality.clamp(1, 100),
        }
    }

    /// 编码 RGBA 数据为 JPEG
    pub fn encode(&self, rgba: &[u8], width: u32, height: u32) -> Result<Vec<u8>> {
        let img: RgbaImage = ImageBuffer::from_raw(width, height, rgba.to_vec())
            .ok_or_else(|| anyhow::anyhow!("Failed to create image buffer"))?;

        let mut jpeg_data = Vec::new();
        let mut encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(
            &mut jpeg_data,
            self.quality as u8,
        );
        
        encoder.encode(
            img.as_raw(),
            width,
            height,
            image::ColorType::Rgba8,
        )?;

        Ok(jpeg_data)
    }

    /// 设置质量
    pub fn set_quality(&mut self, quality: u32) {
        self.quality = quality.clamp(1, 100);
    }
}

/// JPEG 解码器
pub struct JpegDecoder;

impl JpegDecoder {
    /// 解码 JPEG 为 RGBA
    pub fn decode(jpeg_data: &[u8]) -> Result<(Vec<u8>, u32, u32)> {
        let img = image::load_from_memory_with_format(jpeg_data, image::ImageFormat::Jpeg)?;
        let rgba = img.to_rgba8();
        let (width, height) = rgba.dimensions();
        Ok((rgba.into_raw(), width, height))
    }
}

/// 图像缩放器
pub struct ImageScaler;

impl ImageScaler {
    /// 缩放 RGBA 图像
    pub fn scale(
        rgba: &[u8],
        src_width: u32,
        src_height: u32,
        scale: f32,
    ) -> Result<(Vec<u8>, u32, u32)> {
        if (scale - 1.0).abs() < 0.01 {
            return Ok((rgba.to_vec(), src_width, src_height));
        }

        let new_width = (src_width as f32 * scale) as u32;
        let new_height = (src_height as f32 * scale) as u32;

        let img: RgbaImage = ImageBuffer::from_raw(src_width, src_height, rgba.to_vec())
            .ok_or_else(|| anyhow::anyhow!("Failed to create image buffer"))?;

        let resized = image::imageops::resize(
            &img,
            new_width,
            new_height,
            image::imageops::FilterType::Triangle,
        );

        Ok((resized.into_raw(), new_width, new_height))
    }
}

/// 帧差异计算
pub struct FrameDiffer {
    last_frame: Option<Vec<u8>>,
    width: u32,
    height: u32,
}

impl FrameDiffer {
    pub fn new(width: u32, height: u32) -> Self {
        Self {
            last_frame: None,
            width,
            height,
        }
    }

    /// 计算与上一帧的差异区域
    /// 返回差异区域的边界框 (x, y, width, height)
    pub fn compute_diff(&mut self, current: &[u8]) -> Option<DiffRegion> {
        let result = if let Some(ref last) = self.last_frame {
            self.find_diff_region(last, current)
        } else {
            // 第一帧，返回整个区域
            Some(DiffRegion {
                x: 0,
                y: 0,
                width: self.width,
                height: self.height,
                is_full_frame: true,
            })
        };

        self.last_frame = Some(current.to_vec());
        result
    }

    fn find_diff_region(&self, last: &[u8], current: &[u8]) -> Option<DiffRegion> {
        let mut min_x = self.width;
        let mut min_y = self.height;
        let mut max_x = 0u32;
        let mut max_y = 0u32;
        let mut has_diff = false;

        // 每4个字节一组（RGBA）
        for y in 0..self.height {
            for x in 0..self.width {
                let idx = ((y * self.width + x) * 4) as usize;
                if idx + 3 < last.len() && idx + 3 < current.len() {
                    // 简单比较：如果任何通道差异超过阈值，认为有变化
                    let diff = (last[idx] as i32 - current[idx] as i32).abs()
                        + (last[idx + 1] as i32 - current[idx + 1] as i32).abs()
                        + (last[idx + 2] as i32 - current[idx + 2] as i32).abs();

                    if diff > 30 {
                        has_diff = true;
                        min_x = min_x.min(x);
                        min_y = min_y.min(y);
                        max_x = max_x.max(x);
                        max_y = max_y.max(y);
                    }
                }
            }
        }

        if has_diff {
            // 添加一些边距
            let margin = 8;
            min_x = min_x.saturating_sub(margin);
            min_y = min_y.saturating_sub(margin);
            max_x = (max_x + margin).min(self.width - 1);
            max_y = (max_y + margin).min(self.height - 1);

            Some(DiffRegion {
                x: min_x,
                y: min_y,
                width: max_x - min_x + 1,
                height: max_y - min_y + 1,
                is_full_frame: false,
            })
        } else {
            None
        }
    }

    /// 重置状态
    pub fn reset(&mut self) {
        self.last_frame = None;
    }
}

/// 差异区域
#[derive(Debug, Clone)]
pub struct DiffRegion {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32,
    pub is_full_frame: bool,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_jpeg_encode_decode() {
        let width = 100;
        let height = 100;
        let mut rgba = vec![0u8; (width * height * 4) as usize];
        
        // 创建测试图像
        for y in 0..height {
            for x in 0..width {
                let idx = ((y * width + x) * 4) as usize;
                rgba[idx] = (x * 255 / width) as u8;     // R
                rgba[idx + 1] = (y * 255 / height) as u8; // G
                rgba[idx + 2] = 128;                      // B
                rgba[idx + 3] = 255;                      // A
            }
        }

        let encoder = JpegEncoder::new(80);
        let jpeg = encoder.encode(&rgba, width, height).unwrap();
        assert!(!jpeg.is_empty());

        let (decoded, w, h) = JpegDecoder::decode(&jpeg).unwrap();
        assert_eq!(w, width);
        assert_eq!(h, height);
        assert_eq!(decoded.len(), rgba.len());
    }
}
