package org.dromara.service.mqtt;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.iot.mqtt.codec.MqttPublishMessage;
import net.dreamlu.iot.mqtt.codec.MqttQoS;
import net.dreamlu.iot.mqtt.core.server.MqttServer;
import net.dreamlu.iot.mqtt.core.server.event.IMqttMessageListener;
import net.dreamlu.iot.mqtt.core.server.model.Message;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.config.CamelRouterConfig;
import org.dromara.domain.TblSensor;
import org.dromara.domain.TblSensorRecord;
import org.dromara.domain.bo.TblSensorRecordBo;
import org.dromara.domain.vo.TblSensorRecordVo;
import org.dromara.domain.vo.TblSensorVo;
import org.dromara.service.ITblSensorRecordService;
import org.dromara.service.ITblSensorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.tio.core.ChannelContext;

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

@Service
@Slf4j
public class MqttServerMessageListener implements IMqttMessageListener {

    @Autowired
    private ITblSensorRecordService tblSensorRecordService;

    @Autowired
    private ITblSensorService tablSensorService;


    @Autowired
    private CamelRouterConfig camelRouterConfig;

    @Autowired
    private CamelContext camelContext;

    @Override
    public void onMessage(ChannelContext context, String clientId, String topic, MqttQoS qoS, MqttPublishMessage message) {
        log.info("clientId:{} message:{} payload:{}", clientId, message, new String(message.getPayload(), StandardCharsets.UTF_8));
        if(topic!=null){
            if(topic.toString().startsWith("/from/device")){
                //获取设备编号
                TblSensorVo sensorVo = null;
                JSONObject deviceData = JSONUtil.parseObj(new String(message.getPayload(), StandardCharsets.UTF_8));
                if(deviceData.getLong("id")!=null){
                    sensorVo = tablSensorService.queryById(deviceData.getLong("id"));
                }
                if(sensorVo==null){
                    log.error("系统不存在该设备！");
                    return;
                }
                if(deviceData.getJSONArray("points")!=null){
                    for(int i=0;i<deviceData.getJSONArray("points").size();i++){
                        JSONObject point = deviceData.getJSONArray("points").getJSONObject(i);
                        //设置实时值
                        String datapoints = sensorVo.getDatapoints();
                        JSONArray dataj =JSONUtil.parseArray(datapoints);
                        String pointNameLabel = "";
                        for (Object jsonObject : dataj) {
                            if(((JSONObject)jsonObject).getStr("name").equals(point.getStr("name"))){
                                pointNameLabel = ((JSONObject)jsonObject).getStr("label");
                            }
                        }


                        //save record
                        CacheUtils.put("sensorData","sensor_"+sensorVo.getId()+point.getStr("name"),point);
                        TblSensorRecordBo bo = new TblSensorRecordBo();
                        bo.setPointName(point.getStr("name"));
                        bo.setPointValue(point.getStr("value"));
                        bo.setSensorId(sensorVo.getId());
                        bo.setCreateTime(DateUtil.date());
                        bo.getParams().put("sensorName",sensorVo.getName());
                        bo.getParams().put("pointLabel",pointNameLabel);
                        bo.getParams().put("datetime",DateUtil.format(DateUtil.date(), "YYYY_MM"));
                        if(tblSensorRecordService.insertByBo(bo)){
                            //保存成功
                            log.debug("保存数据成功");
                        }
                        process(sensorVo,bo);

                    }

                }

            }
        }
    }

    public void process(TblSensorVo sensorVo,TblSensorRecordBo bo){

        Map<String,Boolean> map = new HashMap<>(Map.of("allDevice", false, "typeDevice_" + sensorVo.getSensorType(), false, "device_" + sensorVo.getId(), false));
        //设备数据
        ProducerTemplate template  = camelContext.createProducerTemplate();
        camelContext.getRoutes().stream().forEach(route -> {
            System.out.println(route.getEndpoint());
            for (String key : map.keySet()) {
                if(route.getEndpoint().toString().contains(key)){
                    map.put(key,true);
                }
            }

        });

        //发送所有设备数据
        for (String key : map.keySet()) {
            if(map.get(key)){
                try {
                template.sendBody(StrUtil.format("direct:{}",key),JSONUtil.toJsonStr(bo));
                }catch (Exception e){}
            }

        }



    }

//    @PostConstruct
//    public void init(){
//        //监听配置mqtt所有数据
//        String xmlstring = "<routes xmlns=\"http://camel.apache.org/schema/spring\"> <route id=\"insertAlarm\">\n" +
//                "        <from uri=\"direct:insertAlarm\"></from>\n" +
//                "        <to uri=\"bean:ruleProcess?method=insertAlarm\"></to>\n" +
//                "    </route></routes>";
//
//    }
}