package com.artfess.device.base.manager.impl;

import com.alibaba.fastjson.JSON;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.DateUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.base.util.time.DateUtil;
import com.artfess.device.base.config.MqConstant;
import com.artfess.device.base.dao.DeviceInfoDao;
import com.artfess.device.base.dao.DeviceVideoPointDao;
import com.artfess.device.base.dao.DeviceWarnInfoDao;
import com.artfess.device.base.dto.StatisticsDto;
import com.artfess.device.base.manager.DeviceWarnInfoManager;
import com.artfess.device.base.model.DeviceInfo;
import com.artfess.device.base.model.DeviceWarnInfo;
import com.artfess.device.base.utils.BizUtils;
import com.artfess.device.base.vo.DeviceWarnInfoVo;
import com.artfess.device.base.vo.StatisticsVo;
import com.artfess.device.base.vo.VideoPointVo;
import com.artfess.rocketmq.producer.RocketMQProducer;
import com.artfess.sysConfig.persistence.manager.SysDictionaryManager;
import com.artfess.sysConfig.persistence.param.DictModel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设备告警信息 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2022-07-15
 */
@Service
public class DeviceWarnInfoManagerImpl extends BaseManagerImpl<DeviceWarnInfoDao, DeviceWarnInfo> implements DeviceWarnInfoManager {

    @Resource
    private SysDictionaryManager sdm;

    @Resource
    private DeviceInfoDao deviceInfoDao;

    @Resource
    private DeviceVideoPointDao deviceVideoPointDao;

    @Autowired
    private RocketMQProducer rocketMQUtils;

    @Override
    public PageList<DeviceWarnInfo> query(QueryFilter<DeviceWarnInfo> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        QueryWrapper<DeviceWarnInfo> wrapper = convert2Wrapper(queryFilter, currentModelClass());
        IPage<DeviceWarnInfo> result = baseMapper.queryPage(convert2IPage(pageBean), wrapper);
        return new PageList<>(result);
    }

    @Override
    public Integer findByDeviceType(String deviceType) {
        return this.baseMapper.findByDeviceType(deviceType);
    }

    @Override
    public DeviceWarnInfo getNewWarnInfo(String deviceCode, String warnType) {
        Assert.hasText(deviceCode, "设备编码不能为空！");
        List<DeviceWarnInfo> list =this.baseMapper.getNewWarnInfo(deviceCode,warnType);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }

    @Override
    public void sendWarnInfoToEventCenter(DeviceWarnInfo warnInfo) {
        DeviceWarnInfoVo deviceWarnInfoVo = new DeviceWarnInfoVo();
        deviceWarnInfoVo.setDevCode(warnInfo.getDeviceCode());
        deviceWarnInfoVo.setEventSrcId(warnInfo.getId());
        deviceWarnInfoVo.setEventTitle(warnInfo.getWarnName());
        deviceWarnInfoVo.setEventTime(DateUtils.now());
        deviceWarnInfoVo.setEventSubClass(warnInfo.getDeviceType());
        deviceWarnInfoVo.setEventDesc(warnInfo.getWarnReason());
        deviceWarnInfoVo.setEventType(Integer.valueOf(warnInfo.getWarnType()));
        if(warnInfo.getDeviceType().equals("5")){
            List<VideoPointVo> videoPointVoList =deviceVideoPointDao.findByVideoCode(warnInfo.getDeviceCode());
            VideoPointVo videoPointVo = videoPointVoList.get(0);
            deviceWarnInfoVo.setRegionCode(videoPointVo.getAreaCode());
            deviceWarnInfoVo.setRegionName(videoPointVo.getAreaName());
            deviceWarnInfoVo.setEventAddr(videoPointVo.getAddress());
            deviceWarnInfoVo.setDevName(videoPointVo.getName());
            if(!StringUtils.isEmpty(videoPointVo.getLttd())){
                deviceWarnInfoVo.setEventLat(new BigDecimal(videoPointVo.getLttd()));
            }
            if(!StringUtils.isEmpty(videoPointVo.getLgtd())){
                deviceWarnInfoVo.setEventLng(new BigDecimal(videoPointVo.getLgtd()));
            }
        }else{
            DeviceInfo deviceInfo = deviceInfoDao.findByDeviceCode(warnInfo.getDeviceCode());
            deviceWarnInfoVo.setRegionCode(deviceInfo.getAreaCode());
            deviceWarnInfoVo.setRegionName(deviceInfo.getAreaName());
            deviceWarnInfoVo.setEventAddr(deviceInfo.getAddress());
            deviceWarnInfoVo.setDevName(deviceInfo.getName());
            if(!StringUtils.isEmpty(deviceInfo.getLttd())){
                deviceWarnInfoVo.setEventLat(new BigDecimal(deviceInfo.getLttd()));
            }
            if(!StringUtils.isEmpty(deviceInfo.getLgtd())){
                deviceWarnInfoVo.setEventLng(new BigDecimal(deviceInfo.getLgtd()));
            }
        }
        //上传报警给事件中心
        String warnInfoString = JSON.toJSONString(deviceWarnInfoVo);
        try{
            rocketMQUtils.send(MqConstant.SEND_STATUS_TOPIC, warnInfoString);
        }catch (Exception e) {
            log.error("发送失败:{}", e);
        }

    }

    @Override
    public List<StatisticsVo> statisticsWarn(StatisticsDto dto) {
        // 字典
        List<DictModel> rqlx = sdm.queryDictListItemsByCode("rqlx");
        List<DictModel> handleStatus = sdm.queryDictListItemsByCode("clzt");
        boolean isYear = "true".equals(dto.getIsYear());
        String inputType = dto.getDateType();
        // 默认格式
        dto.setDateType(BizUtils.getDicValueByCode(rqlx, dto.getDateType()));
        if (StringUtil.isEmpty(dto.getDateType())) {
            dto.setDateType("%Y-%m-%d");
        }
        // 数据分组
        List<StatisticsVo> result = Lists.newArrayList();
        if (isYear) {
            // 年统计 按产品类型和处理状态分，还要给出总数
            Map<String, Map<String, List<StatisticsVo>>> data = baseMapper.statisticsWarn(dto).stream()
                    .collect(Collectors.groupingBy(StatisticsVo::getType, Collectors.groupingBy(StatisticsVo::getStatus)));
            for (Map.Entry<String, Map<String,List<StatisticsVo>>> d : data.entrySet()) {
                StatisticsVo rTemp = new StatisticsVo();
                rTemp.setType(d.getKey());
                int totalCount = 0;
                List<StatisticsVo> rtData = Lists.newArrayList();
                for(Map.Entry<String, List<StatisticsVo>> s : d.getValue().entrySet()){
                    totalCount+=s.getValue().size();
                    String status = BizUtils.getDicValueByCode(handleStatus, s.getKey());
                    rtData.add(new StatisticsVo(status, s.getValue().size()));
                }
                rtData.add(new StatisticsVo("总数", totalCount));
                rTemp.setData(rtData);
                result.add(rTemp);
            }
        } else {
            // 不是年统计则X轴为月份
            Map<String, Map<String, List<StatisticsVo>>> data = baseMapper.statisticsWarn(dto).stream()
                    .collect(Collectors.groupingBy(StatisticsVo::getTime, Collectors.groupingBy(StatisticsVo::getStatus)));
            for (Map.Entry<String, Map<String, List<StatisticsVo>>> d : data.entrySet()) {
                StatisticsVo rTemp = new StatisticsVo();
                rTemp.setTime(d.getKey());
                int totalCount = 0;
                List<StatisticsVo> rtData = new ArrayList<>();
                for (Map.Entry<String, List<StatisticsVo>> t : d.getValue().entrySet()) {
                    totalCount+=t.getValue().size();
                    String status = BizUtils.getDicValueByCode(handleStatus, t.getKey());
                    StatisticsVo rtdTemp = new StatisticsVo(status, t.getValue().size());
                    rtData.add(rtdTemp);
                }
                rtData.add(new StatisticsVo("总数", totalCount));
                rTemp.setData(rtData);
                result.add(rTemp);
            }
            // 没有数据的时间也要加上，数据为0
            List<StatisticsVo> emptyResult = new ArrayList<>();
            if ("1".equals(inputType)) {
                emptyResult = BizUtils.handleEmptyResult(12, dto.getTime(), result);
            }
            if ("2".equals(inputType)) {
                String[] inputTime = dto.getTime().split("-");
                Integer endTime = DateUtil.getDaysOfMonth(Integer.parseInt(inputTime[0]), Integer.parseInt(inputTime[1]));
                emptyResult = BizUtils.handleEmptyResult(endTime, dto.getTime(), result);
            }
            result.addAll(emptyResult);
            // 按时间升序排序
            result = result.stream().sorted(Comparator.comparing(StatisticsVo::getTime)).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    public List<StatisticsVo> statisticsWarnSub(StatisticsDto dto) {
        Assert.notNull(dto, "参数不能为空！");
        Assert.notNull(dto.getDateType(), "日期类型不能为空！");
        Assert.notNull(dto.getTime(), "日期不能为空！");
        List<DictModel> rqlx = sdm.queryDictListItemsByCode("rqlx");
        dto.setDateType(BizUtils.getDicValueByCode(rqlx, dto.getDateType()));
        if (StringUtil.isEmpty(dto.getDateType())) {
            throw new RuntimeException("未定义的日期类型！");
        }
        return baseMapper.statisticsWarnSub(dto);
    }

    @Override
    public List<StatisticsVo> warnCountMonthly() {
        return baseMapper.warnCountMonthly();
    }

    @Override
    public List<StatisticsVo> warnCountCurrently() {
        return baseMapper.warnCountCurrently();
    }
}
