package com.njcn.gather.report.pojo.constant;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * "指标锚点"新型模板的书签命名空间常量。
 * 设计文档：docs/superpowers/specs/2026-07-02-item-anchor-report-template-design.md §3.1
 *
 * @author hongawen
 */
public interface ItemAnchorConstant {

    /** 数据锚点书签前缀：item_{scriptCode}，锚点处按回路插入检测数据表 */
    String ITEM_PREFIX = "item_";

    /** 区段书签前缀：sect_{scriptCode} / sect_{GRP_XXX}，指标无数据时整段删除 */
    String SECT_PREFIX = "sect_";

    /**
     * 父节 → 子节 scriptCode 映射；一个父节的全部子节都隐藏时，父节（组标题+组内公共文字）一并隐藏。
     * key 与模板中 sect_GRP_* 书签名的 GRP_* 部分一致。
     */
    Map<String, List<String>> GRP_CHILDREN = buildGrpChildren();

    /**
     * 已知指标 scriptCode 白名单（规范大写，即云南模板 11 个锚点）。
     * 分流与锚点解析以此为准：白名单外的 item_* 书签一律视为无效，防止老模板中
     * 作者手工遗留的同前缀书签（如 item_1）把整份报告误路由进新路径。
     */
    Set<String> KNOWN_SCRIPT_CODES = buildKnownScriptCodes();

    static Map<String, List<String>> buildGrpChildren() {
        Map<String, List<String>> map = new LinkedHashMap<>();
        map.put("GRP_FUND", Arrays.asList("V", "I", "P", "ANGLE"));
        map.put("GRP_UNB", Arrays.asList("IMBV", "IMBA"));
        map.put("GRP_HARM", Arrays.asList("HV", "HI", "HP"));
        return Collections.unmodifiableMap(map);
    }

    static Set<String> buildKnownScriptCodes() {
        return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(
                "V", "I", "P", "ANGLE", "FREQ", "F", "IMBV", "IMBA", "HV", "HI", "HP")));
    }

    /**
     * 从书签名解析指标锚点的 scriptCode。
     *
     * @param bookmarkName 书签名
     * @return 规范大写 scriptCode（scriptMap / 模板 H5 分组 key 均为大写）；
     *         非 item_ 前缀、空 code 或不在 {@link #KNOWN_SCRIPT_CODES} 白名单内返回 null
     */
    static String resolveItemScriptCode(String bookmarkName) {
        if (bookmarkName == null || bookmarkName.length() <= ITEM_PREFIX.length()) {
            return null;
        }
        if (!bookmarkName.substring(0, ITEM_PREFIX.length()).equalsIgnoreCase(ITEM_PREFIX)) {
            return null;
        }
        String code = bookmarkName.substring(ITEM_PREFIX.length()).toUpperCase();
        return KNOWN_SCRIPT_CODES.contains(code) ? code : null;
    }
}
