# PQ自动化测试配置模块
import json
import copy


class PQConfig:
    def __init__(self, current_test_type="screen_module", device_config={}, pattern={}):
        self.default_cct_params_by_type = {
            "screen_module": {
                "x_ideal": 0.3127,
                "x_tolerance": 0.003,
                "y_ideal": 0.3290,
                "y_tolerance": 0.003,
            },
            "sdr_movie": {
                "x_ideal": 0.3127,
                "x_tolerance": 0.003,
                "y_ideal": 0.3290,
                "y_tolerance": 0.003,
            },
            "hdr_movie": {
                "x_ideal": 0.3127,
                "x_tolerance": 0.003,
                "y_ideal": 0.3290,
                "y_tolerance": 0.003,
            },
        }
        self.default_gamut_reference_by_type = {
            "screen_module": "DCI-P3",
            "sdr_movie": "BT.709",
            "hdr_movie": "BT.2020",
        }

        self.default_test_types = {
            "screen_module": {
                "name": "屏模组性能测试",
                "test_items": ["gamut", "gamma", "cct", "contrast"],
                "timing": "DMT 1920x 1080 @ 60Hz",
                "color_format": "RGB",
                "bpc": 8,
                "colorimetry": "sRGB",
            },
            "sdr_movie": {
                "name": "SDR Movie测试",
                "test_items": ["gamut", "gamma", "cct", "contrast", "accuracy"],
                "timing": "DMT 1920x 1080 @ 60Hz",
                "color_format": "RGB",
                "bpc": 8,
                "colorimetry": "sRGB",
            },
            "hdr_movie": {
                "name": "HDR Movie测试",
                "test_items": ["gamut", "eotf", "cct", "contrast", "accuracy"],
                "timing": "DMT 1920x 1080 @ 60Hz",
                "color_format": "RGB",
                "bpc": 8,
                "colorimetry": "sRGB",
            },
        }

        # 设备连接配置
        self.device_config = {
            "ca_com": "COM1",
            "ucd_list": "0: UCD-323 [2128C209]",
            "ca_channel": "0",
        }

        # ========== RGB Pattern 配置 ==========
        self.default_pattern_rgb = {
            "pattern_mode": "SolidColor",
            "measurement_bit_depth": 8,
            "measurement_max_value": 2,
            "pattern_params": [
                [255, 0, 0],  # 红色
                [0, 255, 0],  # 绿色
                [0, 0, 255],  # 蓝色
            ],
        }

        # ========== 灰阶 Pattern 配置 ==========
        self.default_pattern_gray = {
            "pattern_mode": "SolidColor",
            "measurement_bit_depth": 8,
            "measurement_max_value": 10,
            "pattern_params": [
                [255, 255, 255],  # 100% 白色
                [230, 230, 230],  # 90%
                [205, 205, 205],  # 80%
                [179, 179, 179],  # 70%
                [154, 154, 154],  # 60%
                [128, 128, 128],  # 50%
                [102, 102, 102],  # 40%
                [78, 78, 78],  # 30%
                [52, 52, 52],  # 20%
                [26, 26, 26],  # 10%
                [0, 0, 0],  # 0% 黑色
            ],
        }

        # ========== 色准 Pattern 配置（29色 - SDR 和 HDR 通用）==========
        self.default_pattern_accuracy = {
            "pattern_mode": "SolidColor",
            "measurement_bit_depth": 8,
            "measurement_max_value": 28,  # 29个颜色，最大索引是28
            "pattern_params": [
                # ========== 灰阶 (5个) ==========
                [255, 255, 255],  # 0: White
                [230, 230, 230],  # 1: Gray 80
                [209, 209, 209],  # 2: Gray 65
                [186, 186, 186],  # 3: Gray 50
                [158, 158, 158],  # 4: Gray 35
                # ========== ColorChecker 24色 (18个) ==========
                [115, 82, 66],  # 5: Dark Skin
                [194, 150, 130],  # 6: Light Skin
                [94, 122, 156],  # 7: Blue Sky
                [89, 107, 66],  # 8: Foliage
                [130, 128, 176],  # 9: Blue Flower
                [99, 189, 168],  # 10: Bluish Green
                [217, 120, 41],  # 11: Orange
                [74, 92, 163],  # 12: Purplish Blue
                [194, 84, 97],  # 13: Moderate Red
                [92, 61, 107],  # 14: Purple
                [158, 186, 64],  # 15: Yellow Green
                [230, 161, 46],  # 16: Orange Yellow
                [51, 61, 150],  # 17: Blue (Legacy)
                [71, 148, 71],  # 18: Green (Legacy)
                [176, 48, 59],  # 19: Red (Legacy)
                [237, 199, 33],  # 20: Yellow (Legacy)
                [186, 84, 145],  # 21: Magenta (Legacy)
                [0, 133, 163],  # 22: Cyan (Legacy)
                # ========== 100% 饱和色 (6个) ==========
                [255, 0, 0],  # 23: 100% Red
                [0, 255, 0],  # 24: 100% Green
                [0, 0, 255],  # 25: 100% Blue
                [0, 255, 255],  # 26: 100% Cyan
                [255, 0, 255],  # 27: 100% Magenta
                [255, 255, 0],  # 28: 100% Yellow
            ],
        }

        self.default_pattern_temp = {
            "pattern_mode": "SolidColor",
            "measurement_bit_depth": 8,
            "measurement_max_value": 146,
            "pattern_params": [
                [255, 255, 255],
                [242, 242, 242],
                [230, 230, 230],
                [217, 217, 217],
                [204, 204, 204],
                [191, 191, 191],
                [179, 179, 179],
                [166, 166, 166],
                [153, 153, 153],
                [140, 140, 140],
                [128, 128, 128],
                [115, 115, 115],
                [102, 102, 102],
                [89, 89, 89],
                [77, 77, 77],
                [64, 64, 64],
                [51, 51, 51],
                [38, 38, 38],
                [26, 26, 26],
                [13, 13, 13],
                [0, 0, 0],

                [255, 0, 0],
                [242, 0, 0],
                [230, 0, 0],
                [217, 0, 0],
                [204, 0, 0],
                [191, 0, 0],
                [179, 0, 0],
                [166, 0, 0],
                [153, 0, 0],
                [140, 0, 0],
                [128, 0, 0],
                [115, 0, 0],
                [102, 0, 0],
                [89, 0, 0],
                [77, 0, 0],
                [64, 0, 0],
                [51, 0, 0],
                [38, 0, 0],
                [26, 0, 0],
                [13, 0, 0],
                [0, 0, 0],

                [0, 255, 0],
                [0, 242, 0],
                [0, 230, 0],
                [0, 217, 0],
                [0, 204, 0],
                [0, 191, 0],
                [0, 179, 0],
                [0, 166, 0],
                [0, 153, 0],
                [0, 140, 0],
                [0, 128, 0],
                [0, 115, 0],
                [0, 102, 0],
                [0, 89, 0],
                [0, 77, 0],
                [0, 64, 0],
                [0, 51, 0],
                [0, 38, 0],
                [0, 26, 0],
                [0, 13, 0],
                [0, 0, 0],

                [0, 0, 255],
                [0, 0, 242],
                [0, 0, 230],
                [0, 0, 217],
                [0, 0, 204],
                [0, 0, 191],
                [0, 0, 179],
                [0, 0, 166],
                [0, 0, 153],
                [0, 0, 140],
                [0, 0, 128],
                [0, 0, 115],
                [0, 0, 102],
                [0, 0, 89],
                [0, 0, 77],
                [0, 0, 64],
                [0, 0, 51],
                [0, 0, 38],
                [0, 0, 26],
                [0, 0, 13],
                [0, 0, 0],

                [255, 255, 0],
                [242, 242, 0],
                [230, 230, 0],
                [217, 217, 0],
                [204, 204, 0],
                [191, 191, 0],
                [179, 179, 0],
                [166, 166, 0],
                [153, 153, 0],
                [140, 140, 0],
                [128, 128, 0],
                [115, 115, 0],
                [102, 102, 0],
                [89, 89, 0],
                [77, 77, 0],
                [64, 64, 0],
                [51, 51, 0],
                [38, 38, 0],
                [26, 26, 0],
                [13, 13, 0],
                [0, 0, 0],

                [0, 255, 255],
                [0, 242, 242],
                [0, 230, 230],
                [0, 217, 217],
                [0, 204, 204],
                [0, 191, 191],
                [0, 179, 179],
                [0, 166, 166],
                [0, 153, 153],
                [0, 140, 140],
                [0, 128, 128],
                [0, 115, 115],
                [0, 102, 102],
                [0, 89, 89],
                [0, 77, 77],
                [0, 64, 64],
                [0, 51, 51],
                [0, 38, 38],
                [0, 26, 26],
                [0, 13, 13],
                [0, 0, 0],

                [255, 0, 255],
                [242, 0, 242],
                [230, 0, 230],
                [217, 0, 217],
                [204, 0, 204],
                [191, 0, 191],
                [179, 0, 179],
                [166, 0, 166],
                [153, 0, 153],
                [140, 0, 140],
                [128, 0, 128],
                [115, 0, 115],
                [102, 0, 102],
                [89, 0, 89],
                [77, 0, 77],
                [64, 0, 64],
                [51, 0, 51],
                [38, 0, 38],
                [26, 0, 26],
                [13, 0, 13],
                [0, 0, 0],
            ]
        }

        # 自定义图案
        self.custom_pattern = {
            "pattern_mode": "SolidColor",
            "measurement_bit_depth": 8,
            "measurement_max_value": 0,
            "pattern_params": [],
        }

        self.current_test_types = self.default_test_types
        self.current_test_type = current_test_type
        self.current_pattern = self.default_pattern_rgb

    def get_default_cct_params(self, test_type):
        """获取指定测试类型的默认 CCT 参数副本。"""
        default = self.default_cct_params_by_type.get(
            test_type, self.default_cct_params_by_type["screen_module"]
        )
        return copy.deepcopy(default)

    def get_default_gamut_reference(self, test_type):
        """获取指定测试类型的默认色域参考。"""
        return self.default_gamut_reference_by_type.get(test_type, "DCI-P3")

    # ========== 获取临时配置（用于 Full/Limited 转换）==========
    def get_temp_config_with_converted_params(self, mode, converted_params):
        """
        创建一个临时配置对象，包含转换后的 pattern 参数

        Args:
            mode: "rgb" | "gray" | "accuracy"
            converted_params: 转换后的参数列表（Full 或 Limited Range）

        Returns:
            PQConfig: 临时配置对象（深拷贝，不影响原始配置）
        """
        # 1. 深拷贝整个配置对象
        temp_config = copy.deepcopy(self)

        # 2. 设置正确的 pattern 模式
        if mode == "rgb":
            temp_config.current_pattern = copy.deepcopy(self.default_pattern_rgb)
        elif mode == "gray":
            temp_config.current_pattern = copy.deepcopy(self.default_pattern_gray)
        elif mode == "accuracy":
            temp_config.current_pattern = copy.deepcopy(self.default_pattern_accuracy)

        # 3. 替换为转换后的参数
        temp_config.current_pattern["pattern_params"] = converted_params

        return temp_config

    def to_dict(self):
        """将配置转换为字典格式"""
        return {
            "current_test_type": self.current_test_type,
            "test_types": self.current_test_types,
            "device_config": self.device_config,
            "default_pattern_rgb": self.default_pattern_rgb,
            "default_pattern_gray": self.default_pattern_gray,
            "default_pattern_accuracy": self.default_pattern_accuracy,
            "custom_pattern": self.custom_pattern,
        }

    def from_dict(self, config_dict):
        """从字典加载配置"""
        self.current_test_type = config_dict.get("current_test_type", "screen_module")
        self.current_test_types = config_dict.get("test_types", self.current_test_types)
        self.device_config = config_dict.get("device_config", self.device_config)

        self.default_pattern_rgb = config_dict.get(
            "default_pattern_rgb", self.default_pattern_rgb
        )
        self.default_pattern_gray = config_dict.get(
            "default_pattern_gray", self.default_pattern_gray
        )

        # ========== ✅ 强制使用新的 29色配置 ==========
        loaded_accuracy = config_dict.get("default_pattern_accuracy", None)

        # 检查加载的配置是否是旧的 10色
        if loaded_accuracy and len(loaded_accuracy.get("pattern_params", [])) != 29:
            print(
                f"⚠️ 检测到旧的配置（{len(loaded_accuracy.get('pattern_params', []))}色），强制使用新的 29色配置"
            )
            # 使用 __init__ 中定义的新配置
            self.default_pattern_accuracy = self.default_pattern_accuracy
        else:
            self.default_pattern_accuracy = config_dict.get(
                "default_pattern_accuracy", self.default_pattern_accuracy
            )
        # ==========================================

        self.custom_pattern = config_dict.get("custom_pattern", self.custom_pattern)

    def save_to_file(self, filename):
        """将配置保存到文件"""
        with open(filename, "w", encoding="utf-8") as f:
            json.dump(self.to_dict(), f, indent=4, ensure_ascii=False)

    def set_current_test_type(self, test_type):
        """设置当前测试类型"""
        if test_type in self.current_test_types:
            self.current_test_type = test_type
            return True
        return False

    def set_current_test_items(self, test_items):
        """设置当前测试类型的测试项"""
        if self.current_test_type in self.current_test_types:
            self.current_test_types[self.current_test_type]["test_items"] = test_items
            return True
        return False

    def set_current_timing(self, timing):
        if self.current_test_type in self.current_test_types:
            self.current_test_types[self.current_test_type]["timing"] = timing
            return True
        return False

    def set_device_config(self, ca_com, ucd_list, ca_channel):
        """设置设备连接配置"""
        self.device_config["ca_com"] = ca_com
        self.device_config["ucd_list"] = ucd_list
        self.device_config["ca_channel"] = ca_channel
        return True

    def set_current_pattern(self, mode):
        """设置当前模式的测试图案"""
        if mode == "rgb":
            self.current_pattern = self.default_pattern_rgb
        elif mode == "gray":
            self.current_pattern = self.default_pattern_gray
        elif mode == "accuracy":  # ✅ 色准模式（SDR 和 HDR 通用 29色）
            self.current_pattern = self.default_pattern_accuracy
        elif mode == "custom":
            # self.current_pattern = self.custom_pattern
            self.current_pattern = self.default_pattern_temp
        else:
            return False

        # 确保 measurement_max_value 是整数
        if "measurement_max_value" in self.current_pattern:
            value = self.current_pattern["measurement_max_value"]
            if isinstance(value, str):
                try:
                    self.current_pattern["measurement_max_value"] = int(value)
                except ValueError:
                    self.current_pattern["measurement_max_value"] = (
                        len(self.current_pattern["pattern_params"]) - 1
                    )

        return True

    def set_custom_pattern(self, pattern_mode, pattern_params):
        """设置自定义模式的测试项"""
        self.custom_pattern["pattern_mode"] = pattern_mode
        self.custom_pattern["pattern_params"] = pattern_params
        self.custom_pattern["measurement_max_value"] = len(pattern_params) - 1
        return True

    # ========== ✅ 获取 29色名称列表 ==========
    def get_accuracy_color_names(self):
        """
        获取色准测试的 29个颜色名称（SDR 和 HDR 通用）

        Returns:
            list: 29个颜色名称
        """
        return [
            # 灰阶 (5个)
            "White",
            "Gray 80",
            "Gray 65",
            "Gray 50",
            "Gray 35",
            # ColorChecker 24色 (18个)
            "Dark Skin",
            "Light Skin",
            "Blue Sky",
            "Foliage",
            "Blue Flower",
            "Bluish Green",
            "Orange",
            "Purplish Blue",
            "Moderate Red",
            "Purple",
            "Yellow Green",
            "Orange Yellow",
            "Blue (Legacy)",
            "Green (Legacy)",
            "Red (Legacy)",
            "Yellow (Legacy)",
            "Magenta (Legacy)",
            "Cyan (Legacy)",
            # 100% 饱和色 (6个)
            "100% Red",
            "100% Green",
            "100% Blue",
            "100% Cyan",
            "100% Magenta",
            "100% Yellow",
        ]

    # ========== ✅ 获取 29色的 RGB 值 ==========
    def get_accuracy_color_rgb(self):
        """
        获取色准测试的 RGB 值（用于标准值计算）

        Returns:
            list: [(name, r, g, b), ...]
        """
        names = self.get_accuracy_color_names()
        rgb_values = self.default_pattern_accuracy["pattern_params"]

        return [(name, r, g, b) for name, (r, g, b) in zip(names, rgb_values)]

    def get_temp_pattern_names(self):
        """获取客户模板测试（default_pattern_temp）的固定 pattern 名称列表"""
        percentages = list(range(100, -1, -5))
        color_prefixes = ["W", "R", "G", "B", "Y", "C", "M"]

        names = []
        for prefix in color_prefixes:
            for value in percentages:
                names.append(f"{prefix} {value}%")

        pattern_count = len(self.default_pattern_temp.get("pattern_params", []))

        if pattern_count <= len(names):
            return names[:pattern_count]

        # 兜底：如果后续扩展了 pattern 数量，补充通用名称，避免索引越界。
        for i in range(len(names), pattern_count):
            names.append(f"P {i + 1}")

        return names

    def get_test_item_chinese_names(self, test_items):
        """获取测试项目的显示名称"""
        item_names = []
        for item in test_items:
            if item == "gamut":
                item_names.append("色域")
            elif item == "gamma":
                item_names.append("Gamma")
            elif item == "eotf":
                item_names.append("EOTF")
            elif item == "cct":
                item_names.append("色度一致性")
            elif item == "contrast":
                item_names.append("对比度")
            elif item == "accuracy":
                item_names.append("色准")
            else:
                item_names.append(item)
        return item_names

    def get_current_config(self):
        """返回当前测试类型相关的所有配置信息"""
        if self.current_test_type not in self.current_test_types:
            return {}

        current_test = self.current_test_types[self.current_test_type]

        config_info = {
            "test_type": self.current_test_type,
            "test_name": current_test.get("name", "未知测试"),
            "test_items": current_test.get("test_items", []),
            "test_items_chinese": self.get_test_item_chinese_names(
                current_test.get("test_items", [])
            ),
            "timing": current_test.get("timing", "DMT 1920x 1080 @ 60Hz"),
            "color_format": current_test.get("color_format", "RGB"),
            "bpc": current_test.get("bpc", 8),
            "colorimetry": current_test.get("colorimetry", "sRGB"),
        }

        return config_info


# ========== ✅ 验证代码（测试完成后可删除）==========
if __name__ == "__main__":
    print("=" * 60)
    print("验证 pq_config.py 配置")
    print("=" * 60)

    config = PQConfig()

    # 检查 default_pattern_accuracy
    pattern_count = len(config.default_pattern_accuracy["pattern_params"])
    max_value = config.default_pattern_accuracy["measurement_max_value"]

    print(f"\ndefault_pattern_accuracy:")
    print(f"  图案数量: {pattern_count}")
    print(f"  measurement_max_value: {max_value}")

    if pattern_count == 29 and max_value == 28:
        print("\n✅ 配置正确（29色）")

        # 显示前 5 个图案
        print("\n前5个图案:")
        for i in range(5):
            rgb = config.default_pattern_accuracy["pattern_params"][i]
            names = config.get_accuracy_color_names()
            print(f"  [{i}] {names[i]:15s} RGB{rgb}")

        # 显示后 5 个图案
        print("\n后5个图案:")
        for i in range(24, 29):
            rgb = config.default_pattern_accuracy["pattern_params"][i]
            names = config.get_accuracy_color_names()
            print(f"  [{i}] {names[i]:15s} RGB{rgb}")

        # 测试 set_current_pattern
        print("\n测试 set_current_pattern('accuracy'):")
        config.set_current_pattern("accuracy")
        current_count = len(config.current_pattern["pattern_params"])
        print(f"  current_pattern 图案数量: {current_count}")

        if current_count == 29:
            print("  ✅ set_current_pattern 工作正常")
        else:
            print(f"  ❌ set_current_pattern 失败！只有 {current_count} 个图案")

    else:
        print(f"\n❌ 配置错误！")
        print(f"   期望: 29 个图案, measurement_max_value=28")
        print(f"   实际: {pattern_count} 个图案, measurement_max_value={max_value}")

        print("\n❌ 请检查 default_pattern_accuracy 定义！")
        print("   应该包含:")
        print("     - 5个灰阶")
        print("     - 18个 ColorChecker 色块")
        print("     - 6个 100% 饱和色")
        print("     - 总计 29 个 RGB 数组")

    print("=" * 60)
