#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：topic_templates.py
模块描述：设备类型 MQTT 主题模板定义

每种设备类型定义一组固定主题模板，包含动态参数占位符。
模拟器启动时用 topic_params 替换占位符，生成实际主题。

作者：czj
创建日期：2026-08-03
最后修改：2026-08-03
"""

from typing import Dict, List

# 主题模板结构说明：
# - key: 模板唯一标识
# - template: 主题路径模板（含 {param} 占位符）
# - label: 中文标签
# - params: 需要填写的动态参数名列表
# - param_labels: 参数名 -> 中文标签映射
# - param_defaults: 参数名 -> 默认值映射
# - direction: publish（上报）/ subscribe（接收/订阅）

DEVICE_TOPIC_TEMPLATES: Dict[str, List[dict]] = {
    "door": [
        # ========== 上报主题（publish）==========
        {
            "key": "reboot_response",
            "template": "rebootResponseTopic",
            "label": "重启响应",
            "params": [],
            "param_labels": {},
            "param_defaults": {},
            "direction": "publish",
        },
        {
            "key": "android_broadcast",
            "template": "/uams/android/broadcast",
            "label": "安卓广播",
            "params": ["device_id"],
            "param_labels": {"device_id": "设备ID"},
            "param_defaults": {"device_id": "DS001"},
            "direction": "publish",
        },
        # ========== 订阅主题（subscribe）==========
        {
            "key": "conference",
            "template": "/meeting/conference/{room_id}/",
            "label": "会议信息",
            "params": ["room_id"],
            "param_labels": {"room_id": "会议室编号"},
            "param_defaults": {"room_id": "A101"},
            "direction": "subscribe",
        },
        {
            "key": "material_client",
            "template": "/material/client/{device_id}/",
            "label": "物料客户端",
            "params": ["device_id"],
            "param_labels": {"device_id": "设备ID"},
            "param_defaults": {"device_id": "DS001"},
            "direction": "subscribe",
        },
        {
            "key": "conference_service_request",
            "template": "/iot/v1/conference/service/request/{company_id}/{room_id}/",
            "label": "会议服务请求",
            "params": ["company_id", "room_id"],
            "param_labels": {"company_id": "公司编号", "room_id": "会议室编号"},
            "param_defaults": {"company_id": "001", "room_id": "A101"},
            "direction": "subscribe",
        },
        {
            "key": "face_extract",
            "template": "/doorscreen/v5/{device_id}/face/extractFeature/imageBase64/list/up",
            "label": "人脸特征提取",
            "params": ["device_id"],
            "param_labels": {"device_id": "设备ID"},
            "param_defaults": {"device_id": "DS001"},
            "direction": "subscribe",
        },
        {
            "key": "radar_event",
            "template": "/iot/v1/device/event/request/millimeterhaveRadar/{room_id}/",
            "label": "毫米波雷达事件",
            "params": ["room_id"],
            "param_labels": {"room_id": "会议室编号"},
            "param_defaults": {"room_id": "A101"},
            "direction": "subscribe",
        },
        {
            "key": "meeting_message",
            "template": "/meeting/message/{room_id}/",
            "label": "会议消息",
            "params": ["room_id"],
            "param_labels": {"room_id": "会议室编号"},
            "param_defaults": {"room_id": "A101"},
            "direction": "subscribe",
        },
        {
            "key": "device_service_request",
            "template": "/iot/v1/device/service/request/{company_id}/{device_id}/",
            "label": "设备服务请求",
            "params": ["company_id", "device_id"],
            "param_labels": {"company_id": "公司编号", "device_id": "设备ID"},
            "param_defaults": {"company_id": "001", "device_id": "DS001"},
            "direction": "subscribe",
        },
    ],
    "paperless": [
        # ========== 上报主题（publish）==========
        {
            "key": "reboot_response",
            "template": "rebootResponseTopic",
            "label": "重启响应",
            "params": [],
            "param_labels": {},
            "param_defaults": {},
            "direction": "publish",
        },
        {
            "key": "android_broadcast",
            "template": "/uams/android/broadcast",
            "label": "安卓广播",
            "params": ["device_id"],
            "param_labels": {"device_id": "设备ID"},
            "param_defaults": {"device_id": "PS001"},
            "direction": "publish",
        },
        {
            "key": "meeting_message",
            "template": "/meeting/message/{room_id}/",
            "label": "会议消息",
            "params": ["room_id"],
            "param_labels": {"room_id": "会议室编号"},
            "param_defaults": {"room_id": "A101"},
            "direction": "publish",
        },
        {
            "key": "meeting_control",
            "template": "/iot/v1/meeting/service/request/meetingControl/{company_id}/{mid}/",
            "label": "会议控制",
            "params": ["company_id", "mid"],
            "param_labels": {"company_id": "公司编号", "mid": "会议ID"},
            "param_defaults": {"company_id": "001", "mid": "M001"},
            "direction": "publish",
        },
        {
            "key": "android_panel",
            "template": "/androidPanel/",
            "label": "安卓面板",
            "params": [],
            "param_labels": {},
            "param_defaults": {},
            "direction": "publish",
        },
        {
            "key": "paperless_service",
            "template": "/message/paperLessService/callService",
            "label": "无纸化服务调用",
            "params": [],
            "param_labels": {},
            "param_defaults": {},
            "direction": "publish",
        },
        # ========== 订阅主题（subscribe）==========
        {
            "key": "meeting_service_request",
            "template": "/iot/v1/meeting/service/request/{room_id}/",
            "label": "会议服务请求",
            "params": ["room_id"],
            "param_labels": {"room_id": "会议室编号"},
            "param_defaults": {"room_id": "A101"},
            "direction": "subscribe",
        },
    ],
    "central": [],   # 暂无真实主题，保留旧格式
    "client": [],    # 暂无真实主题，保留旧格式
}


def get_topic_templates(device_type: str) -> List[dict]:
    """
    获取指定设备类型的主题模板列表

    Args:
        device_type: 设备类型 (door/paperless/central/client)

    Returns:
        List[dict]: 主题模板列表
    """
    return DEVICE_TOPIC_TEMPLATES.get(device_type, [])


def has_real_topics(device_type: str) -> bool:
    """
    判断设备类型是否有真实主题模板

    Args:
        device_type: 设备类型

    Returns:
        bool: 是否有真实主题模板
    """
    return bool(DEVICE_TOPIC_TEMPLATES.get(device_type, []))


def resolve_topic(template: str, params: dict) -> str:
    """
    解析主题模板，用参数值替换占位符

    Args:
        template: 主题模板，如 "/meeting/conference/{room_id}/"
        params: 参数值映射，如 {"room_id": "A101"}

    Returns:
        str: 解析后的实际主题，如 "/meeting/conference/A101/"
    """
    result = template
    for key, value in params.items():
        result = result.replace(f"{{{key}}}", str(value))
    return result


def resolve_all_topics(device_type: str, topic_params: dict) -> Dict[str, dict]:
    """
    解析设备类型的所有主题模板

    Args:
        device_type: 设备类型
        topic_params: 参数值映射

    Returns:
        Dict[str, dict]: 解析后的主题映射，key 为模板 key，value 包含:
            - topic: 解析后的实际主题
            - direction: 方向
            - label: 中文标签
            - template: 原始模板
    """
    templates = get_topic_templates(device_type)
    resolved = {}
    for tmpl in templates:
        resolved[tmpl["key"]] = {
            "topic": resolve_topic(tmpl["template"], topic_params or {}),
            "direction": tmpl["direction"],
            "label": tmpl["label"],
            "template": tmpl["template"],
        }
    return resolved


def get_default_params(device_type: str) -> dict:
    """
    获取设备类型的默认参数值

    Args:
        device_type: 设备类型

    Returns:
        dict: 默认参数值映射
    """
    templates = get_topic_templates(device_type)
    defaults = {}
    for tmpl in templates:
        for param_key, default_val in tmpl.get("param_defaults", {}).items():
            if param_key not in defaults:
                defaults[param_key] = default_val
    return defaults
