package com.xydl.cac.transform;

import com.xydl.cac.entity.*;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.model.i2sync.Attr;
import com.xydl.cac.model.i2sync.Datanode;
import com.xydl.cac.model.i2sync.Monitordata;
import com.xydl.cac.model.i2sync.Request;
import com.xydl.cac.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@Slf4j
public class I2DataTransformer {

    public Request transform(NSensor sensor, I2syncRecord record, I2syncConfig config,
                             List<I2syncField> fieldList, List<Map<String, Object>> dataList) throws Exception {

        // 查到可用规则
        List<WarnRule> ruleList = new ArrayList<>();
        Iterator<Integer> it = StaticVariable.rule_Cache.keySet().iterator();
        while (it.hasNext()) {
            Integer key = it.next();
            WarnRule rule = StaticVariable.rule_Cache.get(key);
            if (rule.canDo() && rule.getSensorId().equals(sensor.getId())) {
                ruleList.add(rule);
            }
        }

        LinkedHashMap<String, List<I2syncField>> fieldMap = this.sortFieldList(fieldList);

        List<Datanode> nodeList = new ArrayList<>();
        for (Map<String, Object> map : dataList) {

            Iterator<String> fit = fieldMap.keySet().iterator();
            while (fit.hasNext()) {
                String attach = fit.next();
                List<I2syncField> fieldListNew = fieldMap.get(attach);

                Datanode node = this.buildDatanode(sensor, config.getTypeCode(), attach,
                        fieldListNew, map, ruleList);
                if (node != null) {
                    nodeList.add(node);
                    record.setLastDTime(DateUtil.parse(node.getTimestamp()));
                }
            }
        }

        Monitordata monitordata = new Monitordata();
        monitordata.setCacid(sensor.getSensorCode());
        monitordata.setDatanodenum(nodeList.size());
        monitordata.setDatanode(nodeList);
        Request request = new Request();
        request.setMonitordata(monitordata);
        return request;
    }

    private Datanode buildDatanode(NSensor sensor, String typeCode, String attach,
                                   List<I2syncField> fieldList, Map<String, Object> dataMap,
                                   List<WarnRule> ruleList) {
        List<Attr> attrs = new ArrayList<>();
        for (I2syncField field : fieldList) {
            Object value = dataMap.get(field.getFieldName());
            if (value != null) {
                Attr attr = new Attr();
                attr.setName(field.getDestFieldName());
                attr.setValue(String.valueOf(value));
                if (this.triggerRule(ruleList, field.getFieldName(), value)) {
                    attr.setAlarm("TRUE");
                } else {
                    attr.setAlarm("FALSE");
                }
                attrs.add(attr);
            }
        }
        if (attrs.size() < 1) {
            return null;
        }
        String date = (String) dataMap.get("acquisitionTime");
        Datanode node = new Datanode();
        node.setType(typeCode);
        node.setTimestamp(date);
        node.setAttr(attrs);

        Attr attr = new Attr();
        attr.setName("Phase");
        attr.setAlarm("FALSE");
        attrs.add(attr);
        if (StringUtils.isBlank(attach)) {
            attr.setValue(sensor.getPhase());
            node.setSensorid(sensor.getSensorCode());
            node.setEquipmentid(sensor.getEquipmentId());
        } else {
            attr.setValue("");
            String code = sensor.getSensorCode();
            node.setSensorid(code);
            if (code != null && code.length() > attach.length() + 2) {
                int len = code.length() - 2;
                String tail = code.substring(len);
                String first = code.substring(0, len - attach.length());
                node.setSensorid(first + attach + tail);
            }
            String equipmentid = sensor.getEquipmentId();
            node.setEquipmentid(equipmentid);
            if (equipmentid != null && equipmentid.length() > attach.length() + 2) {
                int len = equipmentid.length() - 2;
                String tail = equipmentid.substring(len);
                String first = equipmentid.substring(0, len - attach.length());
                node.setEquipmentid(first + attach + tail);
            }
        }
        return node;
    }

    private LinkedHashMap<String, List<I2syncField>> sortFieldList(List<I2syncField> fieldList) {
        LinkedHashMap<String, List<I2syncField>> map = new LinkedHashMap<>();
        for (I2syncField item : fieldList) {
            String attach = item.getAttach();
            if (attach == null) {
                attach = "";
            }
            List<I2syncField> list = map.get(attach);
            if (list == null) {
                list = new ArrayList<>();
                map.put(attach, list);
            }
            list.add(item);
        }
        return map;
    }

    private boolean triggerRule(List<WarnRule> ruleList, String fieldName, Object value) {
        for (WarnRule rule : ruleList) {
            if (rule.getTypePoint().getField().equalsIgnoreCase(fieldName)) {
                boolean r = rule.triggerRule(value);
                if (r) {
                    return true;
                }
            }
        }
        return false;
    }
}
