package com.persagy.dmp.rwd.iot.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.dmp.common.context.AppContext;
import com.persagy.dmp.rwd.basic.constant.IotUrlConstant;
import com.persagy.dmp.rwd.basic.utils.MeterUtils;
import com.persagy.dmp.rwd.iot.model.history.InfoCodeModel;
import com.persagy.dmp.rwd.iot.model.history.RequestModel;
import com.persagy.dmp.rwd.iot.service.HistoryIotService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * iot-查询历史数据/分精度数据
 * @author:linhuili
 * @date:2021/8/11
 */
@Service
public class HistoryIotServiceImpl implements HistoryIotService {

    @Autowired
    private CurrentIotServiceImpl currentDataService;

    @Value("${persagy.iot.data.server}")
    private String iotDataServer;
    /**
     * 查询历史数据/分精度数据
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public List<InfoCodeModel> getHistoryData(RequestModel request) throws Exception {
        List<InfoCodeModel> params = request.getParams();
        //信息点校验
        ArrayNode pointList = JsonNodeFactory.instance.arrayNode();
        for (InfoCodeModel param : params) {
            param.setStatus("success");
            checkParam(param, pointList);
        }
        if (pointList.size() == 0) {
            return params;
        }

        //转换为iot请求参数
        ObjectNode requestNode = JsonNodeFactory.instance.objectNode();
        requestNode.put("building", AppContext.getContext().getProjectId().substring(2));
        for (JsonNode jsonNode : pointList) {
            ObjectNode item = (ObjectNode) jsonNode;
            item.put("time_period", request.getPeriod());
            item.put("time_from", request.getStartTime());
            item.put("time_to", request.getEndTime());
        }
        requestNode.set("points", pointList);

        //查询对象绑点信息点的历史数据
        String url = iotDataServer + IotUrlConstant.QUERY_HISTORY_DATA;
        String response = HttpUtil.post(url, requestNode.toString(), 30000);
        JSONObject object = JSONObject.parseObject(response);
        if(object == null){
            return params;
        }
        JSONArray points = object.getJSONArray("points");
        handleIotHisQueryReuslt(params,points);

        return params;
    }


    /**
     * iot历史数据查询结果封装
     * @param params
     * @param points
     */
    private void handleIotHisQueryReuslt(List<InfoCodeModel> params ,JSONArray points){
        if(points == null || points.size()<=0){
            return;
        }
        for (Object point : points) {
            JSONObject meterItem = (JSONObject) point;
            String meter = meterItem.getString("meter");
            String function = meterItem.getString("funcid") + "";
            for (InfoCodeModel param : params) {
                if (!(meter + "-" + function).equals(param.getMeter() + "-" + param.getFunction())) {
                    continue;
                }

                JSONArray data = new JSONArray();
                JSONArray datas = meterItem.getJSONArray("datas");
                if (datas != null && datas.size() > 0) {
                    for (Object jsonNode : datas) {
                        JSONObject dataItem = (JSONObject) jsonNode;
                        JSONObject item = new JSONObject();
                        item.put("time", dataItem.getString("data_time"));
                        item.put("data", dataItem.getDouble("data_value"));
                        data.add(item);
                    }
                }
                param.setData(data);
            }
        }
    }


    /**
     * 信息点校验
     * @param param
     * @param pointList
     * @throws Exception
     */
    private void checkParam(InfoCodeModel param, ArrayNode pointList) throws Exception {
        String objectId = param.getObjectId();
        if (objectId == null) {
            param.setStatus("error");
            param.setError("objectId is not required");
            return;
        }
        String infoCode = param.getInfoCode();
        if (infoCode == null) {
            param.setStatus("error");
            param.setError("infoCode is not required");
            return;
        }
        String classCode = currentDataService.getInfoCodeValue(objectId, "classCode");
        if (classCode == null) {
            param.setStatus("error");
            param.setError("对象不存在或已失效");
            return;
        }

        String infoCodeValue = currentDataService.getInfoCodeValue(objectId, infoCode);
        if (infoCodeValue == null) {
            param.setStatus("error");
            param.setError("value of infoCode[" + objectId + ":" + infoCode + "] is null");
            return;
        }
        // 判断信息点的值是不是表号-功能号格式
        if (!MeterUtils.matchFormat(infoCodeValue)) {
            param.setStatus("error");
            param.setError("value of infoCode[" + objectId + ":" + infoCode + "][ " + infoCodeValue + "] 不是正确的表号功能号");
            return;
        }

        int idx = infoCodeValue.lastIndexOf("-");
        if (idx == -1) {

        } else {
            String meter = infoCodeValue.substring(0, idx);
            String function = infoCodeValue.substring(idx + 1);
            param.setMeter(meter);
            param.setFunction(function);
            ObjectNode point = pointList.addObject();
            point.put("meter", meter);
            point.put("funcid", Long.parseLong(function));
        }
    }

}
