package iot.lidee.gryyjson.json;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import iot.lidee.common.annotation.SysProtocol;
import iot.lidee.common.constant.LideeConstant;
import iot.lidee.common.core.mq.DeviceReport;
import iot.lidee.common.core.mq.MQSendMessageBo;
import iot.lidee.common.core.mq.message.DeviceData;
import iot.lidee.common.core.mq.message.FunctionCallBackBo;
import iot.lidee.common.core.thingsModel.ThingsModelSimpleItem;
import iot.lidee.common.exception.ServiceException;
import iot.lidee.common.utils.DateUtils;
import iot.lidee.iot.model.ThingsModels.ValueItem;
import iot.lidee.protocol.base.protocol.IProtocol;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gsb
 * @date 2022/10/10 16:55
 */
@Slf4j
@Component
@SysProtocol(name = "国瑞药业JsonObject解析协议", protocolCode = LideeConstant.PROTOCOL.GryyJson, description = "系统内置国瑞药业JsonObject解析协议")
public class GryyJsonProtocolService implements IProtocol {

    /**
     * 上报数据格式 <p>
     * [
     *   {
     *     "id": "switch",
     *     "value": "0"
     *   },
     *   {
     *     "id": "gear",
     *     "value": "0"
     *   }
     * ]
     */
    @Override
    public DeviceReport decode(DeviceData deviceData, String clientId) {
        try {
            DeviceReport reportMessage = new DeviceReport();
            // bytep[] 转String

            //获取国瑞设备名称--此协议只有国瑞药业使用
            String[] devArr= clientId.split("-");

            String data = new String(deviceData.getData(), StandardCharsets.UTF_8);
            JSONObject  valueJson = JSON.parseObject(data).getJSONObject("values");
            data=valueJson.getString(devArr[1]);
            // 移除第一个和最后一个字符
            data=JsonObjectToArray(data).toString();
            List<ThingsModelSimpleItem> values = JSON.parseArray(data, ThingsModelSimpleItem.class);
            //上报数据时间
            for (ThingsModelSimpleItem value : values) {
                value.setTs(DateUtils.getNowDate());
            }
            reportMessage.setThingsModelSimpleItem(values);
            reportMessage.setClientId(clientId);
            reportMessage.setSerialNumber(clientId);
            reportMessage.setSources(data);
            return reportMessage;
        } catch (Exception e) {
            throw new ServiceException("数据解析异常" + e);
        }
    }


    /**
     * 下发 [{"id":"switch","value":"0","remark":""}]
     *
     * @param message
     * @return
     */
    @Override
    public FunctionCallBackBo encode(MQSendMessageBo message) {
        try {
            FunctionCallBackBo callBack = new FunctionCallBackBo();
            JSONObject params = message.getParams();
            ValueItem valueItem = new ValueItem();
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                valueItem.setId(entry.getKey());
                valueItem.setValue(entry.getValue() + "");
                valueItem.setRemark("");
            }
            String msg = "[" + JSONObject.toJSONString(valueItem) + "]";
            callBack.setSources(msg);
            callBack.setMessage(msg.getBytes());
            return callBack;
        } catch (Exception e) {
            log.error("=>指令编码异常,device={},data={}", message.getSerialNumber(),
                    message.getParams());
            return null;
        }
    }


    /**
     * 将嵌套的 JSON 对象转换为 JSON 数组，并进行字段映射
     * 字段映射规则：raw_data -> value, timestamp -> remark
     */
    public static JSONArray JsonObjectToArray(String jsonStr) {
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        JSONArray jsonArray = new JSONArray();

        // 字段映射关系
        Map<String, String> fieldMapping = new HashMap<>();
        fieldMapping.put("raw_data", "value");
        fieldMapping.put("timestamp", "remark");

        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            JSONObject item = new JSONObject();
            // 添加 id 字段，值为原对象的 key
            item.put("id", entry.getKey());

            // 处理原对象的属性，进行字段映射
            JSONObject valueObj = (JSONObject) entry.getValue();
            for (Map.Entry<String, Object> propEntry : valueObj.entrySet()) {
                String fieldName = propEntry.getKey();
                Object fieldValue = propEntry.getValue();

                // 根据映射关系转换字段名
                if (fieldMapping.containsKey(fieldName)) {
                    item.put(fieldMapping.get(fieldName), fieldValue);
                } else {
                    // 保持原字段名不变
                    item.put(fieldName, fieldValue);
                }
            }

            jsonArray.add(item);
        }

        return jsonArray;
    }
}
