/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.modular.warning.warningInfo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.core.param.OrgIdParam;
import vip.xiaonuo.modular.base.baseConfig.entity.BaseConfig;
import vip.xiaonuo.modular.base.baseConfig.mapper.BaseConfigMapper;
import vip.xiaonuo.modular.warning.warningInfo.entity.WarningInfo;
import vip.xiaonuo.modular.warning.warningInfo.entity.vo.WarningInfoListVo;
import vip.xiaonuo.modular.warning.warningInfo.entity.vo.WarningInfoProportionVo;
import vip.xiaonuo.modular.warning.warningInfo.entity.vo.WarningInfoRateVo;
import vip.xiaonuo.modular.warning.warningInfo.mapper.WarningInfoMapper;
import vip.xiaonuo.modular.warning.warningInfo.param.*;
import vip.xiaonuo.modular.warning.warningInfo.service.WarningInfoService;
import vip.xiaonuo.modular.warning.warningManager.param.WarningManagerOrgIdParam;
import vip.xiaonuo.sys.modular.user.entity.SysUser;
import vip.xiaonuo.sys.modular.user.mapper.SysUserMapper;

import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 预警Service接口实现类
 *
 * @author newspaper
 * @date  2023/12/26 13:40
 **/
@Service
public class WarningInfoServiceImpl extends ServiceImpl<WarningInfoMapper, WarningInfo> implements WarningInfoService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private BaseConfigMapper baseConfigMapper;

    @Autowired
    private WarningInfoMapper warningInfoMapper;

    @Override
    public Page<WarningInfo> page(WarningInfoPageParam warningInfoPageParam) {
        String type = warningInfoPageParam.getType();
        QueryWrapper<WarningInfo> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(warningInfoPageParam.getWarningType())) {
            queryWrapper.lambda().eq(WarningInfo::getWarningTypeId, warningInfoPageParam.getWarningType());
        }
        if(ObjectUtil.isNotEmpty(warningInfoPageParam.getUnitId())) {
            queryWrapper.lambda().eq(WarningInfo::getUnitId, warningInfoPageParam.getUnitId());
        }
        switch (type) {
            case "0":
                // 处理今日的逻辑
                queryWrapper.lambda().between(WarningInfo::getWarningTime, DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date()));
                break;
            case "1":
                // 处理本周的逻辑
                queryWrapper.lambda().ge(WarningInfo::getWarningTime, DateUtil.beginOfWeek(new Date()));
                break;
            case "2":
                // 处理本月的逻辑
                queryWrapper.lambda().ge(WarningInfo::getWarningTime, DateUtil.beginOfMonth(new Date()));
                break;
            case "3":
                // 处理自定义时间范围的逻辑
                String startWarningTime = warningInfoPageParam.getStartWarningTime() + " 00:00:00";
                String endWarningTime = warningInfoPageParam.getEndWarningTime() + " 23:59:59";
                queryWrapper.lambda().between(WarningInfo::getWarningTime, startWarningTime, endWarningTime);
                break;
            default:
                break;
        }
        queryWrapper.lambda().eq(WarningInfo::getOrgId,warningInfoPageParam.getOrgId()).orderByDesc(WarningInfo::getWarningTime);
        Page<WarningInfo> page = new Page<>(warningInfoPageParam.getCurrent(),warningInfoPageParam.getSize());
        Page<WarningInfo> warningInfoPage = this.page(page, queryWrapper);
        List<WarningInfo> warningInfoList = warningInfoPage.getRecords();
        for (WarningInfo warningInfo : warningInfoList) {
            String[] split = warningInfo.getWarningNotifierId().split(",");
            for (String s : split) {
                String name = sysUserMapper.selectById(s).getName();
                if (ObjectUtil.isNotEmpty(warningInfo.getWarningNotifierName())){
                    warningInfo.setWarningNotifierName(warningInfo.getWarningNotifierName() + "," + name);
                }else {
                    warningInfo.setWarningNotifierName(name);
                }
            }
        }
        return warningInfoPage;
    }

    @Override
    public WarningInfoProportionVo getProportion(WarningInfoTypeParam warningInfoTypeParam) {
        String orgId = warningInfoTypeParam.getOrgId();
        WarningInfoProportionVo warningInfoProportionVo = new WarningInfoProportionVo();
        DateTime dateTime;
        if (warningInfoTypeParam.getType().equals("0")){
            dateTime = DateUtil.beginOfDay(new Date());
        }else {
           dateTime = DateUtil.beginOfMonth(new Date());
        }
        long total = this.count(new QueryWrapper<WarningInfo>().lambda().eq(WarningInfo::getOrgId, orgId).ge(WarningInfo::getWarningTime, dateTime));
        warningInfoProportionVo.setTotal(total);

        String parentConfig = baseConfigMapper.selectOne(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getParentId, 0).eq(BaseConfig::getConfigName, "预警类型")).getId();
        List<BaseConfig> baseConfigs = baseConfigMapper.selectList(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getParentId, parentConfig).orderByAsc(BaseConfig::getSortCode));
        List<WarningInfoRateVo> warningInfoRateVoList = new ArrayList<>();
        for (BaseConfig baseConfig : baseConfigs) {
            WarningInfoRateVo warningInfoRateVo = new WarningInfoRateVo();
            long count = this.count(new QueryWrapper<WarningInfo>().lambda().eq(WarningInfo::getOrgId, orgId).eq(WarningInfo::getWarningTypeId, baseConfig.getId()).ge(WarningInfo::getWarningTime, dateTime));
            warningInfoRateVo.setName(baseConfig.getConfigName());
            warningInfoRateVo.setValue(count);
            warningInfoRateVoList.add(warningInfoRateVo);
        }
        warningInfoProportionVo.setList(warningInfoRateVoList);
        return warningInfoProportionVo;
    }

    @Override
    public List<WarningInfoListVo> listSevenDayWarning(OrgIdParam orgIdParam) {
        String orgId = orgIdParam.getOrgId();
        List<WarningInfoListVo> warningInfoListVoList = warningInfoMapper.listSevenDayWarning(orgId);
        return warningInfoListVoList;
    }

    @Override
    public Page<WarningInfo> listWarningByType(WarningInfoWarningTypeParam warningTypeParam) {
        String type = warningTypeParam.getType();
        String orgId = warningTypeParam.getOrgId();
        Integer current = warningTypeParam.getCurrent();
        Integer size = warningTypeParam.getSize();
        Page<WarningInfo> page = new Page<>(current,size);
        String warningType;
        Page<WarningInfo> warningInfos = new Page<>();
        QueryWrapper<WarningInfo> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().ge(WarningInfo::getWarningTime,DateUtil.beginOfDay(new Date())).eq(WarningInfo::getWarningStatus,0).eq(WarningInfo::getOrgId,orgId).orderByDesc(WarningInfo::getWarningTime);
        Map<String, String> typeToConfigNameMapping = new HashMap<>();
        typeToConfigNameMapping.put("1", "环控预警");
        typeToConfigNameMapping.put("2", "能耗预警");
        typeToConfigNameMapping.put("3", "巡检预警");
        typeToConfigNameMapping.put("4", "洗消预警");
        typeToConfigNameMapping.put("5", "饲喂预警");
        typeToConfigNameMapping.put("6", "设备预警");
        typeToConfigNameMapping.put("7", "erp预警");
        if (typeToConfigNameMapping.containsKey(type)) {
            // 根据type获取对应的configName
            String configName = typeToConfigNameMapping.get(type);
            // 通过查询数据库获取对应的warningType值
            warningType = baseConfigMapper.selectOne(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getConfigName, configName)).getId();
            queryWrapper.lambda().eq(WarningInfo::getWarningTypeId,warningType);
            warningInfos = this.page(page,queryWrapper);
        }else if ("0".equals(type)){
            warningInfos = this.page(page,queryWrapper);
        }else {
            throw new CommonException("参数范围错误!");
        }
        return warningInfos;
    }

    @Override
    public List<BaseConfig> warningTypeSelector() {
        String parentConfig = baseConfigMapper.selectOne(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getParentId, 0).eq(BaseConfig::getConfigName, "预警类型")).getId();
        return baseConfigMapper.selectList(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getParentId, parentConfig).orderByAsc(BaseConfig::getSortCode));
    }
}
