package com.mortals.xhx.busiz.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.util.AESUtil;
import com.mortals.xhx.base.DeviceAuth;
import com.mortals.xhx.base.framework.ws.message.SendToAllRequest;
import com.mortals.xhx.base.framework.ws.util.WebSocketUtil;
import com.mortals.xhx.busiz.req.DeviceReq;
import com.mortals.xhx.busiz.req.UploadDeviceReq;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.DeviceQueueAuthInfo;
import com.mortals.xhx.busiz.rsp.DeviceResp;
import com.mortals.xhx.busiz.security.DeviceTokenService;
import com.mortals.xhx.common.code.ActiveEnum;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.code.StatusEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.common.model.DefaultTbQueueMsgHeaders;
import com.mortals.xhx.common.model.MessageHeader;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceLogService;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.module.platform.model.PlatformEntity;
import com.mortals.xhx.module.platform.service.PlatformService;
import com.mortals.xhx.module.product.model.ProductEntity;
import com.mortals.xhx.module.product.service.ProductService;
import com.mortals.xhx.queue.TbQueueMsgHeaders;
import com.mortals.xhx.queue.TopicPartitionInfo;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * 设备
 *
 * @author: zxfei
 * @date: 2021/8/24 20:28
 */
@RestController
@CommonsLog
@RequestMapping("/api")
public class DeviceApiController {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private ProductService productService;
    @Autowired
    private PlatformService platformService;
    @Value("${queue.rabbitmq.virtual_host:}")
    private String virtualHost;
    @Value("${tok.rabbitmq.password:}")
    private String password;
    @Value("${queue.rabbitmq.host:}")
    private String host;
    @Value("${queue.rabbitmq.port:}")
    private int port;
    @Value("${queue.rabbitmq.username:}")
    private String username;
    @Value("${token.secret}")
    private String secret;


    /**
     * 设备激活
     *
     * @param req
     * @return
     */
    @PostMapping("active")
    public String active(@RequestBody DeviceReq req) {
        log.info("【设备激活】【请求体】-->  " + JSONObject.toJSONString(req));
        ApiResp<DeviceResp> rsp = new ApiResp<>();
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        DeviceResp deviceResp = new DeviceResp();
        try {
            //根据设备编码查询设备是否存在，如果存在判断是否已经激活
            DeviceEntity deviceEntity = deviceService.getExtCache(req.getDeviceNum());
            if (ObjectUtils.isEmpty(deviceEntity)) {
                deviceEntity = new DeviceEntity();
                deviceEntity.initAttrValue();
                deviceEntity.setDeviceMac(req.getDeviceMac());
                deviceEntity.setDeviceCode(req.getDeviceNum());
                deviceEntity.setCreateUserId(1L);
                deviceEntity.setCreateTime(new Date());
                deviceService.save(deviceEntity);
            }
            if (deviceEntity.getActive() != ActiveEnum.已激活.getValue()) {
                rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
                rsp.setMsg("当前设备未激活，请在后台配置后再激活！");
            } else {
                //判断设备是否已经激活，如果已激活返回token信息
                if (deviceEntity.getActive() == ActiveEnum.已激活.getValue() && deviceEntity.getStatus() == StatusEnum.启用.getValue()) {
                    DeviceQueueAuthInfo authInfo = new DeviceQueueAuthInfo();
                    authInfo.setHost(host);
                    authInfo.setPort(port);
                    authInfo.setUsername(username);
                    authInfo.setPassword(password);
                    authInfo.setVirtualHost(virtualHost);
                    PlatformEntity platformEntity = platformService.get(deviceEntity.getPlatformId());
                    if (ObjectUtils.isEmpty(platformEntity)) {
                        throw new AppException("当前设备未配置所属系统平台，请在后台配置后再激活！");
                    }
                   // authInfo.setHost(platformEntity.getPlatformSn());
                    ProductEntity productEntity = productService.get(deviceEntity.getProductId());
                    if (ObjectUtils.isEmpty(productEntity)) {
                        throw new AppException("当前设备未配置所属产品，请在后台配置后再激活！");
                    }
                    authInfo.setExchangeName(platformEntity.getPlatformSn()+Constant.EXCHANGE_SPLIT+productEntity.getProductCode());
                    authInfo.setUploadTopicFilter(Constant.UPLOAD_TOPIC + deviceEntity.getDeviceCode());
                    authInfo.setDownTopicFilter(Constant.DOWN_TOPIC + deviceEntity.getDeviceCode());
                    String token = AESUtil.encryptForApp(JSON.toJSONString(authInfo), secret);
                    deviceResp.setToken(token);
                }
                deviceEntity.setOnlineTime(new Date());
                deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
                deviceEntity.setIp(req.getIp());
                deviceEntity.setPort(req.getPort());
                deviceEntity.setCenternum(req.getCenternum());
                deviceService.update(deviceEntity);
            }
            rsp.setData(deviceResp);
        } catch (Exception e) {
            log.error("接收数据失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return JSON.toJSONString(rsp);
        }
        log.info("响应【设备激活】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return JSON.toJSONString(rsp);
    }


    /**
     * 设备数据上报
     *
     * @param req
     * @return
     */
    @PostMapping("upload")
    //@DeviceAuth
    public String upload(@RequestBody UploadDeviceReq req) {
        log.info("【设备数据上报】【请求体】-->  " + JSONObject.toJSONString(req));
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            //根据设备编码查询设备
            DeviceEntity deviceEntity = deviceService.getExtCache(req.getDeviceNum());
            if (!ObjectUtils.isEmpty(deviceEntity)) {
                //将上报信息转发到mq中

                PlatformEntity platformEntity = platformService.get(deviceEntity.getPlatformId());
                if (ObjectUtils.isEmpty(platformEntity)) {
                    throw new AppException("当前设备未配置所属系统平台，请在后台配置后再激活！");
                }
                // authInfo.setHost(platformEntity.getPlatformSn());
                ProductEntity productEntity = productService.get(deviceEntity.getProductId());
                if (ObjectUtils.isEmpty(productEntity)) {
                    throw new AppException("当前设备未配置所属产品，请在后台配置后再激活！");
                }
                String exchangeName = platformEntity.getPlatformSn() + Constant.EXCHANGE_SPLIT + productEntity.getProductCode();

                TopicPartitionInfo info = TopicPartitionInfo.builder().exchangeName(exchangeName).topic(Constant.UPLOAD_TOPIC + deviceEntity.getDeviceMac()).build();
                TbQueueMsgHeaders header = new DefaultTbQueueMsgHeaders();
                header.put(MessageHeader.MESSAGETYPE, Constant.MESSAGETYPE_HEARTBEAT);
                ApiResp<String> sendDeviceMessageResp = deviceService.sendDeviceMessage(deviceEntity, info, header, JSON.toJSONString(req), null);
                log.info(String.format("sendMsgResp:%s", JSON.toJSONString(sendDeviceMessageResp)));
            }
        } catch (Exception e) {
            log.error("接收数据失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return JSON.toJSONString(rsp);
        }

        log.debug("响应【设备数据上报】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return JSON.toJSONString(rsp);
    }


}
