package com.fastbee.iot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fastbee.common.extend.core.domin.entity.SysUser;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.iot.convert.AlertLogConvert;
import com.fastbee.iot.domain.AlertLog;
import com.fastbee.iot.mapper.AlertLogMapper;
import com.fastbee.iot.model.DeviceAlertCount;
import com.fastbee.iot.model.param.DataCenterParam;
import com.fastbee.iot.model.vo.AlertCountVO;
import com.fastbee.iot.model.vo.AlertLogVO;
import com.fastbee.iot.service.IAlertLogService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.fastbee.common.extend.utils.SecurityUtils.getLoginUser;


/**
 * 设备告警Service业务层处理
 *
 * @author kerwincui
 * @date 2022-01-13
 */
@Service
public class AlertLogServiceImpl extends ServiceImpl<AlertLogMapper,AlertLog> implements IAlertLogService {

    @Resource
    private AlertLogMapper alertLogMapper;

    /**
     * 查询设备告警
     *
     * @param alertLogId 设备告警主键
     * @return 设备告警
     */
    @Override
    public AlertLog selectAlertLogByAlertLogId(Long alertLogId) {
        return alertLogMapper.selectById(alertLogId);
    }

    /**
     * 查询设备告警日志列表
     *
     * @param alertLogVO 设备告警日志
     * @return 设备告警日志
     */
    @Override
    public Page<AlertLogVO> pageAlertLogVO(AlertLogVO alertLogVO) {
        AlertLog alertLog = AlertLogConvert.INSTANCE.convertAlertLog(alertLogVO);
        SysUser user = getLoginUser().getUser();
        // 查询所属机构
        // 兼容组态多租户分享
        if (null != alertLogVO.getDeptUserId()) {
            alertLog.setUserId(alertLogVO.getDeptUserId());
        } else {
            if (null != user.getDeptId()) {
                alertLog.setUserId(user.getDept().getDeptUserId());
            } else {
                alertLog.setUserId(user.getUserId());
            }
        }
        LambdaQueryWrapper<AlertLog> lqw = buildQueryWrapper(alertLog);
        lqw.orderByDesc(AlertLog::getCreateTime);
        Page<AlertLog> alertLogPage = baseMapper.selectPage(new Page<>(alertLogVO.getPageNum(), alertLogVO.getPageSize()), lqw);
        return AlertLogConvert.INSTANCE.convertAlertLogVOPage(alertLogPage);
    }

    @Override
    public List<AlertLog> selectAlertLogListByCreateBy(String createBy, String remark, Integer status) {
        AlertLog alertLog = new AlertLog();
        alertLog.setCreateBy(createBy);
        alertLog.setStatus(status);
        alertLog.setRemark(remark);
        LambdaQueryWrapper<AlertLog> queryWrapper = this.buildQueryWrapper(alertLog);
        queryWrapper.orderByDesc(AlertLog::getCreateTime);
        return alertLogMapper.selectList(queryWrapper);
    }

    /**
     * 查询设备告警列表
     *
     * @param alertLog 设备告警
     * @return 设备告警
     */
    @Override
    public Long selectAlertLogListCount(AlertLog alertLog) {
        return alertLogMapper.selectAlertLogListCount(alertLog);
    }

    @Override
    public List<DeviceAlertCount> selectDeviceAlertCount(List<String> serialNumberList) {
        return alertLogMapper.selectDeviceAlertCount(serialNumberList);
    }

    @Override
    public DeviceAlertCount selectDeviceAlertCountBySN(String serialNumber) {
        return alertLogMapper.selectDeviceAlertCountBySN(serialNumber);
    }

    @Override
    public List<DeviceAlertCount> selectSceneAlertCount() {
        return alertLogMapper.selectSceneAlertCount();
    }

    @Override
    public DeviceAlertCount selectSceneAlertCountBySceneId(String sceneId) {
        return alertLogMapper.selectSceneAlertCountBySceneId(sceneId);
    }

    /**
     * 新增设备告警
     *
     * @param alertLog 设备告警
     * @return 结果
     */
    @Override
    public int insertAlertLog(AlertLog alertLog) {
        alertLog.setCreateTime(DateUtils.getNowDate());
        return alertLogMapper.insert(alertLog);
    }

    @Override
    public int insertAlertLogBatch(List<AlertLog> alertLogList) {
        return alertLogMapper.insertBatch(alertLogList) ? 1 : 0;
    }

    /**
     * 修改设备告警
     *
     * @param alertLog 设备告警
     * @return 结果
     */
    @Override
    public int updateAlertLog(AlertLog alertLog) {
        alertLog.setUpdateTime(DateUtils.getNowDate());
        if (alertLog.getRemark().length() > 0) {
            // 1=不需要处理,2=未处理,3=已处理
            alertLog.setStatus(3);
        }
        return alertLogMapper.updateById(alertLog);
    }

    @Override
    public int updateAlertLogStatus(AlertLog alertLog) {
        LambdaUpdateWrapper<AlertLog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(AlertLog::getStatus, alertLog.getStatus());
        updateWrapper.set(AlertLog::getUpdateTime, DateUtils.getNowDate());
        updateWrapper.eq(AlertLog::getSerialNumber, alertLog.getSerialNumber());
        updateWrapper.eq(AlertLog::getCreateBy, alertLog.getCreateBy());
        return this.update(updateWrapper) ? 1 : 0;
    }

    /**
     * 通过设备编号删除设备告警信息
     *
     * @param SerialNumber 设备告警主键
     * @return 结果
     */
    @Override
    public int deleteAlertLogBySerialNumber(String SerialNumber) {
        LambdaQueryWrapper<AlertLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertLog::getSerialNumber, SerialNumber);
        return alertLogMapper.delete(queryWrapper);
    }
    @Override
    public List<AlertCountVO> countAlertProcess(DataCenterParam dataCenterParam) {
        LocalDateTime beginTime = null;
        LocalDateTime endTime = null;
        if (dataCenterParam.getBeginTime() != null && dataCenterParam.getEndTime() != null) {
            beginTime = parseTime(dataCenterParam.getBeginTime());
            endTime = parseTime(dataCenterParam.getEndTime());
        }
        return alertLogMapper.countAlertProcess(dataCenterParam, beginTime, endTime);
    }
    private LocalDateTime parseTime(String time) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(time, formatter);
    }

    @Override
    public List<AlertCountVO> countAlertLevel(DataCenterParam dataCenterParam) {
        LocalDateTime beginTime = null;
        LocalDateTime endTime = null;
        if (dataCenterParam.getBeginTime() != null && dataCenterParam.getEndTime() != null) {
            beginTime = parseTime(dataCenterParam.getBeginTime());
            endTime = parseTime(dataCenterParam.getEndTime());
        }
        return alertLogMapper.countAlertLevel(dataCenterParam, beginTime, endTime);
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AlertLog entity){
        //TODO 做一些数据校验,如唯一约束
    }

    private LambdaQueryWrapper<AlertLog> buildQueryWrapper(AlertLog query) {
        Map<String, Object> params = query.getParams();
        LambdaQueryWrapper<AlertLog> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(query.getAlertName()), AlertLog::getAlertName, query.getAlertName());
        lqw.eq(query.getAlertLevel() != null, AlertLog::getAlertLevel, query.getAlertLevel());
        lqw.eq(query.getStatus() != null, AlertLog::getStatus, query.getStatus());
        lqw.eq(StringUtils.isNotBlank(query.getSerialNumber()), AlertLog::getSerialNumber, query.getSerialNumber());
        lqw.eq(query.getProductId() != null, AlertLog::getProductId, query.getProductId());
        lqw.eq(StringUtils.isNotBlank(query.getDetail()), AlertLog::getDetail, query.getDetail());
        lqw.eq(query.getUserId() != null, AlertLog::getUserId, query.getUserId());
        lqw.like(StringUtils.isNotBlank(query.getDeviceName()), AlertLog::getDeviceName, query.getDeviceName());
        lqw.eq(StringUtils.isNotBlank(query.getRemark()), AlertLog::getRemark, query.getRemark());
        lqw.eq(StringUtils.isNotBlank(query.getCreateBy()), AlertLog::getCreateBy, query.getCreateBy());

        if (!Objects.isNull(params.get("beginTime")) &&
                !Objects.isNull(params.get("endTime"))) {
            lqw.between(AlertLog::getCreateTime, params.get("beginTime"), params.get("endTime"));
        }
        return lqw;
    }
}
