package com.ruoyi.interfaces.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.CustomQueryWrapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.interfaces.domain.PtService;
import com.ruoyi.interfaces.domain.PtServiceLog;
import com.ruoyi.interfaces.domain.Statistics;
import com.ruoyi.interfaces.domain.vo.StatisticsVo;
import com.ruoyi.interfaces.mapper.StatisticsMapper;
import com.ruoyi.interfaces.service.PtServiceService;
import com.ruoyi.interfaces.service.StatisticsService;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LinQiLong
 * @date 2022/1/14 10:16
 */
@Service
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private PtServiceService serviceService;


    private final StatisticsMapper mapper;

    public StatisticsServiceImpl(StatisticsMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public Map<String, Integer> cntByCatalog() {
        // 获取全部数据
        List<Statistics> statisticsList = mapper.getStatisticsData();
        // 分组获取总请求量
        Map<String, Integer> map = statisticsList.stream()
                .collect(Collectors.groupingBy(Statistics::getCateName, Collectors.summingInt(Statistics::getCnt)));
        // 筛选前十数据
        map = map.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
                .limit(10)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        return map;
    }

    @Override
    public Map<String, Long> srvNumByServiceDept() {
        // 获取全部数据
        QueryWrapper<PtService> wrapper = new CustomQueryWrapper<>();
        wrapper.eq("status", "1");
        List<PtService> statisticsList = serviceService.list(wrapper);
        // 分组获取总请求量
        Map<String, Long> map = statisticsList.stream()
                .collect(Collectors.groupingBy(PtService::getServiceDept, Collectors.counting()));
        // 筛选前十数据
        map = map.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
                .limit(10)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        return map;
    }

    @Override
    public Map<String, Integer> total() {
        Map<String, Integer> map = new HashMap<>(12);
        int serviceTotal = mapper.getServiceTotal();
        map.put("serviceTotal", serviceTotal);
        map.put("interfaceNum", serviceTotal);
        int viewNum = mapper.getViewNum();
        map.put("viewNum", viewNum);
        int userNum = mapper.getUserNum();
        map.put("userNum", userNum);
        int dataSetDownloadNum = mapper.getDataSetDownloadNum();
        map.put("dataSetDownloadNum", dataSetDownloadNum);
        int cnt = mapper.getCnt();
        map.put("cnt", cnt);
        int dataSetNum = mapper.getDataSetNum();
        map.put("dataSetNum", dataSetNum);
        map.put("fileNum", dataSetNum);
        int deptNum = mapper.getDeptNum();
        map.put("deptNum", deptNum);
        int cateNum = mapper.getCateNum();
        map.put("cateNum", cateNum);
        map.put("dataItemNum", 0);
        return map;
    }

    @Override
    public Map<String, Integer> keywords() {
        List<StatisticsVo> statisticsVoList = mapper.keywords();
        return statisticsVoList.stream()
                .collect(Collectors.toMap(StatisticsVo::getName, StatisticsVo::getValue));
    }

    @Override
    public List<StatisticsVo> viewNumByCity() {
        return mapper.viewNumByCity();
    }

    @Override
    public List<StatisticsVo> serviceByCnt() {
        List<Statistics> serviceList = mapper.serviceByCnt();
        List<StatisticsVo> statisticsVoList = new ArrayList<>(10);
        serviceList.forEach(ptService -> {
            statisticsVoList.add(new StatisticsVo(ptService.getName(), ptService.getCnt()));
        });
        return statisticsVoList;
    }

    @Override
    public Map<String, Object> lastTwoWeeksCnt() {
        Map<String, Object> ret = new HashMap<>();
    /*    Map<String, Long> thisWeekMap = new LinkedHashMap<>();
        Map<String, Long> lastWeekMap = new LinkedHashMap<>();
        List<String> weekList = new ArrayList<>();

        // 上两周时间
        Date lastTwoWeekDay = getLastTwoWeekDay();
        Date date = new Date();

        QueryWrapper<PtServiceLog> wrapper = new CustomQueryWrapper<>();
        wrapper.gt("tm", lastTwoWeekDay);
        // 获取记录时间
        List<PtServiceLog> logList = logService.list(wrapper);

        int i = 1;
        while (date.getTime() >= lastTwoWeekDay.getTime()) {
            String dateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, lastTwoWeekDay);
            long lastTwoWeekDayMilliseconds = lastTwoWeekDay.getTime();
            long num = logList.stream()
                    .filter(log -> lastTwoWeekDayMilliseconds == delTime(log.getTm()).getTime())
                    .count();

            if (i <= 7) {
                lastWeekMap.put(dateStr, num);
                weekList.add(getWeekOfDate(lastTwoWeekDay));
            } else {
                thisWeekMap.put(dateStr, num);
            }

            lastTwoWeekDay = DateUtils.addDays(lastTwoWeekDay, 1);
            i++;
        }
        ret.put("thisWeekMap", thisWeekMap);
        ret.put("lastWeekMap", lastWeekMap);
        ret.put("weekList", weekList);*/
        return ret;
    }

    @Override
    public Map<String, Long> totalByParam(String param) {
        param = Optional.ofNullable(param).orElse("");
        // 获取全部数据
        QueryWrapper<PtService> wrapper = new CustomQueryWrapper<>();
        wrapper.eq("status", "1");
        List<PtService> statisticsList = serviceService.list(wrapper);
        Map<String, Long> map = new HashMap<>();
        // 分组获取总请求量
        switch (param) {
            case "serviceDept":
                map = statisticsList.stream()
                        .collect(Collectors.groupingBy(PtService::getServiceDept, Collectors.counting()));
                break;
            case "serviceSource":
                map = statisticsList.stream()
                        .collect(Collectors.groupingBy(PtService::getServiceSource, Collectors.counting()));
                break;
            case "maintainUnit":
                map = statisticsList.stream()
                        .collect(Collectors.groupingBy(PtService::getMaintainUnit, Collectors.counting()));
                break;
            case "developUnit":
                map = statisticsList.stream()
                        .collect(Collectors.groupingBy(PtService::getDevelopUnit, Collectors.counting()));
                break;
            default:
        }
        // 筛选前十数据
        map = map.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
                .limit(10)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        return map;
    }

    @Override
    public List<Map<String, Object>> getMaintainUnitSystemTree() {
        List<Map<String, Object>> ret = new ArrayList<>();
        // 获取全部数据
        QueryWrapper<PtService> wrapper = new CustomQueryWrapper<>();
        wrapper.eq("status", "1");
        List<PtService> statisticsList = serviceService.list(wrapper);
        Map<String, Long> maintainUnitMap = statisticsList.stream()
                .collect(Collectors.groupingBy(PtService::getMaintainUnit, Collectors.counting()));

        Iterator it = maintainUnitMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Object, Object> m = (Map.Entry<Object, Object>) it.next();
            Map<String, Object> maintainUnit = new HashMap<>();
            maintainUnit.put("name", m.getKey());
            maintainUnit.put("value", m.getValue());
            ret.add(maintainUnit);
        }

        for (Map<String, Object> map : ret) {
            Map<String, Long> source = statisticsList.stream()
                    .filter(o -> MapUtils.getString(map, "name").equals(o.getMaintainUnit()))
                    .collect(Collectors.groupingBy(PtService::getServiceSource, Collectors.counting()));
            if (!source.isEmpty()) {
                List<Map<String, Object>> sourceList = new ArrayList<>();
                Iterator sourceIt = source.entrySet().iterator();
                while (sourceIt.hasNext()) {
                    Map.Entry<Object, Object> m = (Map.Entry<Object, Object>) sourceIt.next();
                    Map<String, Object> s = new HashMap<>();
                    s.put("name", m.getKey());
                    s.put("value", m.getValue());
                    sourceList.add(s);
                }
                map.put("children", sourceList);
            }
        }

        return ret;
    }

    @Override
    public Map<String, Object> getUnitSystemDept() {
        Set<String> nodeSet = new HashSet<>();
        List<Map<String, String>> nodes = new ArrayList<>();
        List<Map<String, Object>> links = new ArrayList<>();
        // 获取全部数据
        QueryWrapper<PtService> wrapper = new CustomQueryWrapper<>();
        wrapper.eq("status", "1");
        List<PtService> statisticsList = serviceService.list(wrapper);
        // 多级分组
        Map<String, Map<String, Long>> resultMap = statisticsList.stream()
                .collect(Collectors.groupingBy(PtService::getMaintainUnit,
                        Collectors.groupingBy(PtService::getServiceSource,
                                Collectors.counting())));
        links.addAll(getSangjiList(resultMap, nodeSet));

        Map<String, Map<String, Long>> resultMap2 = statisticsList.stream()
                .collect(Collectors.groupingBy(PtService::getServiceSource,
                        Collectors.groupingBy(PtService::getServiceDept,
                                Collectors.counting())));
        links.addAll(getSangjiList(resultMap2, nodeSet));

        nodeSet.forEach(node -> {
            Map<String, String> n = new HashMap<>(1);
            n.put("name", node);
            nodes.add(n);
        });

        Map<String, Object> ret = new HashMap<>(2);
        ret.put("nodes", nodes);
        ret.put("links", links);
        return ret;
    }

    @Override
    public List<StatisticsVo> totalByCatalog() {
        // 获取全部数据
        List<Statistics> statisticsList = mapper.getStatisticsData();
        // 分组获取总请求量
        return statisticsList.stream()
                .collect(Collectors.groupingBy(Statistics::getCateName, Collectors.counting()))
                .entrySet()
                .stream()
                .map(entry -> new StatisticsVo(entry.getKey(), Integer.parseInt(String.valueOf(entry.getValue()))))
                .sorted(Comparator.comparing(StatisticsVo::getValue).reversed())
                .collect(Collectors.toList());
    }

    List<Map<String, Object>> getSangjiList(Map<String, Map<String, Long>> resultMap, Set<String> nodeSet) {
        List<Map<String, Object>> ret = new ArrayList<>();
        for (Map.Entry<String, Map<String, Long>> entry : resultMap.entrySet()) {
            String mapKey = entry.getKey();
            nodeSet.add(mapKey);
            Map<String, Long> mapValue = entry.getValue();
            if (!mapValue.isEmpty()) {
                for (Map.Entry<String, Long> e : mapValue.entrySet()) {
                    if (mapKey.equals(e.getKey())) {
                        continue;
                    }
                    Map<String, Object> item = new HashMap<>();
                    item.put("source", mapKey);
                    item.put("target", e.getKey());
                    item.put("value", e.getValue());
                    ret.add(item);
                    nodeSet.add(e.getKey());
                }
            }
        }
        return ret;
    }

    /**
     * 获取两周前时间
     *
     * @return
     */
    private Date getLastTwoWeekDay() {
        Calendar c = Calendar.getInstance();
        // 1. 过去七天
        c.setTime(new Date());
        c.add(Calendar.DATE, -13);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    private Date delTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    private String getWeekOfDate(Date date) {
        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int index = c.get(Calendar.DAY_OF_WEEK) - 1;
        return weekDays[index];
    }

}
