# -*- coding: UTF-8 -*-
"""
数据范围转换器
将 Full Range (0-255) 转换为 Limited Range (16-235)

使用方法:
    from app.data_range_converter import DataRangeConverter

    converter = DataRangeConverter()
    converted_params = converter.convert(pattern_params, "Limited")
"""


class DataRangeConverter:
    """数据范围转换器"""

    def __init__(self, verbose=True):
        """
        初始化转换器

        Args:
            verbose: 是否打印详细日志
        """
        self.verbose = verbose

    def convert_value(self, value):
        """
        将单个 Full Range 值转换为 Limited Range

        转换公式:
            limited = 16 + (value / 255) × (235 - 16)

        Args:
            value: Full Range 值 (0-255)

        Returns:
            int: Limited Range 值 (16-235)
        """
        # 边界值直接映射
        if value == 0:
            return 16
        elif value == 255:
            return 235
        else:
            # 线性映射
            limited = 16 + round((value / 255.0) * (235 - 16))
            # 限制范围
            return max(16, min(235, limited))

    def convert_rgb(self, r, g, b):
        """
        转换单个 RGB 值

        Args:
            r, g, b: Full Range RGB 值 (0-255)

        Returns:
            tuple: Limited Range RGB 值 (16-235)
        """
        return (self.convert_value(r), self.convert_value(g), self.convert_value(b))

    def convert(self, pattern_params, data_range="Full"):
        """
        转换图案参数列表

        Args:
            pattern_params: 图案参数列表 [[r,g,b], [r,g,b], ...]
            data_range: "Full" 或 "Limited"

        Returns:
            list: 转换后的图案参数列表
        """
        # Full Range 不需要转换
        if data_range == "Full":
            if self.verbose:
                print("使用 Full Range (0-255)，无需转换")
            return pattern_params

        # Limited Range 需要转换
        if data_range == "Limited":
            if self.verbose:
                self._print_header()

            converted = []
            for i, rgb in enumerate(pattern_params):
                # 获取原始值
                r_orig, g_orig, b_orig = rgb[0], rgb[1], rgb[2]

                # 转换
                r_new, g_new, b_new = self.convert_rgb(r_orig, g_orig, b_orig)

                # 保存
                converted.append([r_new, g_new, b_new])

                # 打印日志（关键值）
                if self.verbose:
                    self._print_conversion(
                        i, r_orig, g_orig, b_orig, r_new, g_new, b_new
                    )

            if self.verbose:
                self._print_footer(len(pattern_params))

            return converted

        # 未知范围，返回原始值
        else:
            if self.verbose:
                print(f"⚠ 未知的数据范围: {data_range}，使用原始值")
            return pattern_params

    def _print_header(self):
        """打印转换头部信息"""
        print("=" * 80)
        print("【数据范围转换】Limited Range (16-235)")
        print("  转换公式: 16 + (value / 255) × (235 - 16)")
        print("=" * 80)

    def _print_conversion(self, index, r_orig, g_orig, b_orig, r_new, g_new, b_new):
        """
        打印转换日志

        策略：只打印关键值，避免刷屏
        - 第一个和最后一个图案
        - 0, 128, 255 等关键值
        """
        # 判断是否需要打印
        should_print = False

        # 第一个和最后一个
        if index == 0:
            should_print = True
            label = "黑色"
        elif index == len([]) - 1:  # 需要在外部判断
            should_print = True
            label = "白色"
        # 关键 RGB 值
        elif (
            r_orig in [0, 128, 255]
            or g_orig in [0, 128, 255]
            or b_orig in [0, 128, 255]
        ):
            should_print = True
            if r_orig == 128:
                label = "50% 灰"
            else:
                label = ""

        if should_print:
            diff = abs(r_new - r_orig)
            print(
                f"  图案 {index+1:2d} {label:8s}: "
                f"RGB({r_orig:3d},{g_orig:3d},{b_orig:3d}) → "
                f"RGB({r_new:3d},{g_new:3d},{b_new:3d})  "
                f"(差值: {diff:+3d})"
            )

    def _print_footer(self, total_count):
        """打印转换尾部信息"""
        print(f"转换完成，共 {total_count} 个图案")
        print("=" * 80)

    def get_info(self):
        """获取转换器信息"""
        return {
            "name": "Data Range Converter",
            "version": "1.0.0",
            "full_range": "0-255",
            "limited_range": "16-235",
            "formula": "16 + (value / 255) × 219",
        }


# ========== 便捷函数 ==========


def convert_pattern_params(pattern_params, data_range="Full", verbose=True):
    """
    便捷函数：转换图案参数

    Args:
        pattern_params: 图案参数列表 [[r,g,b], [r,g,b], ...]
        data_range: "Full" 或 "Limited"
        verbose: 是否打印日志

    Returns:
        list: 转换后的图案参数列表

    示例:
        >>> from app.data_range_converter import convert_pattern_params
        >>> params = [[0,0,0], [255,255,255]]
        >>> converted = convert_pattern_params(params, "Limited")
        [[16,16,16], [235,235,235]]
    """
    converter = DataRangeConverter(verbose=verbose)
    return converter.convert(pattern_params, data_range)


def convert_single_rgb(r, g, b, data_range="Full"):
    """
    便捷函数：转换单个 RGB 值

    Args:
        r, g, b: RGB 值 (0-255)
        data_range: "Full" 或 "Limited"

    Returns:
        tuple: 转换后的 RGB 值

    示例:
        >>> from app.data_range_converter import convert_single_rgb
        >>> r, g, b = convert_single_rgb(0, 0, 0, "Limited")
        (16, 16, 16)
    """
    if data_range == "Full":
        return (r, g, b)

    converter = DataRangeConverter(verbose=False)
    return converter.convert_rgb(r, g, b)


# ========== 测试代码 ==========

if __name__ == "__main__":
    """测试转换器"""

    print("=" * 80)
    print("数据范围转换器 - 测试")
    print("=" * 80)

    # 测试 1: 基本转换
    print("\n[测试 1] 基本转换...")
    converter = DataRangeConverter(verbose=False)

    test_values = [0, 16, 64, 128, 192, 235, 255]
    print("  Full Range → Limited Range:")
    for v in test_values:
        limited = converter.convert_value(v)
        diff = limited - v
        print(f"    {v:3d} → {limited:3d}  (差值: {diff:+3d})")

    # 测试 2: RGB 转换
    print("\n[测试 2] RGB 转换...")
    test_rgb = [
        (0, 0, 0),
        (128, 128, 128),
        (255, 255, 255),
    ]

    for r, g, b in test_rgb:
        r_new, g_new, b_new = converter.convert_rgb(r, g, b)
        print(f"    RGB({r},{g},{b}) → RGB({r_new},{g_new},{b_new})")

    # 测试 3: 完整转换流程
    print("\n[测试 3] 完整转换流程...")
    pattern_params = [
        [255, 255, 255],  # 100% 白
        [230, 230, 230],  # 90%
        [204, 204, 204],  # 80%
        [128, 128, 128],  # 50%
        [0, 0, 0],  # 0% 黑
    ]

    converted = converter.convert(pattern_params, "Limited")

    print("\n  对比:")
    for i, (orig, conv) in enumerate(zip(pattern_params, converted)):
        print(f"    [{i+1}] {orig} → {conv}")

    # 测试 4: 便捷函数
    print("\n[测试 4] 便捷函数...")
    result = convert_pattern_params(
        [[0, 0, 0], [255, 255, 255]], "Limited", verbose=False
    )
    print(f"  结果: {result}")

    r, g, b = convert_single_rgb(128, 128, 128, "Limited")
    print(f"  RGB(128,128,128) → RGB({r},{g},{b})")

    # 测试 5: 获取信息
    print("\n[测试 5] 转换器信息...")
    info = converter.get_info()
    for key, value in info.items():
        print(f"  {key}: {value}")

    print("\n" + "=" * 80)
    print("测试完成")
    print("=" * 80)
