"""IDS 数据共享模块。

提供 JSON 加载和 HTML 表格渲染函数，
供 render_ids_acq_map / render_ids_exc_map / render_ids_daq_reg / render_ids_awg_reg 复用。
"""

import json
from pathlib import Path
from collections import OrderedDict

# 输出顺序（先列出的模块排在前面）
ACQ_MODULE_ORDER = ["MCU_INS", "MCU_DAT", "DAQ_REG", "DAQ_PAR", "DAQ_FLT"]
EXC_MODULE_ORDER = ["MCU_INS", "MCU_DAT", "AWG_REG", "AWG_IDX", "AWG_WVE"]


# ---------- 数据加载 ----------

def _load_ids(filepath: str) -> dict:
    """加载 IDS JSON 文件并返回解析后的 dict。"""
    path = Path(filepath)
    if not path.exists():
        raise FileNotFoundError(f"IDS 文件不存在: {path}")
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


# ---------- HTML 工具 ----------

def _td(text: str, **kwargs) -> str:
    """生成 <td> 单元格，支持 rowspan / style 等属性。"""
    attrs = " ".join(f'{k}="{v}"' for k, v in kwargs.items() if v is not None)
    return f"<td {attrs}>{text}</td>" if attrs else f"<td>{text}</td>"


def _th(text: str) -> str:
    return f"<th>{text}</th>"


def _bit_range_str(bits: list) -> str:
    """将 [15, 8] 或 [7] 转为位段字符串。"""
    if len(bits) == 1:
        return str(bits[0])
    return f"{bits[0]}:{bits[-1]}"


# ---------- 映射表渲染 ----------

def render_mapping_acq_table(data: dict) -> str:
    """渲染 msmt_acq 通道模块基地址表。"""
    mi = data.get("MappingInfo", {}).get("msmt_acq", {})
    return _render_mapping_table(mi, ACQ_MODULE_ORDER, "ACQ")


def render_mapping_exc_table(data: dict) -> str:
    """渲染 msmt_exc 通道模块基地址表。"""
    mi = data.get("MappingInfo", {}).get("msmt_exc", {})
    return _render_mapping_table(mi, EXC_MODULE_ORDER, "EXC")


def _render_mapping_table(mapping: dict, module_order: list, label: str) -> str:
    """通用的通道模块基地址渲染。"""
    rows = []
    # 收集所有模块名
    all_modules = set()
    for ch_info in mapping.values():
        all_modules.update(ch_info.get("Modules", {}).keys())

    # 按 module_order 排序，未在列表中的放最后
    ordered = [m for m in module_order if m in all_modules]
    ordered += sorted(all_modules - set(module_order))

    for mod_name in ordered:
        for ch in sorted(mapping.keys(), key=int):
            info = mapping[ch]
            modules = info.get("Modules", {})
            if mod_name not in modules:
                continue
            m = modules[mod_name]
            exaddr = info.get("Exaddr", "")
            cid = info.get("Cid", "")
            rows.append(
                "<tr>"
                f"<td>ch{ch}</td>"
                f"<td>{exaddr}</td>"
                f"<td>{cid}</td>"
                f"<td><code>{mod_name}</code></td>"
                f"<td><code>{m.get('StartAddress', '')}</code></td>"
                f"<td>{m.get('Size', '')}</td>"
                f"<td>{m.get('Info', '')}</td>"
                "</tr>"
            )

    if not rows:
        return "<p>（无映射数据）</p>"

    header = (
        "<tr>"
        "<th>通道</th><th>Exaddr</th><th>Cid</th>"
        "<th>模块</th><th>起始地址</th><th>大小</th><th>说明</th>"
        "</tr>"
    )
    return f"<table>{header}{''.join(rows)}</table>"


# ---------- 寄存器表渲染 ----------

def render_daq_reg_table(data: dict) -> str:
    """渲染 DAQ_REG 寄存器汇总表 + 位域明细。"""
    regs = data.get("Modules", {}).get("DAQ_REG", {})
    return _render_reg_table(regs, "DAQ_REG")


def render_awg_reg_table(data: dict) -> str:
    """渲染 AWG_REG 寄存器汇总表 + 位域明细。"""
    regs = data.get("Modules", {}).get("AWG_REG", {})
    return _render_reg_table(regs, "AWG_REG")


def _render_reg_table(regs: dict, label: str) -> str:
    """通用寄存器表渲染（汇总表 + 每位域明细）。"""
    if not regs:
        return "<p>（无寄存器数据）</p>"

    # 按偏移地址排序
    sorted_regs = sorted(regs.values(), key=lambda r: int(r.get("OffsetAddress", "0x0"), 16))

    # ---- 汇总表 ----
    summary_rows = []
    for r in sorted_regs:
        name = list(regs.keys())[list(regs.values()).index(r)]
        offset = r.get("OffsetAddress", "")
        perm = r.get("Permission", "")
        desc = r.get("SegDescription", "")
        summary_rows.append(
            "<tr>"
            f"<td><strong>{name}</strong></td>"
            f"<td><code>{offset}</code></td>"
            f"<td>{perm}</td>"
            f"<td>{desc}</td>"
            "</tr>"
        )

    summary = (
        "<table>"
        "<tr><th>寄存器名</th><th>偏移地址</th><th>权限</th><th>描述</th></tr>"
        f"{''.join(summary_rows)}"
        "</table>"
    )

    # ---- 位域明细表（仅含字段数 > 0 的寄存器） ----
    detail_parts = []
    for r in sorted_regs:
        fields = r.get("Fields", [])
        if not fields:
            continue
        name = list(regs.keys())[list(regs.values()).index(r)]
        offset = r.get("OffsetAddress", "")

        field_rows = []
        for f in fields:
            bits = f.get("Bits", [])
            field_name = f.get("FieldName", "")
            fdesc = (f.get("FieldDescription", "") or "").replace("\n", "<br>")
            reset = f.get("ResetValue", "")
            field_rows.append(
                "<tr>"
                f"<td><code>[{_bit_range_str(bits)}]</code></td>"
                f"<td><strong>{field_name}</strong></td>"
                f"<td>{reset}</td>"
                f"<td>{fdesc}</td>"
                "</tr>"
            )

        if field_rows:
            detail_parts.append(
                f"<h4>{name}（{offset}）</h4>"
                "<table>"
                "<tr><th>位段</th><th>字段名</th><th>复位值</th><th>描述</th></tr>"
                f"{''.join(field_rows)}"
                "</table>"
            )

    if detail_parts:
        return f"{summary}<br>{''.join(detail_parts)}"
    return summary
