package com.njcn.gather.icd.mapping.pojo.bo.template;

import lombok.Data;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 默认模板模型。
 *
 * 用于承接 `DefaultCfg.txt` 解析后的配置内容，当前仅保留映射接口实际使用的字段。
 */
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class DefaultTemplate {

    /** 报告分组配置，决定 ReportMap 和前端候选分组。 */
    @JsonProperty("ReportList")
    private List<ReportCfgItem> reportList = new ArrayList<ReportCfgItem>();

    /** LN 类别配置，决定 DataSetList 的业务分组描述。 */
    @JsonProperty("LnClassList")
    private List<LnClassCfgItem> lnClassList = new ArrayList<LnClassCfgItem>();

    /** 相别配置，用于生成 sdiList 的相别描述。 */
    @JsonProperty("PhaseList")
    private List<PhaseCfgItem> phaseList = new ArrayList<PhaseCfgItem>();

    /** 倍率配置，用于从 DOI/DAI 值解析 coefficient。 */
    @JsonProperty("MultiplierList")
    private List<MultiplierCfgItem> multiplierList = new ArrayList<MultiplierCfgItem>();

    /** 单位配置，用于从 DOI/DAI 值解析 unit。 */
    @JsonProperty("UnitList")
    private List<UnitCfgItem> unitList = new ArrayList<UnitCfgItem>();

    /** 类型配置，用于识别 mag/ang 等 typeList 节点。 */
    @JsonProperty("TypeList")
    private List<TypeCfgItem> typeList = new ArrayList<TypeCfgItem>();

    /** 数据对象配置，决定每个绑定标签应生成哪些 DOI。 */
    @JsonProperty("DataObjectsList")
    private List<DataObjectCfgItem> dataObjectsList = new ArrayList<DataObjectCfgItem>();

    /**
     * 执行模板基础校验。
     *
     * 返回问题列表；为空表示校验通过。
     */
    public List<String> verify() {
        List<String> problems = new ArrayList<String>();
        ensureDuplicateNames("LnClassList", extractNames(lnClassList), problems);
        ensureDuplicateNames("PhaseList", extractNames(phaseList), problems);
        ensureDuplicateNames("MultiplierList", extractNames(multiplierList), problems);
        ensureDuplicateNames("UnitList", extractNames(unitList), problems);
        ensureDuplicateNames("TypeList", extractNames(typeList), problems);
        ensureDuplicateObjectNames(problems);
        if (reportList == null || reportList.isEmpty()) {
            problems.add("DefaultCfg.ReportList 为空");
        }
        return problems;
    }

    /**
     * 汇总配置项中的所有 nameList 名称，用于重复项校验。
     */
    private List<String> extractNames(List<? extends NameListSupport> list) {
        List<String> names = new ArrayList<String>();
        if (list == null) {
            return names;
        }
        for (NameListSupport item : list) {
            if (item.getNameList() != null) {
                names.addAll(item.getNameList());
            }
        }
        return names;
    }

    /**
     * 校验指定配置段是否存在重复名称。
     */
    private void ensureDuplicateNames(String section, List<String> names, List<String> problems) {
        Set<String> set = new HashSet<String>();
        for (String name : names) {
            if (name == null) {
                continue;
            }
            String key = name.trim();
            if (!set.add(key)) {
                problems.add(section + " 中存在重复配置项：" + key);
            }
        }
    }

    /**
     * 校验每个 DataObjectsList 分组内的对象名称是否重复。
     */
    private void ensureDuplicateObjectNames(List<String> problems) {
        if (dataObjectsList == null) {
            return;
        }
        for (DataObjectCfgItem dataObject : dataObjectsList) {
            List<String> names = new ArrayList<String>();
            if (dataObject.getObjectList() != null) {
                for (ObjectCfgItem object : dataObject.getObjectList()) {
                    if (object.getNameList() != null) {
                        names.addAll(object.getNameList());
                    }
                }
            }
            ensureDuplicateNames("DataObjectsList[" + dataObject.getDesc() + "]", names, problems);
        }
    }
    /** 统一抽象：所有包含 `nameList` 的配置项都实现该接口。 */
    public interface NameListSupport {
        List<String> getNameList();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class ReportCfgItem {

        /**
         * 报告分组描述，例如“统计数据”“实时数据”“波动闪变”。
         */
        @JsonProperty("desc")
        private String desc;

        /**
         * 报告 `inst`，例如 `01`。
         */
        @JsonProperty("inst")
        private String inst;

        /**
         * 原始配置中的 `TrgOps`，例如 `40`、`96`。
         *
         * 这里必须显式声明 `@JsonProperty("TrgOps")`，否则在当前项目中容易反序列化为 `null`。
         */
        @JsonProperty("TrgOps")
        private String trgOps;

        /**
         * 原始配置中的 `Select`，例如 `DataStatFileMap`、`DataRealFileMap`、`FlickerFileMap`。
         *
         * 这里必须显式声明 `@JsonProperty("Select")`，否则在当前项目中容易反序列化为 `null`。
         */
        @JsonProperty("Select")
        private String select;

        /**
         * 当前分组覆盖的数据集名称列表。
         */
        @JsonProperty("DataSetList")
        private List<String> dataSetList = new ArrayList<String>();

        /**
         * 当前分组允许配置的标签模板列表。
         */
        @JsonProperty("LnInstList")
        private List<String> lnInstList = new ArrayList<String>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class LnClassCfgItem implements NameListSupport {
        /** LN 类别描述。 */
        private String desc;

        /** 当前描述覆盖的 lnClass 名称列表。 */
        private List<String> nameList = new ArrayList<String>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class PhaseCfgItem implements NameListSupport {
        /** 相别中文描述。 */
        private String desc;

        /** 当前相别描述覆盖的 SDI 名称列表。 */
        private List<String> nameList = new ArrayList<String>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class MultiplierCfgItem implements NameListSupport {
        /** 倍率数值。 */
        private int multiplier;

        /** 能映射到该倍率的 DAI 值列表。 */
        private List<String> nameList = new ArrayList<String>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class UnitCfgItem implements NameListSupport {
        /** 单位描述。 */
        private String desc;

        /** 能映射到该单位的 DAI 值列表。 */
        private List<String> nameList = new ArrayList<String>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class TypeCfgItem implements NameListSupport {
        /** 类型中文描述。 */
        private String desc;

        /** 能映射到该类型的 SDI 名称列表。 */
        private List<String> nameList = new ArrayList<String>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class DataObjectCfgItem {
        /** 数据对象业务描述。 */
        private String desc;

        /** 当前数据对象配置适用的绑定标签列表。 */
        @JsonProperty("LnInstList")
        private List<String> lnInstList = new ArrayList<String>();

        /** 当前标签下需要输出的 DOI 对象配置。 */
        @JsonProperty("ObjectList")
        private List<ObjectCfgItem> objectList = new ArrayList<ObjectCfgItem>();
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    public static class ObjectCfgItem implements NameListSupport {
        /** DOI 输出描述。 */
        private String desc;

        /** 基波标志，直接写入最终 doiList.baseflag。 */
        private int baseflag;

        /** 普通 DOI 分支下的基波数量。 */
        private int basecount;

        /** queueList 分支下的队列数量。 */
        private int queuecount;

        /** 普通匹配优先使用的 DOI 名称列表。 */
        private List<String> nameList = new ArrayList<String>();

        /** nameList 未命中时才使用的 DOI 兜底名称列表。 */
        private List<String> queueList = new ArrayList<String>();
    }
}
