package com.xueyi.system.digitalmans.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xueyi.common.core.constant.digitalman.InitConstants;
import com.xueyi.common.core.constant.digitalman.MessageConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.mqtt.connection.MqttTemplate;
import com.xueyi.common.web.annotation.TenantIgnore;
import com.xueyi.common.web.entity.service.impl.BaseServiceImpl;
import com.xueyi.message.api.transfer.domain.vo.DmActiveVo;
import com.xueyi.message.api.transfer.feign.RemoteTransferService;
import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto;
import com.xueyi.system.api.digitalmans.domain.po.DmManDevicePo;
import com.xueyi.system.api.digitalmans.domain.vo.DashboardVo;
import com.xueyi.system.digitalmans.domain.query.DmManDeviceQuery;
import com.xueyi.system.digitalmans.manager.IDmManDeviceManager;
import com.xueyi.system.digitalmans.mapper.DmManDeviceMapper;
import com.xueyi.system.digitalmans.service.IDmManDeviceService;
import com.xueyi.system.emcs.domain.po.DmExceptionLogPo;
import com.xueyi.system.emcs.mapper.DmExceptionLogMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 数字人设备管理管理 服务层处理
 *
 * @author xueyi
 */
@Service
public class DmManDeviceServiceImpl extends BaseServiceImpl<DmManDeviceQuery, DmManDeviceDto, IDmManDeviceManager> implements IDmManDeviceService {


    private static final Logger log = LoggerFactory.getLogger(DmManDeviceServiceImpl.class);
    @Autowired
    RemoteTransferService remoteTransferService;

    @Autowired
    IDmManDeviceManager manDeviceManager;


    @Autowired
    DmManDeviceMapper manDeviceMapper;

    @Autowired
    RedisTemplate<String, Serializable> manDeviceDtoRedisTemplate;

    @Autowired
    DmExceptionLogMapper exceptionLogMapper;


    @Autowired
    MqttTemplate mqttTemplate;

    /**
     * 查询数字人设备管理对象列表 | 数据权限
     *
     * @param dmManDevice 数字人设备管理对象
     * @return 数字人设备管理对象集合
     */
    @Override
    //@DataScope(userAlias = "createBy", mapperScope = {"DmManDeviceMapper"})
    public List<DmManDeviceDto> selectListScope(DmManDeviceQuery dmManDevice) {
        List<DmManDeviceDto> list = baseManager.selectListByManual(dmManDevice);
        list.forEach(item->{
            if (item.getDeviceId() != null && !item.getDeviceId().equalsIgnoreCase("")) {
                AjaxResult result = remoteTransferService.getDeviceOnlineStatus(item.getDeviceId());
                if (result.isSuccess() && !result.get("msg").toString().equalsIgnoreCase(""));
                item.setOnlineStatus(result.get("msg").toString());
            }
            else {
                item.setOnlineStatus(InitConstants.DEVICE_ACTIVATE_STATUS_NOT_ACTIVATE);
            }
        });

        return list;
    }

    @TenantIgnore(tenantLine = true)
    @Override
    public int insert(DmManDeviceDto dto) {
        return super.insert(dto);
    }

    @TenantIgnore(tenantLine = true)
    @Override
    public DmManDeviceDto manDeviceInfoInner(String devId) {
        DmManDeviceDto dto = (DmManDeviceDto) manDeviceDtoRedisTemplate.opsForHash().get(MessageConstants.REDIS_GROUP_DEVICE_HEADER,devId);
        if (dto == null) {
            dto = manDeviceManager.selectInfoByDevId(devId);
            if (dto != null) {
                manDeviceDtoRedisTemplate.opsForHash().put(MessageConstants.REDIS_GROUP_DEVICE_HEADER,devId,dto);
            }
        }
        return dto;
    }

    @TenantIgnore(tenantLine = true)
    @Override
    public Integer manDeviceInfoInnerUpdate(DmActiveVo vo) {
        DmManDeviceDto dto = manDeviceManager.selectInfoByManCode(vo.getSecret());
        if (dto == null) {
            return 0;
        }
        dto.setDeviceId(vo.getSncode());
        if (vo.getActivateTime() != null) {
            dto.setActivateTime(vo.getActivateTime());
        }
        dto.setOnlineStatus(InitConstants.DEVICE_ACTIVATE_STATUS_ONLINE);
        return manDeviceManager.updateInfoByManual(dto);
    }

    @TenantIgnore(tenantLine = true)
    @Override
    public DmManDevicePo getOne(String devId) {
        return manDeviceMapper.getOne(devId);
    }

    @Override
    public List<DmManDeviceDto> manDeviceListNotNullByTenantId(Long tenantId) {
        return super.baseManager.selectManDeviceListNotNullByTenantId(tenantId);
    }

    @Override
    public DashboardVo dashboardData() {
        DashboardVo vo = new DashboardVo();

        List<DmManDeviceDto> manDeviceDtoList = this.selectList(new DmManDeviceQuery());
        // 获取数字员工总数
        vo.setDigitalMans(manDeviceDtoList.size());
        // 获取当前在线率
        Long total = (long)manDeviceDtoList.size();
        Long onlineTotal = manDeviceDtoList.stream().filter(item->(!item.getOnlineStatus().isEmpty()) &&
                item.getOnlineStatus().equalsIgnoreCase("1")).count();
        int percent = (total == 0?0 : (int)(onlineTotal/total.doubleValue() * 100));
        log.info("数字员工总数为{}，当前在线设备为{}，当前在线率为：{}",total, onlineTotal, percent);

        vo.setOnlineDevices(percent);
        // 近七天预警
        LocalDateTime currentDate = LocalDateTime.now();
        LocalDateTime sevenDaysAgo =currentDate.minusDays(7).withHour(0).withMinute(0).withSecond(0);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        vo.setAlertNear7Days(exceptionLogMapper.selectList(Wrappers.<DmExceptionLogPo>query().lambda()
                .ge(DmExceptionLogPo::getCreateTime,sevenDaysAgo.format(formatter))).size());
        // 当前未解除预警数
        vo.setOnProcessAlert(exceptionLogMapper.selectList(Wrappers.<DmExceptionLogPo>query().lambda()
                .eq(DmExceptionLogPo::getAlertStatus,0)).size());
        return vo;
    }

    @Override
    public Integer restartDevice(Integer type, String devId) {
        // 发送重启指令
        JSONObject message = new JSONObject();
        message.put("type",type);
        mqttTemplate.sendToMqtt("/prod/digital_man/" + devId + "/notify/restart", message.toJSONString());
        // 更新设备启动状态
        DmManDeviceDto dmManDeviceDto = new DmManDeviceDto();
        dmManDeviceDto.setManCode(devId);


        switch (MessageConstants.RestartEnum.getEnum(type)) {
            case RESTART_APP:
//                dmManDeviceDto.setSetupStatus(MessageConstants.RestartEnum.RESTART_APP.getCode().toString());
                // 更新设备在线状态
                dmManDeviceDto.setOnlineStatus(InitConstants.DEVICE_ACTIVATE_STATUS_APP_RESTART);
                break;
            case RESTART_DEVICE:
//                dmManDeviceDto.setSetupStatus(MessageConstants.RestartEnum.RESTART_DEVICE.getCode().toString());
                // 更新设备在线状态
                dmManDeviceDto.setOnlineStatus(InitConstants.DEVICE_ACTIVATE_STATUS_DEVICE_REBOOT);
                break;
            default:
                break;
        }
        return super.baseManager.updateInfoByManual(dmManDeviceDto);
    }
}