package com.fastbee.iot.timer;//package com.fastbee.farming;

import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.core.redis.RedisKeyBuilder;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.json.JsonUtils;
import com.fastbee.iot.cache.DeviceCacheConstants;
import com.fastbee.iot.cache.ITSLCache;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.httpclient.HttpAPIController;
import com.fastbee.iot.httpclient.HttpResultDTO;
import com.fastbee.iot.model.ThingsModels.PropertyDto;
import com.fastbee.iot.model.haiwei.bo.HaiWeiBo;
import com.fastbee.iot.model.haiwei.HaiWeiDeviceInfoVo;
import com.fastbee.iot.model.haiwei.HaiWeiPropertyVo;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.iot.tdengine.service.model.TdLogDto;
import com.fastbee.waterele.domain.MaWatereleRecord;
import com.fastbee.waterele.service.IMaWatereleRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.fastbee.iot.enums.ProductTypeEnum.*;

@Component("qxtrTask")
@Slf4j
public class QxtrTask {

    @Autowired
    private IDeviceService iDeviceService;
    @Resource
    private ITSLCache itslCache;
    @Autowired
    private ILogService iLogService;
    @Resource
    RedisCache redisCache;
    @Resource
    private IMaWatereleRecordService watereleRecordService;
    private static Pattern pattern = Pattern.compile("[-+]?[0-9]+(\\.[0-9]+)?$");

    /**
     * 定时任务 新增太阳能设备
     */
    public void getSolarDeviceFromHttp() throws Exception {
//        log.info("定时任务，新增 太阳能设备 数据");
        Device device = new Device();
        device.setProductId(Long.valueOf(SOLAR_DEVICE.getType()));
        List<Device> devices = iDeviceService.selectDeviceList(device);
        getDeviceInfo(Long.valueOf(SOLAR_DEVICE.getType()), devices);
    }

    /**
     * 定时任务 更新设备在线状态
     */
    public void updateDeviceStatus() throws Exception {
//        log.info("定时任务，更新设备在线状态");
        Device device = new Device();
        ArrayList<Map<String, Object>> resultList = new ArrayList<>();
        device.setProductId(136L);
        List<Device> deviceList = iDeviceService.selectDeviceList(device);
        for (Device item : deviceList) {
            MaWatereleRecord maWatereleRecord = new MaWatereleRecord();
            maWatereleRecord.setDevSn(item.getSerialNumber());
            List<MaWatereleRecord> list  = watereleRecordService.getList(maWatereleRecord);
            int status = 4;
            if(list.size() > 0){
                MaWatereleRecord record = list.get(0);
                if(new Date().getTime() - record.getCreateTime().getTime() < 3600000){
                    status = 3;
                }
            }
            item.setStatus(status);
            iDeviceService.updateDevice(item);
        }
    }



    /**
     * 定时任务 流量计设备
     */
    public void getFlowMeterDeviceFromHttp() throws Exception {
//        log.info("定时任务，新增 流量计设备 数据");
        Device device = new Device();
        device.setProductId(Long.valueOf(FLOW_METER_DEVICE.getType()));
        List<Device> devices = iDeviceService.selectDeviceList(device);
        getDeviceInfo(Long.valueOf(FLOW_METER_DEVICE.getType()), devices);
    }

    /**
     * 定时任务 门锁控制设备
     */
    public void getDoorLockDeviceFromHttp() throws Exception {
//        log.info("定时任务，新增 门锁控制设备 数据");
        Device device = new Device();
        device.setProductId(Long.valueOf(DOOR_LOCK_DEVICE.getType()));
        List<Device> devices = iDeviceService.selectDeviceList(device);
        getDeviceInfo(Long.valueOf(DOOR_LOCK_DEVICE.getType()), devices);
    }

    /*//////////////////////////////////////////////////////////////////////////////////////////////////////*/

    public void getDeviceInfo(Long productId, List<Device> devices) {
        Date createTime = new Date();
        getDeviceInfoFromHttp(productId, devices, createTime);
    }

    public void getDeviceInfoFromHttp(Long productId, List<Device> devices, Date createTime) {
        String url = "https://cloud.haiwell.com/api/project/machine/datagroup/getTagsValue";
        com.alibaba.fastjson2.JSONObject thingsModelObject =
                com.alibaba.fastjson2.JSONObject.parseObject(itslCache.getCacheThingsModelByProductId(productId));
        com.alibaba.fastjson2.JSONArray thingsList = thingsModelObject.getJSONArray("properties");
            List<PropertyDto> properties = thingsList.toList(PropertyDto.class);
        Map<String, List<PropertyDto>> stringListMap =
                properties.stream().collect(Collectors.groupingBy(PropertyDto::getGroup));
        for (Device device : devices) {
            try {
                Map<String, String> devParams = getDevParams(device);
                HaiWeiBo haiWeiBo = new HaiWeiBo();
                haiWeiBo.setAccount(devParams.get("account"));
                haiWeiBo.setMachineCode(devParams.get("machineCode"));
                haiWeiBo.setPrivateKey(devParams.get("privateKey"));
                haiWeiBo.setWebapiKey(devParams.get("webapiKey"));
                Map<String, String> mapAll = new HashMap<>();
                for (String group : stringListMap.keySet()) {
                    List<PropertyDto> propertyDtos = stringListMap.get(group);
                    haiWeiBo.setGroupTag(group);
                    String[] tags = new String[propertyDtos.size()];
                    for (int i = 0; i < propertyDtos.size(); i++) {
                        tags[i] = propertyDtos.get(i).getId();
                    }
                    haiWeiBo.setTags(tags);
                    HttpResultDTO duhttpResultDTO =
                            HttpAPIController.doPostWithJsonParamAndHeaders(url, JsonUtils.toJsonString(haiWeiBo),
                            new HashMap<>());
                    if (null != duhttpResultDTO && duhttpResultDTO.getCode() == 200) {
                        Object object = com.alibaba.fastjson.JSON.parse(duhttpResultDTO.getBody());    //先转换成Object
                        Object map = ((Map<String, String>) object).get("result");
                        if(!ObjectUtils.isEmpty(map)) {
                            Object map1 = ((Map<String, String>) map).get("data");
                            mapAll.putAll((Map<String, String>) map1);
                        }
                    }
                }
                setCacheOrDb(device, mapAll, properties);
            } catch (Exception e) {
                log.error("getDeviceInfoFromHttp error", e);
            }
        }
    }

    private void setCacheOrDb(Device deviceEntity, Map<String, String> map, List<PropertyDto> propertyDtos) {
        HaiWeiDeviceInfoVo haiWeiDeviceInfoVo = new HaiWeiDeviceInfoVo();
        List<HaiWeiPropertyVo> propertyList = new ArrayList<>();
        haiWeiDeviceInfoVo.setDeviceId(deviceEntity.getDeviceId());
        haiWeiDeviceInfoVo.setSerialNumber(deviceEntity.getSerialNumber());
        haiWeiDeviceInfoVo.setDeviceName(deviceEntity.getDeviceName());
        haiWeiDeviceInfoVo.setReceiveTime(new Date());
        haiWeiDeviceInfoVo.setOnline(true);

        for (PropertyDto propertyDto : propertyDtos) {
            HaiWeiPropertyVo haiWeiPropertyVo = new HaiWeiPropertyVo();
            haiWeiPropertyVo.setModelId(Long.valueOf(propertyDto.getModelId()));
            haiWeiPropertyVo.setNameCn(propertyDto.getName());
            haiWeiPropertyVo.setNameEn(propertyDto.getId());
            com.alibaba.fastjson2.JSONObject datatype = propertyDto.getDatatype();
            Object type = datatype.get("type");
            //值类型如果是枚举
            if ("enum".equals(type)) {
                ArrayList<Map> enumList = (ArrayList) datatype.get("enumList");
                HashMap<String, String> a = new HashMap<>();
                for (Map map1 : enumList) {
                    a.put((String) map1.get("value"), (String) map1.get("text"));
                }
                haiWeiPropertyVo.setEnumMap(a);
            } else {
                haiWeiPropertyVo.setUnit((String) datatype.get("unit"));
            }
            String s = map.get(propertyDto.getId());
            //拿到属性值
            if (!ObjectUtils.isEmpty(s)) {
                //值为数字，取小数点后两位
                boolean matches = pattern.matcher(s).matches();
                if (matches) {
                    BigDecimal roundedNumber = new BigDecimal(Double.valueOf(s)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    s = String.valueOf(roundedNumber);
                }
                haiWeiPropertyVo.setValue(s);
            } else {
                haiWeiPropertyVo.setValue("");
            }
            haiWeiPropertyVo.setValueAndUnit(haiWeiPropertyVo.getValue() + haiWeiPropertyVo.getUnit());
            propertyList.add(haiWeiPropertyVo);
        }
        haiWeiDeviceInfoVo.setPropertyList(propertyList);
        //插入缓存
        redisCache.setCacheObject(DeviceCacheConstants.getDeviceLogKey(deviceEntity.getDeviceId().toString()), haiWeiDeviceInfoVo);
        //插入数据库
        List<DeviceLog> deviceLogEntityList = new ArrayList<>();
        for (HaiWeiPropertyVo waterFertilizePropertyVo : propertyList) {
            DeviceLog deviceLogEntity = new DeviceLog();
            deviceLogEntity.setLogValue(waterFertilizePropertyVo.getValue().toString());
            deviceLogEntity.setIdentity(waterFertilizePropertyVo.getNameEn());
            deviceLogEntity.setModelName(waterFertilizePropertyVo.getNameCn());
            deviceLogEntity.setDeviceId(deviceEntity.getDeviceId());
            deviceLogEntity.setSerialNumber(deviceEntity.getSerialNumber());
            deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
            deviceLogEntity.setLogType(1);
            deviceLogEntity.setCreateTime(new Date());
            deviceLogEntity.setIsMonitor(0);
            deviceLogEntity.setMode(2);
            deviceLogEntityList.add(deviceLogEntity);
            redisCache.zSetAdd(RedisKeyBuilder.buildDeviceOnlineListKey(), deviceLogEntity.getSerialNumber(), DateUtils.getTimestampSeconds());
        }
        if (deviceLogEntityList.size() > 0) {
            String key = DeviceCacheConstants.getDeviceInsertDb(deviceEntity.getDeviceId());
            Object cacheObject = redisCache.getCacheObject(key);
            //1分钟插入数据库一次
            if (null == cacheObject) {
                redisCache.setCacheObject(key, 0, 1, TimeUnit.MINUTES);
                TdLogDto dto = new TdLogDto();
                dto.setSerialNumber(deviceEntity.getSerialNumber());
                dto.setList(deviceLogEntityList);
                iLogService.saveBatch(dto);
            }
        }

    }

    public Map<String, String> getDevParams(Device device) {
        Map<String, String> devData = new HashMap<>();
        devData.put("machineCode", device.getSerialNumber());
        String remark = device.getRemark();
        String[] split = remark.split(",");
        for (String s : split) {
            String[] split1 = s.split("_");
            devData.put(split1[0],split1[1]);
        }
        return devData;
    }

}



