import json
import re
from collections import defaultdict

def postprocess_technical_table(data, good_list, special_keys=None, parent_key=''):
    """
    传输技术参数需求的时候后处理，输入的data为经过main_postprocess处理的采购需求数据
    """
    def get_suffix(n):
        """
        根据数字n返回对应的字母后缀。
        1 -> 'a', 2 -> 'b', ..., 26 -> 'z', 27 -> 'aa', 28 -> 'ab', ...
        """
        suffix = ''
        while n > 0:
            n, r = divmod(n - 1, 26)
            suffix = chr(97 + r) + suffix
        return suffix

    def count_matching_keys(data, patterns, special_keys, key_value_map=None):
        """
        递归统计匹配键的出现次数及其对应的唯一值，仅统计值为列表的键。
        对于每个键，会先去除键名中的空格，如果这个清理后的键不在 special_keys 列表中且满足至少一个patterns，就把对应的值（列表转换为元组）添加到 key_value_map 字典中。
        注意：同一个键对应的相同值（转换成元组后）只会保存一次，保证唯一性。
        返回结构：{
        'key1': [tuple_value1, tuple_value2, ...],
        'key2': [tuple_value1, ...],
            }
        """
        if key_value_map is None:
            key_value_map = defaultdict(list)

        if isinstance(data, dict):
            for key, value in data.items():
                clean_key = key.replace(" ", "")  # 去除键中的空格
                if isinstance(value, list):
                    if clean_key not in special_keys and any(pattern.match(clean_key) for pattern in patterns):
                        value_tuple = tuple(value)
                        if value_tuple not in key_value_map[clean_key]:    #每个键下的值若一样，则只保留一个
                            key_value_map[clean_key].append(value_tuple)
                elif isinstance(value, dict):
                    count_matching_keys(value, patterns, special_keys, key_value_map)
        elif isinstance(data, list):
            for item in data:
                if isinstance(item, (dict, list)):
                    count_matching_keys(item, patterns, special_keys, key_value_map)

        return key_value_map

    def assign_suffixes(key_value_map):
        """
        如果该键只有一个唯一值，则不添加后缀-a -b..
        如果有多个唯一值，则给第一个值不添加后缀，后续的值按照顺序分别添加 -a、-b、-c
        返回一个字典，键为原键名，值为另一个字典，键为值元组，值为对应的后缀（如果需要）。
        """
        suffix_assignment = defaultdict(dict)
        for key, values in key_value_map.items():
            if len(values) == 1:
                suffix_assignment[key][values[0]] = ''  # 只有一个唯一值，不需要后缀
            else:
                for idx, val in enumerate(values, start=1):
                    if idx == 1:
                        suffix = ''  # 第一个唯一值不添加后缀
                    else:
                        suffix = '-' + get_suffix(idx - 1)  # 从 '-a' 开始
                    suffix_assignment[key][val] = suffix
        return suffix_assignment

    def process_data(data, patterns, special_keys, suffix_assignment, filtered_data, parent_key):
        """递归处理数据并构建结果"""

        if isinstance(data, dict):
            for key, value in data.items():
                clean_key = key.replace(" ", "")  # 去除键中的空格
                current_parent_key = clean_key if parent_key == '' else f"{parent_key}的{clean_key}"

                if isinstance(value, list):
                    if clean_key in special_keys:
                        # 处理 special_keys，前缀父键路径
                        new_key = current_parent_key
                        filtered_data[new_key] = value
                    elif any(pattern.match(clean_key) for pattern in patterns):
                        # 处理普通匹配键
                        # 检查是否以特殊符号开头
                        if clean_key.startswith(('▲', '★','●','■','◆','☆','△','◇','○','□','#')):    #货物名以特殊符号开头->移至键值（技术参数）开头
                            #提取符号并去除符号：
                            symbol = clean_key[0]
                            stripped_key = clean_key[1:]
                            value_tuple = tuple(value)
                            suffix = suffix_assignment.get(stripped_key, {}).get(value_tuple, '')
                            if suffix:
                                new_key = f"{stripped_key}{suffix}"
                            else:
                                new_key = stripped_key
                            # 将符号添加到每个字符串的开头
                            new_value = [symbol + item for item in value]
                            filtered_data[new_key] = new_value
                        else:
                            # 获取当前值的后缀
                            value_tuple = tuple(value)
                            suffix = suffix_assignment.get(clean_key, {}).get(value_tuple, '')
                            if suffix:
                                new_key = f"{clean_key}{suffix}"
                            else:
                                new_key = clean_key
                            filtered_data[new_key] = value
                elif isinstance(value, dict):
                    # 继续递归处理嵌套字典
                    process_data(value, patterns, special_keys, suffix_assignment, filtered_data, current_parent_key)
        elif isinstance(data, list):
            for item in data:
                if isinstance(item, (dict, list)):
                    process_data(item, patterns, special_keys, suffix_assignment, filtered_data, parent_key)

    def generate_patterns(good_list):
        """生成匹配的正则表达式列表"""
        return [re.compile(r'^' + re.escape(g) + r'(?:-\d+)?$') for g in good_list]

    if special_keys is None:
        special_keys = ["系统功能"]  # 默认值为 ["系统功能"]

    # 去除 good_list 中的空格
    clean_good_list = [g.replace(" ", "") for g in good_list]

    # 构建匹配的正则表达式
    patterns = generate_patterns(clean_good_list)

    # 先统计所有匹配键的出现次数及其对应的唯一值，仅统计值为列表的键
    key_value_map = count_matching_keys(data, patterns, special_keys)

    # 为每个键的唯一值分配后缀
    suffix_assignment = assign_suffixes(key_value_map)

    # 用于存储最终结果
    filtered_data = {}

    # 递归处理数据
    process_data(data, patterns, special_keys, suffix_assignment, filtered_data, parent_key)

    return filtered_data

def main_postprocess(data):
    #解析采购要求时候的后处理，用于前端网页展示。
    def recursive_process(item):
        pattern = re.compile(r'(.+)-\d+$')

        if isinstance(item, dict):
            cleaned_dict = {
                key: recursive_process(value)
                for key, value in item.items()
                if not (pattern.match(key) and value == [])  #删除键名匹配 pattern = re.compile(r'(.+)-\d+$') 且其键值为 [] 的键值对
            }
            return cleaned_dict
        elif isinstance(item, list):
            return remove_common_prefixes(item)
        else:
            return item

    temp = restructure_data(data)
    processed_data = recursive_process(temp)   #重构数据以标准化嵌套层级至三层，便于前端展示。
    return processed_data

def restructure_data(data):
    """
    重构数据以标准化嵌套层级至三层。
    - 如果所有顶层键的值都是列表（两层结构），直接返回原数据。
    - 如果存在混合的两层和三层结构，或更深层级，则将所有数据统一为三层结构。
    """
    def get_max_depth(d, current_depth=1):
        """
        计算字典的最大嵌套深度。
        """
        if not isinstance(d, dict) or not d:
            return current_depth
        return max(get_max_depth(v, current_depth + 1) for v in d.values())

    # 检查是否所有顶层键的值都是列表（即两层结构）
    all_two_layers = all(isinstance(value, list) for value in data.values())

    if all_two_layers:
        # 所有数据都是两层结构，直接返回
        return data

    # 否则，存在混合或更深层级，需要重构为三层结构
    structured_data = {}
    for key, value in data.items():
        if isinstance(value, dict):
            # 检查是否有子值是字典（即原始深度 >=4）
            has_deeper = any(isinstance(sub_value, dict) for sub_value in value.values())
            if has_deeper:
                # 如果存在更深层级，展开至三层
                for sub_key, sub_value in value.items():
                    if isinstance(sub_value, dict):
                        # 保留为三层
                        structured_data[sub_key] = sub_value
                    elif isinstance(sub_value, list):
                        # 将两层结构转换为三层结构
                        structured_data[sub_key] = {sub_key: sub_value}
                    else:
                        raise ValueError(f"键'{sub_key}'的数据格式异常: {type(sub_value)}")
            else:
                # 已经是三层结构，保持不变
                structured_data[key] = value
        elif isinstance(value, list):
            # 将两层结构转换为三层结构
            structured_data[key] = {key: value}
        else:
            raise ValueError(f"键'{key}'的数据格式异常: {type(value)}")

    # 检查重构后的数据深度
    max_depth = get_max_depth(structured_data)
    if max_depth > 3:
        # 递归调用以进一步重构
        return restructure_data(structured_data)
    else:
        return structured_data

# 定义删除公共前缀的函数
def remove_common_prefixes(string_list, min_occurrence=3):
    """
    删除列表中所有满足出现次数>= min_occurrence 的公共前缀。

    Args:
        string_list (list): 字符串列表。
        min_occurrence (int): 前缀至少出现的次数。

    Returns:
        list: 删除公共前缀后的字符串列表。
    """
    # 定义获取所有以'：'结尾的前缀的函数
    def get_prefixes(s):
        prefixes = []
        for i in range(len(s)):
            if s[i] in ['：', ':']:
                prefixes.append(s[:i + 1])
        return prefixes

    if not string_list:
        return string_list

    # 构建前缀到字符串集合的映射
    prefix_to_strings = {}
    for s in string_list:
        prefixes = get_prefixes(s)
        unique_prefixes = set(prefixes)
        for prefix in unique_prefixes:
            if prefix not in prefix_to_strings:
                prefix_to_strings[prefix] = set()
            prefix_to_strings[prefix].add(s)

    # 找出所有出现次数 >= min_occurrence 的前缀
    qualifying_prefixes = [prefix for prefix, strings in prefix_to_strings.items() if len(strings) >= min_occurrence]

    if not qualifying_prefixes:
        # 没有满足条件的公共前缀，返回原列表
        return string_list

    # 为了确保较长的前缀先被匹配，按长度降序排序
    qualifying_prefixes.sort(key=len, reverse=True)

    # 对每个字符串，循环删除所有匹配的前缀
    new_string_list = []
    for s in string_list:
        original_s = s
        changed = True
        while changed:
            changed = False
            for prefix in qualifying_prefixes:
                if s.startswith(prefix):
                    s = s[len(prefix):]
                    changed = True
                    # 一旦删除一个前缀，重新开始检查，以处理可能的多个前缀
                    break
        new_string_list.append(s)
    return new_string_list

if __name__ == "__main__":
    # 示例数据
    sample_data = {
        "★交通信号机": [
            "应采用区域控制信号机，并应与广水市交通信号控制系统兼容，信号机能接入已有系统平台，实现联网优化功能。",
            "1、控制功能：（1）区域协调控制：可对单个孤立交叉口、干道多个交叉口和关联性较强的交叉口群进行综合性地信号控制。",
            "1、控制功能：（2）线性协调控制：可对干道多个相邻交叉口进行协调控制。",
            "1、控制功能：（3）多时段控制：可根据交叉口的交通状况，将每天划分为多个不同的时段，每个时段配置不同的控制方案，能设置至少 10个时段、10种以上不同控制方案，能根据不同周日类型对方案进行调整。信号机能够根据内置时钟选择各个时段的控制方案，实现交叉口的合理控制。",
            "2、采集功能：（1）信号机支持接入线圈、地磁、视频、微波、超声波检测器、RFID等多种检测方式。",
            "2、采集功能：（2）信号机支持交通信息采集与统计,并支持交通流量共享。",
            "3、运维功能：（1）信号机能够自动检测地磁故障，若故障，能够自动上传故障信息至监控中心。"
        ],
        "▲高清视频抓拍像机": [
            "1：摄像机：有效像素：≥900W像素",
            "1：摄像机：最低照度：彩色≤0.001lx",
            "1：摄像机：传感器类型：≥1英寸全局曝光 COMS/GMOS/GS COMS",
            "1：摄像机：电子快门：至少满足 1/25s至 1/100,000s，可调",
            "2：视频图像：视频压缩标准：至少支持 H264、H265等",
            "2：视频图像：视频分辨率：≥4096×2160，向下可设置",
        ],
    }
    # 处理数据
    result = main_postprocess(sample_data)
    # 输出处理结果
    print(json.dumps(result,ensure_ascii=False,indent=4))

