package com.fastbee.iot.haiwei.service.impl;

import cn.hutool.core.bean.BeanUtil;

import com.alibaba.fastjson.JSON;
import com.fastbee.common.core.domain.CommonResult;
import com.fastbee.common.core.redis.RedisCache;
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.enums.WaterFertilizerHttpEnum;
import com.fastbee.iot.haiwei.service.HaiWeiService;
import com.fastbee.iot.httpclient.HttpAPIController;
import com.fastbee.iot.httpclient.HttpResultDTO;
import com.fastbee.iot.mapper.DeviceMapper;
import com.fastbee.iot.model.ThingsModels.PropertyDto;
import com.fastbee.iot.model.haiwei.CmdHaiWeiVo;
import com.fastbee.iot.model.haiwei.CmdTagVo;
import com.fastbee.iot.model.haiwei.HaiWeiDeviceInfoVo;
import com.fastbee.iot.model.haiwei.HaiWeiVo;
import com.fastbee.iot.model.haiwei.bo.CmdHaiWeiBo;
import com.fastbee.iot.model.haiwei.dto.CmdHaiWeiDto;
import com.fastbee.iot.service.IDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

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

@Service
@Slf4j
public class HaiWeiServiceImpl implements HaiWeiService {
    @Resource
    private IDeviceService iDeviceService;
    @Resource
    private RedisCache redisCache;
    @Resource
    DeviceMapper deviceMapper;
    @Resource
    private ITSLCache itslCache;

    @Override
    public CommonResult<List<HaiWeiVo>> getHaiWeiDevices() {
        Device device = new Device();
        device.setProductId(Long.valueOf(SOLAR_DEVICE.getType()));
        List<Device> devices = iDeviceService.selectDeviceList(device);
        device.setProductId(Long.valueOf(FLOW_METER_DEVICE.getType()));
        List<Device> devices1 = iDeviceService.selectDeviceList(device);
        device.setProductId(Long.valueOf(DOOR_LOCK_DEVICE.getType()));
        List<Device> devices2 = iDeviceService.selectDeviceList(device);
        devices.addAll(devices1);
        devices.addAll(devices2);
        List<HaiWeiVo> deviceVos = new ArrayList<>();
        for (Device device1 : devices) {
            HaiWeiVo haiWeiVo = new HaiWeiVo();
            BeanUtil.copyProperties(device1, haiWeiVo);
            deviceVos.add(haiWeiVo);
        }
        return CommonResult.success(deviceVos);
    }

    @Override
    public CommonResult<HaiWeiDeviceInfoVo> getCache(Long deviceId) {
        HaiWeiDeviceInfoVo haiWeiDeviceInfoVo =
                redisCache.getCacheObject(DeviceCacheConstants.getDeviceLogKey(deviceId.toString()));
        if (haiWeiDeviceInfoVo != null) {
            if (null != haiWeiDeviceInfoVo.getReceiveTime()) {
                //5分钟未更新设备信息，任务设备离线
                if (System.currentTimeMillis() - haiWeiDeviceInfoVo.getReceiveTime().getTime() >= 1000 * 60 * 5) {
                    haiWeiDeviceInfoVo.setOnline(false);
                }
            } else {
                haiWeiDeviceInfoVo.setOnline(false);
            }
        }
        return CommonResult.success(haiWeiDeviceInfoVo);
    }

    @Override
    public CommonResult<CmdHaiWeiVo> cmdDevices(CmdHaiWeiDto cmdHaiWeiDto) {
        String url = "https://cloud.haiwell.com/api/project/machine/datagroup/setTagsValue";
        Device deviceEntity = deviceMapper.selectDeviceByDeviceId(cmdHaiWeiDto.getDeviceId());
        CmdHaiWeiVo cmdWaterFertilizerVo = new CmdHaiWeiVo();
        cmdWaterFertilizerVo.setDeviceId(cmdHaiWeiDto.getDeviceId());
        List<CmdTagVo> cmdTagVos = new ArrayList<>();
        Map<String, String> devParams = getDevParams(deviceEntity);
        CmdHaiWeiBo cmdWaterFertilizerBo = new CmdHaiWeiBo();
        cmdWaterFertilizerBo.setAccount(devParams.get("account"));
        cmdWaterFertilizerBo.setMachineCode(devParams.get("machineCode"));
        cmdWaterFertilizerBo.setPrivateKey(devParams.get("privateKey"));
        cmdWaterFertilizerBo.setWebapiKey(devParams.get("webapiKey"));
        //获取该产品下功能模型
        com.alibaba.fastjson2.JSONObject thingsModelObject =
                com.alibaba.fastjson2.JSONObject.parseObject(itslCache.getCacheThingsModelByProductId(deviceEntity.getProductId()));
        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::getId));
        Map<String, String> tags = new HashMap<>();
        String group = null;
        List<PropertyDto> propertyDtos = stringListMap.get(cmdHaiWeiDto.getNameEn());
        if (StringUtils.isEmpty(group)) {
            group = propertyDtos.get(0).getGroup();
            String[] split = cmdHaiWeiDto.getValue().split("\\.");
            tags.put(cmdHaiWeiDto.getNameEn(), split[0]);
            cmdWaterFertilizerBo.setGroupTag(group);
            cmdWaterFertilizerBo.setTags(tags);

            HttpResultDTO duhttpResultDTO = HttpAPIController.doPostWithJsonParamAndHeaders(url,
                    JsonUtils.toJsonString(cmdWaterFertilizerBo), new HashMap<>());
            group = null;
            tags.clear();
            if (null != duhttpResultDTO && duhttpResultDTO.getCode() == 200) {
                Object object = JSON.parse(duhttpResultDTO.getBody());
                //请求报错
                if (JsonUtils.toJsonString((Map<String, String>) object).contains("error")) {
                    Object map = ((Map<String, String>) object).get("error");
                    Object map1 = ((Map<String, String>) map).get("code");
                    WaterFertilizerHttpEnum waterFertilizerHttpEnum = WaterFertilizerHttpEnum.getWaterFertilizerHttpEnum((String) map1);
                    return CommonResult.error(500,waterFertilizerHttpEnum.getName());
                } else {
                    Object map = ((Map<String, String>) object).get("result");
                    Object map1 = ((Map<String, String>) map).get("data");
                    Map<String, Integer> a = (Map<String, Integer>) map1;
                    for (String s : a.keySet()) {
                        CmdTagVo cmdTagVo = new CmdTagVo();
                        cmdTagVo.setNameEn(s);
                        Integer s1 = (Integer) a.get(s);
                        cmdTagVo.setResult(s1.toString());
                        cmdTagVos.add(cmdTagVo);
                    }
                }
            } else {
                return CommonResult.error(500,"Http请求异常");
            }

        }
        cmdWaterFertilizerVo.setCmdTagVos(cmdTagVos);
        return CommonResult.success(cmdWaterFertilizerVo);
    }

    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;
    }

}
