package com.mortals.xhx.daemon.task;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.framework.ws.message.SendToAllRequest;
import com.mortals.xhx.base.framework.ws.util.WebSocketUtil;
import com.mortals.xhx.busiz.rsp.SiteInfo;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.common.key.ParamKey;
import com.mortals.xhx.common.pdu.site.SitePdu;
import com.mortals.xhx.feign.site.ISiteFeign;
import com.mortals.xhx.module.alarm.model.AlarmSmsSendEntity;
import com.mortals.xhx.module.alarm.model.AlarmSmsSendQuery;
import com.mortals.xhx.module.alarm.service.AlarmSmsSendService;
import com.mortals.xhx.module.device.model.*;
import com.mortals.xhx.module.device.service.*;
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 lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.math.BigDecimal.ROUND_HALF_DOWN;
import static java.util.stream.Collectors.counting;

/**
 * 设备统计任务，生成当天统计数据
 *
 * @author: zxfei
 * @date: 2022/3/9 15:19
 */
@CommonsLog
@Service("DeviceStatTask")
public class DeviceStatTaskImpl implements ITaskExcuteService {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private DeviceLogService deviceLogService;
    @Autowired
    private DeviceModuleUseService deviceModuleUseService;

    @Autowired
    private ProductService productService;
    @Autowired
    private PlatformService platformService;

    @Autowired
    private DeviceStatService deviceStatService;
    @Autowired
    private ISiteFeign siteFeign;
    @Autowired
    private DeviceAlarmInfoService deviceAlarmInfoService;
    @Autowired
    private AlarmSmsSendService alarmSmsSendService;


    @Override
    public void excuteTask(ITask task) throws AppException {
        log.debug("设备统计，开始执行");
        doDeviceStat();
        log.debug("设备统计，结束执行");
    }


    /**
     * 统计设备
     */
    private void doDeviceStat() {

        //查询当天统计，如果有 则更新统计结果，否则新增
        DeviceStatEntity deviceStatEntity = deviceStatService.selectOne(new DeviceStatQuery()
                .year(DateUtil.year(new Date()))
                .month(DateUtil.month(new Date()) + 1)
                .day(DateUtil.dayOfMonth(new Date())));
        if (ObjectUtils.isEmpty(deviceStatEntity)) {
            deviceStatEntity = new DeviceStatEntity();
            deviceStatEntity.initAttrValue();
            deviceStatEntity.setCreateTime(new Date());
            deviceStatEntity.setYear(DateUtil.year(new Date()));
            deviceStatEntity.setMonth(DateUtil.month(new Date()) + 1);
            deviceStatEntity.setDay(DateUtil.dayOfMonth(new Date()));
        }

        //获取昨天统计数据
        DeviceStatEntity yesterdayDeviceStat = deviceStatService.selectOne(new DeviceStatQuery()
                .year(DateUtil.year(DateUtil.yesterday()))
                .month(DateUtil.month(DateUtil.yesterday()) + 1)
                .day(DateUtil.dayOfMonth(DateUtil.yesterday())));
        if (ObjectUtils.isEmpty(yesterdayDeviceStat)) {
            yesterdayDeviceStat = new DeviceStatEntity();
            yesterdayDeviceStat.initAttrValue();
        }
        try {
            //获取设备总数
            List<DeviceEntity> deviceList = deviceService.find(new DeviceQuery());
            Integer deviceTotalCount = deviceList.size();

            deviceStatEntity.setDeviceTotalCount(deviceTotalCount);
            deviceStatEntity.setDeviceAddCount(deviceTotalCount - yesterdayDeviceStat.getDeviceTotalCount());

            //站点数量
            String resp = siteFeign.list(new SitePdu());
            JSONObject jsonObject = JSONObject.parseObject(resp);
            if (jsonObject.getInteger("code") == 1) {
                List<SitePdu> sitePduList = jsonObject.getJSONObject("data").getObject("data", new TypeReference<List<SitePdu>>() {
                });
                deviceStatEntity.setSiteTotalCount(sitePduList.size());
                deviceStatEntity.setSiteAddCount(sitePduList.size() - yesterdayDeviceStat.getSiteTotalCount());
            }

            //在线数量
            Long deviceOnlineCount = deviceList.parallelStream().filter(f -> f.getDeviceStatus() == DeviceStatusEnum.在线.getValue()).count();
            deviceStatEntity.setDeviceOnlineCount(deviceOnlineCount.intValue());
            deviceStatEntity.setDeviceOnlineRatio(new BigDecimal(deviceOnlineCount).divide(new BigDecimal(deviceList.size()),ROUND_HALF_DOWN).setScale(2));

            //离线数量
            Long deviceOfflineCount = deviceList.parallelStream().filter(f -> f.getDeviceStatus() == DeviceStatusEnum.离线.getValue()).count();
            deviceStatEntity.setDeviceOfflineCount(deviceOfflineCount.intValue());
            deviceStatEntity.setDeviceOfflineRatio(new BigDecimal(deviceOfflineCount).divide(new BigDecimal(deviceList.size()),ROUND_HALF_DOWN).setScale(2));

            //停用数量
            Long deviceStopCount = deviceList.parallelStream().filter(f -> f.getEnabled() == YesNoEnum.NO.getValue()).count();
            deviceStatEntity.setDeviceStopCount(deviceStopCount.intValue());
            deviceStatEntity.setDeviceStopRatio(new BigDecimal(deviceStopCount).divide(new BigDecimal(deviceList.size()),ROUND_HALF_DOWN).setScale(2));

            //今日告警数量
            DeviceAlarmInfoQuery deviceAlarmInfoQuery = new DeviceAlarmInfoQuery();
            deviceAlarmInfoQuery.setCreateTimeStart(DateUtils.getCurrStrDate());
            deviceAlarmInfoQuery.setCreateTimeEnd(DateUtils.getCurrStrDate());
            List<DeviceAlarmInfoEntity> deviceAlarmInfoList = deviceAlarmInfoService.find(deviceAlarmInfoQuery);
            deviceStatEntity.setAlarmTotalCount(deviceAlarmInfoList.size());
            deviceStatEntity.setAlarmAddCount(deviceAlarmInfoList.size() - yesterdayDeviceStat.getAlarmTotalCount());

            //推送数量
            AlarmSmsSendQuery alarmSmsSendQuery = new AlarmSmsSendQuery();
            alarmSmsSendQuery.setSendTimeStart(DateUtils.getCurrStrDate());
            alarmSmsSendQuery.setSendTimeEnd(DateUtils.getCurrStrDate());
            alarmSmsSendQuery.setSendStatus(SendStatusEnum.发送成功.getValue());

            List<AlarmSmsSendEntity> alarmSmsSendEntities = alarmSmsSendService.find(alarmSmsSendQuery);
            deviceStatEntity.setPushTotalCount(alarmSmsSendEntities.size());
            deviceStatEntity.setPushAddCount(alarmSmsSendEntities.size()-yesterdayDeviceStat.getPushTotalCount());

            //上行下行数量
            DeviceLogQuery deviceLogQuery = new DeviceLogQuery();
            deviceLogQuery.setCreateTimeStart(DateUtils.getCurrStrDate());
            deviceLogQuery.setCreateTimeEnd(DateUtils.getCurrStrDate());
            Map<Boolean, Long> collect = deviceLogService.find(deviceLogQuery).parallelStream().collect(Collectors.partitioningBy(x -> x.getLogType() == LogTypeEnum.上报事件.getValue(), counting()));
            deviceStatEntity.setUploadMessageTotalCount(collect.getOrDefault(true,0L).intValue());
            deviceStatEntity.setDownloadMessageTotalCount(collect.getOrDefault(false,0L).intValue());

            if (deviceStatEntity.newEntity()) {
                deviceStatEntity.setCreateTime(new Date());
                deviceStatService.save(deviceStatEntity);
            } else {
                deviceStatEntity.setUpdateTime(new Date());
                deviceStatService.update(deviceStatEntity);
            }


        } catch (Exception e) {
            log.error("更新任务异常，结束执行", e);
        }
    }


    @Override
    public void stopTask(ITask task) throws AppException {

    }

    public static void main(String[] args) {

        System.out.println(DateUtil.month(new Date()));

        System.out.println(DateUtil.year(new Date()));

        System.out.println(DateUtil.dayOfMonth(new Date()));


    }


}
