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

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.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.base.util.time.DateUtil;
import com.artfess.device.base.dao.DeviceStatusLogDao;
import com.artfess.device.base.dto.StatisticsDto;
import com.artfess.device.base.manager.DeviceStatusLogManager;
import com.artfess.device.base.model.DeviceStatusLog;
import com.artfess.device.base.utils.BizUtils;
import com.artfess.device.base.vo.DeviceStatusTimeVo;
import com.artfess.device.base.vo.StatisticsVo;
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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.Serializable;
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 DeviceStatusLogManagerImpl extends BaseManagerImpl<DeviceStatusLogDao, DeviceStatusLog> implements DeviceStatusLogManager {

    @Resource
    private SysDictionaryManager sdm;

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

    @Override
    public DeviceStatusLog getById(Serializable id) {
        QueryWrapper<DeviceStatusLog> wrapper = new QueryWrapper<DeviceStatusLog>().eq("log.ID_", id);
        List<DeviceStatusLog> result = baseMapper.queryPage(new Page<>(1, -1, 1), wrapper).getRecords();
        return BeanUtils.isEmpty(result) ? null : result.get(0);
    }

    @Override
    public List<StatisticsVo> statistics(StatisticsDto dto) {
        // 字典
        List<DictModel> rqlx = sdm.queryDictListItemsByCode("rqlx");
        List<DictModel> deviceStatus = sdm.queryDictListItemsByCode("sbzt");
        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 = new ArrayList<>();
        if (isYear) {
            Map<String, List<StatisticsVo>> data = baseMapper.statistics(dto).stream()
                    .collect(Collectors.groupingBy(StatisticsVo::getStatus));
            for (Map.Entry<String, List<StatisticsVo>> d : data.entrySet()) {
                StatisticsVo rTemp = new StatisticsVo();
                rTemp.setCount(d.getValue().size());
                rTemp.setStatus(BizUtils.getDicValueByCode(deviceStatus, d.getKey()));
                result.add(rTemp);
            }
        } else {
            // 不是年统计分到下一级
            Map<String, Map<String, List<StatisticsVo>>> data = baseMapper.statistics(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());
                List<StatisticsVo> rtData = new ArrayList<>();
                for (Map.Entry<String, List<StatisticsVo>> t : d.getValue().entrySet()) {
                    StatisticsVo rtdTemp = new StatisticsVo();
                    rtdTemp.setCount(t.getValue().size());
                    rtdTemp.setStatus(BizUtils.getDicValueByCode(deviceStatus, t.getKey()));
                    rtData.add(rtdTemp);
                }
                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> statisticsSub(StatisticsDto dto) {
        Assert.notNull(dto, "参数不能为空！");
        Assert.notNull(dto.getDateType(), "日期类型不能为空！");
        Assert.notNull(dto.getTime(), "日期不能为空！");
        Assert.notNull(dto.getDeviceStatus(), "设备状态不能为空！");
        List<DictModel> rqlx = sdm.queryDictListItemsByCode("rqlx");
        dto.setDateType(BizUtils.getDicValueByCode(rqlx, dto.getDateType()));
        if (StringUtil.isEmpty(dto.getDateType())) {
            throw new RuntimeException("未定义的日期类型！");
        }
        return baseMapper.statisticsSub(dto);
    }

    @Override
    public List<StatisticsVo> statisticsTrouble(StatisticsDto dto) {
        // 字典
        List<DictModel> deviceType = sdm.queryDictListItemsByCode("sblx");
        List<DictModel> rqlx = sdm.queryDictListItemsByCode("rqlx");

        // 默认格式
        dto.setDeviceStatus("2");
        dto.setDateType(BizUtils.getDicValueByCode(rqlx, dto.getDateType()));
        if (StringUtil.isEmpty(dto.getDateType())) {
            dto.setDateType("%Y-%m-%d");
        }

        List<StatisticsVo> result = new ArrayList<>();
        Map<String, List<StatisticsVo>> data = baseMapper.statistics(dto).stream().collect(Collectors.groupingBy(StatisticsVo::getType));
        for (Map.Entry<String, List<StatisticsVo>> t : data.entrySet()) {
            StatisticsVo vo = new StatisticsVo();
            vo.setType(BizUtils.getDicValueByCode(deviceType, t.getKey()));
            vo.setCount(t.getValue().size());
            result.add(vo);
        }
        return result;
    }

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

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

    @Override
    public PageList<DeviceStatusTimeVo> timeStatistics(QueryFilter<DeviceStatusLog> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        Map<String, Object> params = queryFilter.getParams();
        IPage<DeviceStatusTimeVo> result = baseMapper.failureStatistics(convert2IPage(pageBean), params);
        result.getRecords().forEach(deviceStatusTimeVo -> {
            if (!"0".equals(deviceStatusTimeVo.getTimeLength())) {
                deviceStatusTimeVo.setTimeLength((int) Math.floor(Integer.parseInt(deviceStatusTimeVo.getTimeLength()) / 60) + "时" + Integer.parseInt(deviceStatusTimeVo.getTimeLength()) % 60 + "分");
            }
            if (!"0".equals(deviceStatusTimeVo.getTimeLength1())) {
                deviceStatusTimeVo.setTimeLength1((int) Math.floor(Integer.parseInt(deviceStatusTimeVo.getTimeLength1()) / 60) + "时" + Integer.parseInt(deviceStatusTimeVo.getTimeLength1()) % 60 + "分");
            }

        });
        return new PageList<DeviceStatusTimeVo>(result);
    }
}
