package com.mortals.xhx.module.product.service.impl;

import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.net.url.UrlPath;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.system.message.impl.MessageProducer;
import com.mortals.xhx.busiz.rsp.ProductVersionInfo;
import com.mortals.xhx.common.code.LogTypeEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.common.key.QueueKey;
import com.mortals.xhx.common.model.DefaultTbQueueMsgHeaders;
import com.mortals.xhx.common.model.MessageHeader;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceLogEntity;
import com.mortals.xhx.module.device.model.DeviceQuery;
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.dao.ProductDao;
import com.mortals.xhx.module.product.model.ProductEntity;
import com.mortals.xhx.module.product.model.ProductQuery;
import com.mortals.xhx.module.product.model.ProductVersionEntity;
import com.mortals.xhx.module.product.model.ProductVersionQuery;
import com.mortals.xhx.module.product.service.ProductService;
import com.mortals.xhx.module.product.service.ProductVersionService;
import com.mortals.xhx.queue.DefaultTbQueueMsg;
import com.mortals.xhx.queue.TbQueueMsg;
import com.mortals.xhx.queue.TbQueueMsgHeaders;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.List;

import static com.mortals.xhx.common.key.Constant.MESSAGETYPE_UPGREAD;
import static com.mortals.xhx.common.key.Constant.PARAM_SERVER_HTTP_URL;
import static com.mortals.xhx.common.key.ErrorCode.DEVICE_VERSION_UNEXIST;
import static com.mortals.xhx.common.key.ErrorCode.DEVICE_VERSION_UNEXIST_CONTENT;

/**
 * ProductService
 * 产品 service实现
 *
 * @author zxfei
 * @date 2022-06-27
 */
@Service("productService")
@Slf4j
public class ProductServiceImpl extends AbstractCRUDCacheServiceImpl<ProductDao, ProductEntity, Long> implements ProductService {

    @Autowired
    private ProductVersionService productVersionService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private DeviceLogService deviceLogService;
    @Autowired
    private MessageProducer messageProducer;

    @Override
    protected void saveBefore(ProductEntity entity, Context context) throws AppException {
        //新增产品编码不能重复
        ProductEntity productEntity = this.selectOne(new ProductQuery().productCode(entity.getProductCode()));
        if (!ObjectUtils.isEmpty(productEntity)) throw new AppException("当前产品编码已存在！");
        //默认时，需拼接homeUrl
        updateDeviceHomeUrl(entity);
        super.saveBefore(entity, context);
    }


    @Override
    protected void updateBefore(ProductEntity entity, Context context) throws AppException {
        ProductEntity productEntity = this.get(entity.getId());
        if (!productEntity.getProductCode().equals(entity.getProductCode())) {
            ProductEntity productEntity1 = this.selectOne(new ProductQuery().productCode(entity.getProductCode()));
            if (!ObjectUtils.isEmpty(productEntity1)) throw new AppException("当前产品编码已存在！");
        }
        updateDeviceHomeUrl(entity);
        super.updateBefore(entity, context);
    }

    private void updateDeviceHomeUrl(ProductEntity entity) {
        if (!ObjectUtils.isEmpty(entity.getSkinName())) {
            String path = UrlPath.of(Constant.DEVICE_BASEHOME_PATH, Charset.defaultCharset())
                    .add(entity.getProductCode())
                    .add(entity.getSkinName())
                    .build(Charset.defaultCharset());
            entity.setHomeUrl(path);
        }
    }


    @Override
    public void upGrade(Long productId, Context context) {
        ProductVersionQuery productVersionQuery = new ProductVersionQuery();
        productVersionQuery.setProductId(productId);
        productVersionQuery.setOrderColList(Arrays.asList(new OrderCol("version")));
        productVersionQuery.setOrderKind(OrderCol.DESCENDING);

        ProductVersionEntity productVersionEntity = productVersionService.selectOne(productVersionQuery);
        if (ObjectUtils.isEmpty(productVersionEntity))
            throw new AppException(DEVICE_VERSION_UNEXIST, DEVICE_VERSION_UNEXIST_CONTENT);
        //查询设备 构建下发信息
        ProductEntity productEntity = this.get(productVersionEntity.getProductId());
        if (ObjectUtils.isEmpty(productEntity)) {
            throw new AppException("当前设备未配置所属产品，请在后台配置后再激活！");
        }
        PlatformEntity platformEntity = platformService.get(productEntity.getPlatformId());
        if (ObjectUtils.isEmpty(platformEntity)) {
            throw new AppException("当前设备未配置所属系统平台，请在后台配置后再激活！");
        }

        String exchangeName = platformEntity.getPlatformSn() + Constant.EXCHANGE_SPLIT + productEntity.getProductCode();

        List<DeviceEntity> deviceList = deviceService.find(new DeviceQuery().productId(productId));
        deviceList.forEach(deviceEntity -> {
            //TopicPartitionInfo info = TopicPartitionInfo.builder().exchangeName(exchangeName).topic(Constant.DOWN_TOPIC + deviceEntity.getDeviceCode()).build();

            ProductVersionInfo productVersionInfo = new ProductVersionInfo();
            BeanUtils.copyProperties(productVersionEntity, productVersionInfo, BeanUtil.getNullPropertyNames(productVersionEntity));
            buildDownloadUrl(productVersionEntity, productVersionInfo);

            TbQueueMsgHeaders header = new DefaultTbQueueMsgHeaders();
            header.put(MessageHeader.MESSAGETYPE, MESSAGETYPE_UPGREAD);
            header.put(MessageHeader.DEVICECODE, deviceEntity.getDeviceCode());
            header.put(MessageHeader.TIMESTAMP, DateUtils.getCurrStrDateTime());
            header.put(MessageHeader.MESSAGESIGN, "abcd1234");
            TbQueueMsg queueMsg = new DefaultTbQueueMsg(IdUtil.fastUUID(),  Base64.getEncoder().encodeToString(JSON.toJSONString(productVersionInfo).getBytes()), header);
            messageProducer.sendMsg(QueueKey.DEFAULT_EXCHANGE,Constant.DOWN_TOPIC + deviceEntity.getDeviceCode(),JSON.toJSONString(queueMsg));

            DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
            deviceLogEntity.initAttrValue();
            deviceLogEntity.setTraceID(IdUtil.fastSimpleUUID());
            deviceLogEntity.setSiteId(deviceEntity.getSiteId());
            deviceLogEntity.setDeviceId(deviceEntity.getId());
            deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
            deviceLogEntity.setDeviceCode(deviceEntity.getDeviceCode());
            deviceLogEntity.setMessageHead(MESSAGETYPE_UPGREAD);
            deviceLogEntity.setContent(Base64.getEncoder().encodeToString(JSON.toJSONString(productVersionInfo).getBytes()));
            deviceLogEntity.setLogType(LogTypeEnum.下发服务.getValue());
            deviceLogEntity.setCreateUserId(1L);
            deviceLogEntity.setCreateTime(new Date());
            deviceLogService.save(deviceLogEntity,context);
            log.info("【发送中】发送升级版本信息，设备编码:{}",deviceEntity.getDeviceCode());

           // deviceService.sendDeviceMessage(deviceEntity, info, header, Base64.getEncoder().encodeToString(JSON.toJSONString(productVersionInfo).getBytes()), callback, null);
        });

    }

    private void buildDownloadUrl(ProductVersionEntity productVersionEntity, ProductVersionInfo productVersionInfo) {
        String download = "";
        if (!ObjectUtils.isEmpty(productVersionEntity.getFilePath())) {
            download = productVersionEntity.getFilePath();
        }
        String domain = GlobalSysInfo.getParamValue(PARAM_SERVER_HTTP_URL, "http://192.168.0.98:11091");
      // String temp= domain+"/"+download;
        //productVersionInfo.setDownloadUrl(temp);
        productVersionInfo.setDownloadUrl(UrlBuilder.of(domain).addPath(download).toString());
    }
}