package cn.com.ty.lift.batch.applet.service;

import cn.com.ty.lift.batch.applet.constants.DataStatisticsConstants;
import cn.com.ty.lift.batch.applet.dao.mapper.ContractDataMapper;
import cn.com.ty.lift.batch.applet.dao.model.ContractDataModel;
import cn.com.ty.lift.batch.applet.dao.model.request.ContractDataRequest;
import cn.com.ty.lift.batch.applet.dao.model.response.DueToContractResponse;
import cn.com.ty.lift.batch.applet.dao.model.response.LostContractResponse;
import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author huangyuan
 * @date 2020/2/3
 * @description
 */
@Service
public class ContractDataService {

    @Resource
    private ContractDataMapper contractDataMapper;

    /**
     * @param contractDataRequest 起始时间 终止时间
     * @return
     * @description 获取合同数据
     * @date 2020/2/4 11:47 上午
     */
    public List<ContractDataModel> getContractDataListFromRedis(ContractDataRequest contractDataRequest) {
        //从redis中获取当前公司合同数据
        List<ContractDataModel> contractDataModelList = contractDataMapper.getContractDataList(contractDataRequest);
        if (contractDataModelList != null && contractDataModelList.size() > 0) {
            //将合同数据变为 id->数据的map
            Map<Long, Long> idToContractModel = contractDataModelList.stream().collect(
                    Collectors.groupingBy(ContractDataModel::getId, Collectors.counting()));
            //设置合同状态
            contractDataModelList.forEach(contractDataModel -> {
                if (contractDataModel.getStatus() != null) {
                    switch (contractDataModel.getStatus()) {
                        case 2:
                            contractDataModel.setContractType(2);
                        case 3:
                            //合同结束，如果有续签，则合同未丢失，如果没有需求合同丢失
                            contractDataModel.setContractType(3);
                            Long count = idToContractModel.get(contractDataModel.getId());
                            if (count != null && count > 0) {
                                contractDataModel.setContractType(0);
                            }
                    }
                }
            });
        }
        return contractDataModelList;
    }

    /**
     * @param
     * @return
     * @description 合同总览
     * @date 2020/2/5 4:35 下午
     */
    public RestResponse contractOverView(ContractDataRequest contractDataRequest) {
        Map<Integer, Long> contractTypeToNum = DataStatisticsConstants.ANNUAL_STATUS_TO_NUM;
        //从redis中获取合同数据
        List<ContractDataModel> contractDataModelList = getContractDataListFromRedis(contractDataRequest);
        if (contractDataModelList != null && contractDataModelList.size() > 0) {
            //设置新增合同数量
            contractTypeToNum.put(1, (long) contractDataModelList.size());
            //设置计划合同数量
//            long planContractNum = contractDataModelList.stream().filter(contractDataModel -> {
//                if (contractDataModel.getContractType() != null) {
//                    return contractDataModel.getContractType() == 2;
//                }
//                return false;
//            }).count();
            Long performContractNum = contractDataMapper.getPerformNum(contractDataRequest);
            contractTypeToNum.put(2, performContractNum);
            //设置丢失合同数量
            long lostContractNum = contractDataModelList.stream().filter(contractDataModel -> {
                if (contractDataModel.getContractType() != null) {
                    return contractDataModel.getContractType() == 3;
                }
                return false;
            }).count();
            contractTypeToNum.put(3, lostContractNum);
        }
        return RestResponse.success(ProjectUtils.transReturnMapToStatisticsKVModel(contractTypeToNum),
                ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 丢失合同统计
     * @date 2020/2/5 4:39 下午
     */
    public RestResponse lostContract(ContractDataRequest contractDataRequest) {
        List<LostContractResponse> lostContractResponseList = new ArrayList<>();
        List<ContractDataModel> contractDataModelList = getContractDataListFromRedis(contractDataRequest);
        if (contractDataModelList != null && contractDataModelList.size() > 0) {
            //定义一个临时变量
            final List<LostContractResponse> finalLostContractResponseList = new ArrayList<>();
            contractDataModelList = contractDataModelList.stream()
                    .filter(contractDataModel -> {
                        if (contractDataModel.getContractType() != null) {
                            return contractDataModel.getContractType() == 3;
                        }
                        return false;
                    })
                    .collect(Collectors.toList());
            //循环设置丢失合同信息
            contractDataModelList.forEach(contractDataModel -> {
                LostContractResponse lostContractResponse = new LostContractResponse();
                lostContractResponse.setContractCode(contractDataModel.getCode());
                lostContractResponse.setProjectName(contractDataModel.getProjectName());
                lostContractResponse.setStartDate(contractDataModel.getStarDate());
                lostContractResponse.setEndDate(contractDataModel.getEndDate());
                //设置应收金额
                double planMoney = contractDataModel.getPlanMoney() != null ? contractDataModel.getPlanMoney().doubleValue() : 0d;
                double workMoney = contractDataModel.getWorkMoney() != null ? contractDataModel.getWorkMoney().doubleValue() : 0d;
                lostContractResponse.setNotReceiveMoney(planMoney - workMoney);
                //设置持续时间
                lostContractResponse.setDuration(0L);
                if (contractDataModel.getStarDate() != null && contractDataModel.getEndDate() != null) {
                    lostContractResponse.setDuration(
                            Duration.between(contractDataModel.getEndDate(), contractDataModel.getStarDate()).toDays());
                }
                finalLostContractResponseList.add(lostContractResponse);
            });
            //通过应收金额降序排列，并取前5的数据
            lostContractResponseList = finalLostContractResponseList.stream()
                    .sorted(Comparator.comparing(LostContractResponse::getNotReceiveMoney)).limit(5)
                    .collect(Collectors.toList());
        }
        return RestResponse.success(lostContractResponseList, ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 到期预警
     * @date 2020/2/5 4:41 下午
     */
    public RestResponse dueToWarn(ContractDataRequest contractDataRequest) {
        List<DueToContractResponse> dueToContractResponseList = new ArrayList<>();
        List<ContractDataModel> contractDataModelList = getContractDataListFromRedis(contractDataRequest);
        if (contractDataModelList != null && contractDataModelList.size() > 0) {
            final List<DueToContractResponse> finalDueToContractResponseList = new ArrayList<>();
            //获取在执行中的合同
            contractDataModelList = contractDataModelList.stream().filter(contractDataModel -> {
                if (contractDataModel.getContractType() != null) {
                    return contractDataModel.getContractType() == 2;
                }
                return true;
            }).collect(Collectors.toList());
            contractDataModelList.forEach(contractDataModel -> {
                DueToContractResponse dueToContractResponse = new DueToContractResponse();
                dueToContractResponse.setCollectDate(contractDataModel.getPlanDate());
                dueToContractResponse.setEndDate(contractDataModel.getEndDate());
                dueToContractResponse.setProjectName(contractDataModel.getProjectName());
                double needMoney = contractDataModel.getPlanMoney() != null ? contractDataModel.getPlanMoney().doubleValue() : 0d;
                dueToContractResponse.setNeedMoney(needMoney);
                finalDueToContractResponseList.add(dueToContractResponse);
            });
            //通过到期时间顺序排列
            dueToContractResponseList = finalDueToContractResponseList.stream()
                    .sorted(Comparator.comparing(DueToContractResponse::getEndDate))
                    .collect(Collectors.toList());
            //如果是前5的数据获取前5的数据
            if ("top5".equals(contractDataRequest.getContractScope())) {
                dueToContractResponseList = dueToContractResponseList.stream()
                        .limit(5).collect(Collectors.toList());
            }
        }
        return RestResponse.success(dueToContractResponseList, ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }
}
