package com.gz.service.statistics.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.alibaba.fastjson.JSONObject;
import com.gz.common.DataGlobalVariable;
import com.gz.dto.borrow.ArchiveBorrowDTO;
import com.gz.dto.system.ArchivesTreeDTO;
import com.gz.mapper.borrow.ArchiveBorrowMapper;
import com.gz.mapper.statistics.SelectStatisticsMapper;
import com.gz.mapper.system.ArchivesTreeMapper;
import com.gz.rvo.statistics.ArchiveStatisticsRVO;
import com.gz.rvo.statistics.ArchiveYearStatisticsRVO;
import com.gz.rvo.statistics.BorrowStatisticsRVO;
import com.gz.service.statistics.SelectStatisticsService;
import com.gz.service.system.ArchivesTreeService;
import com.gz.utils.JwtUtils;
import com.gz.vo.statistics.StatisticsVO;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.Id;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 查询统计Service 实现
 *
 * @author LiuchangLan
 * @date 2021/3/8 14:59
 */
@Service
public class SelectStatisticsServiceImpl implements SelectStatisticsService {

    @Resource
    private SelectStatisticsMapper selectStatisticsMapper;

    @Resource
    private ArchivesTreeService archivesTreeService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private ArchiveBorrowMapper archiveBorrowMapper;

    @Override
    public List<ArchiveStatisticsRVO> selectStatisticsByType(StatisticsVO vo) {
        if (vo.getMl() != null) {
            vo.setMlCodes(getMl(vo.getMl()));
        }
        if (!StringUtils.isEmpty(vo.getTime())) {
            vo.setStartTime(vo.getTime().split(" - ")[0]);
            vo.setEndTime(vo.getTime().split(" - ")[1]);
        }
        // 统计结果
        List<ArchiveStatisticsRVO> tree = selectStatisticsMapper.selectArchiveStatistics(vo);
        tree.forEach(e -> {
            if (e.getParentId() == -1) {
                for (ArchiveStatisticsRVO node : tree) {
                    Integer archiveCount = 0;
                    Integer fileCount = 0;
                    if (e.getId().equals(node.getParentId())) {
                        archiveCount += node.getArchiveCount();
                        fileCount += node.getFileCount();
                    }
                    e.setArchiveCount(e.getArchiveCount() + archiveCount);
                    e.setFileCount(e.getFileCount() + fileCount);
                }
            }
        });
        return tree;
    }

    @Override
    public List<ArchiveYearStatisticsRVO> selectArchiveYearStatistics(StatisticsVO vo) {
        if (vo.getMl() != null) {
            vo.setMlCodes(getMl(vo.getMl()));
        }
        if (!StringUtils.isEmpty(vo.getTime())) {
            vo.setStartTime(vo.getTime().split(" - ")[0]);
            vo.setEndTime(vo.getTime().split(" - ")[1]);
        }
        return selectStatisticsMapper.selectArchiveYearStatistics(vo);
    }

    @Override
    public List<BorrowStatisticsRVO> selectBorrowStatistics(StatisticsVO vo) {
        if (vo.getMl() != null) {
            vo.setMlCodes(getMl(vo.getMl()));
        }
        if (!StringUtils.isEmpty(vo.getTime())) {
            vo.setStartTime(vo.getTime().split(" - ")[0]);
            vo.setEndTime(vo.getTime().split(" - ")[1]);
        }
        return selectStatisticsMapper.selectBorrowStatistics(vo);
    }

    private List<String> getMl(Integer id) {
        String key = String.format(DataGlobalVariable.STATISTICS_ML_CODE_KEY_FOMAT, id);
        String listString = stringRedisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(listString)) {
            ArchivesTreeDTO dto = archivesTreeService.selectByPrimaryKey(id);
            List<String> collect = archivesTreeService.selectChildById(id).stream().map(ArchivesTreeDTO::getCode).collect(Collectors.toList());
            if (dto.getParentId() == -1) {
                collect.add(archivesTreeService.selectByPrimaryKey(id).getCode());
            } else {
                collect.add(archivesTreeService.selectParentByCode(dto.getCode()).getCode());
            }
            stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(collect), 1L, TimeUnit.DAYS);
            return collect;
        } else {
            return JSONObject.parseObject(listString, List.class);
        }
    }


    @Override
    public Map<String,Integer> selectUserBorrowCountStatistics() {
        ArchiveBorrowDTO param = new ArchiveBorrowDTO();
        param.setAdminId(JwtUtils.getCurrentUserJwtPayload().getId());
        List<ArchiveBorrowDTO> selectResult = archiveBorrowMapper.select(param);
        Integer dqwgh = 0, // 到期未归还
                jjdq = 0, // 即将到期
                sqwcl = 0, // 申请未处理
                lsjyw = selectResult.size(); // 历史借阅数

        for (ArchiveBorrowDTO item : selectResult) {
            // 当前时间
            DateTime now = DateUtil.date();
            // 预计归还时间
            DateTime estimateReturnTime = DateUtil.parseDate(item.getEstimateReturnTime());
            // 已经过期 未归还 原件借阅 借阅审核已通过
            if (now.before(estimateReturnTime) && item.getReturnStatus() == 0 && item.getBorrowType() == 1 && item.getAuditStatus() == 2){
                dqwgh ++;
            }
            // 剩余3天为即将到期
            if (DateUtil.between(now,estimateReturnTime, DateUnit.DAY) == 3){
                jjdq ++;
            }
            if (item.getBorrowType() == 1 && item.getAuditStatus() == 0){
                sqwcl ++;
            }
        }
        Map<String,Integer> result = new HashMap<>();
        result.put("dqwgh", dqwgh);
        result.put("jjdq", jjdq);
        result.put("sqwcl", sqwcl);
        result.put("lsjyw",lsjyw);
        return result;
    }
}
