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.PaymentDataMapper;
import cn.com.ty.lift.batch.applet.dao.model.PaymentDataModel;
import cn.com.ty.lift.batch.applet.dao.model.request.PaymentDataRequest;
import cn.com.ty.lift.batch.applet.dao.model.response.ProjectPaymentResponse;
import cn.com.ty.lift.batch.applet.dao.model.response.RegionPaymentResponse;
import cn.com.ty.lift.batch.applet.util.DataStatisticsUtil;
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.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
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 PaymentDataService {

    @Resource
    private PaymentDataMapper paymentDataMapper;

    /**
     * @param paymentDataRequest
     * @return
     * @description 从redis中获取收款数据
     * @date 2020/2/4 2:30 下午
     */
    public List<PaymentDataModel> getPaymentDataListFromRedis(PaymentDataRequest paymentDataRequest) {
        //从redis中获取当前公司的收款数据
        List<PaymentDataModel> paymentDataModelList = paymentDataMapper.getPaymentDataList(paymentDataRequest);
        if (paymentDataModelList != null && paymentDataModelList.size() > 0) {
            //通过合同类型过滤
            if (paymentDataRequest.getPaymentType() != null) {
                paymentDataModelList = paymentDataModelList.stream().filter(paymentDataModel -> {
                    if (paymentDataModel.getPaymentType() != null) {
                        return paymentDataModel.getPaymentType().equals(paymentDataRequest.getPaymentType());
                    }
                    return false;
                }).collect(Collectors.toList());
            }
        }
        return paymentDataModelList;
    }

    /**
     * @param
     * @return
     * @description 收款数据总览
     * @date 2020/2/5 4:55 下午
     */
    public RestResponse paymentOverView(PaymentDataRequest paymentDataRequest) {
        Map<Integer, Double> paymentStatusToMoney = DataStatisticsConstants.PAYMENT_STATUS_TO_MONEY;
        List<PaymentDataModel> paymentDataModelList = getPaymentDataListFromRedis(paymentDataRequest);
        if (paymentDataModelList != null && paymentDataModelList.size() > 0) {
            //计划收款总和
            double totalPlanMoney = paymentDataModelList.stream().mapToDouble(
                    paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getPlanMoney())
            ).sum();
            //实际收款总和
            double totalWorkMoney = paymentDataModelList.stream().mapToDouble(
                    paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getWorkMoney())
            ).sum();
            //超期未收总和
            double totalBeyondMoney = totalPlanMoney - totalWorkMoney;
            paymentStatusToMoney.put(1, totalPlanMoney);
            paymentStatusToMoney.put(2, totalWorkMoney);
            paymentStatusToMoney.put(3, totalBeyondMoney);
        }
        return RestResponse.success(ProjectUtils.transReturnMapToStatisticsKVModel(paymentStatusToMoney),
                ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 站点排名
     * @date 2020/2/5 5:00 下午
     */
    public RestResponse regionRank(PaymentDataRequest paymentDataRequest) {
        List<RegionPaymentResponse> regionPaymentResponseList = new ArrayList<>();
        List<PaymentDataModel> paymentDataModelList = getPaymentDataListFromRedis(paymentDataRequest);
        if (paymentDataModelList != null && paymentDataModelList.size() > 0) {
            //区域名称对应付款数据
            Map<String, List<PaymentDataModel>> regionNameToPaymentData = paymentDataModelList.stream()
                    .collect(Collectors.groupingBy(paymentDataModel -> {
                        if (StringUtils.isNotBlank(paymentDataModel.getRegionName())) {
                            return paymentDataModel.getRegionName();
                        }
                        return "暂无名称";
                    }));
            regionNameToPaymentData.forEach((key, value) -> {
                RegionPaymentResponse regionPaymentResponse = new RegionPaymentResponse();
                //计划收款总和
                double planMoney = value.stream().mapToDouble(
                        paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getPlanMoney())
                ).sum();
                //实际收款总和
                double workMoney = value.stream().mapToDouble(
                        paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getWorkMoney())
                ).sum();
                //超期未收总和
                double beyondMoney = planMoney - workMoney;
                if (beyondMoney > 0d) {
                    regionPaymentResponse.setRegionName(key);
                    regionPaymentResponse.setPlanMoney(planMoney);
                    regionPaymentResponse.setBeyondMoney(beyondMoney);
                    regionPaymentResponseList.add(regionPaymentResponse);
                }
            });
            //通过超期款排名，并取前5的数据
//            regionPaymentResponseList = finalRegionPaymentResponseList.stream()
//                    .sorted(Comparator.comparing(RegionPaymentResponse::getBeyondMoney)).limit(5)
//                    .collect(Collectors.toList());
        }
        return RestResponse.success(regionPaymentResponseList, ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 超期项目统计
     * @date 2020/2/5 5:02 下午
     */
    public RestResponse dueToProject(PaymentDataRequest paymentDataRequest) {
        List<ProjectPaymentResponse> projectPaymentResponseList = new ArrayList<>();
        //从redis中获取收款数据
        List<PaymentDataModel> paymentDataModelList = getPaymentDataListFromRedis(paymentDataRequest);
        if (paymentDataModelList != null && paymentDataModelList.size() > 0) {
            //声明一个final类型变量来封装数据
            final List<ProjectPaymentResponse> finalProjectPaymentResponseList = new ArrayList<>();
            //将数据转化为项目名->付款数据
            Map<String, List<PaymentDataModel>> projectNameToPaymentData = paymentDataModelList.stream()
                    .collect(Collectors.groupingBy(a -> {
                        if (StringUtils.isNotBlank(a.getProjectName())) {
                            return a.getProjectName();
                        }
                        return "暂无名称";
                    }));
            projectNameToPaymentData.forEach((key, value) -> {
                if (value != null && value.size() > 0) {
                    PaymentDataModel paymentDataModel = value.get(0);
                    ProjectPaymentResponse projectPaymentResponse = new ProjectPaymentResponse();
                    projectPaymentResponse.setProjectName(key);
                    //计划收款总和
                    double planMoney = paymentDataModel.getPlanMoney() != null
                            ? paymentDataModel.getPlanMoney().doubleValue() : 0d;
                    //实际收款总和
                    double workMoney = paymentDataModel.getWorkMoney() != null
                            ? paymentDataModel.getWorkMoney().doubleValue() : 0d;
                    //超期未收总和
                    double beyondMoney = planMoney - workMoney;
                    if (beyondMoney > 0d) {
                        projectPaymentResponse.setBeyondAmount(beyondMoney);
                        //超期天数 计划收款和实际收款日期差值
                        LocalDate afterDate = LocalDate.now();
                        if (paymentDataModel.getWorkDate() != null) {
                            afterDate = paymentDataModel.getWorkDate();
                        }
                        if (afterDate != null && paymentDataModel.getPlanDate() != null) {
                            projectPaymentResponse.setDueToDays((long) afterDate.until(
                                    paymentDataModel.getPlanDate()).getDays());
                        }
                        //合同金额
                        double contractMoney = paymentDataModel.getContractMoney() != null
                                ? paymentDataModel.getContractMoney().doubleValue() : 0d;
                        projectPaymentResponse.setContractMoney(contractMoney);
                        finalProjectPaymentResponseList.add(projectPaymentResponse);
                    }
                }
            });
            //通过超期款倒序
            projectPaymentResponseList = finalProjectPaymentResponseList.stream()
                    .sorted(Comparator.comparing(ProjectPaymentResponse::getBeyondAmount).reversed())
                    .collect(Collectors.toList());
            //判断获取的是前5的数据 还是所有数据
            if (projectPaymentResponseList.size() > 5 && "top5".equals(paymentDataRequest.getProjectScope())) {
                projectPaymentResponseList = projectPaymentResponseList.stream().limit(5).collect(Collectors.toList());
            }
        }
        return RestResponse.success(projectPaymentResponseList, ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    public RestResponse paymentMonthOverView(PaymentDataRequest paymentDataRequest) {
        Map<Integer, Double> paymentStatusToMoney = DataStatisticsConstants.PAYMENT_STATUS_TO_MONEY;
        List<PaymentDataModel> paymentDataModelList = getPaymentDataListFromRedis(paymentDataRequest);
        List<PaymentDataModel> beforeBeyondList = paymentDataModelList.stream().filter(paymentDataModel -> {
            if (paymentDataModel.getPlanDate() != null) {
                return DataStatisticsUtil.getMonth(paymentDataModel.getPlanDate()) < paymentDataRequest.getMonth();
            }
            return false;
        }).collect(Collectors.toList());
        //计算之前的超期金额
        double beforeBeyondMoney = 0d;
        if (beforeBeyondList.size() > 0) {
            double beforePlanMoney = beforeBeyondList.stream().mapToDouble(
                    paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getPlanMoney())
            ).sum();
            double beforeWorkMoney = beforeBeyondList.stream().mapToDouble(
                    paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getWorkMoney())
            ).sum();
            beforeBeyondMoney = beforePlanMoney - beforeWorkMoney;
        }
        //本月付款数据
        List<PaymentDataModel> monthPaymentList = paymentDataModelList.stream().filter(paymentDataModel -> {
            if (paymentDataModel.getPlanDate() != null) {
                return DataStatisticsUtil.getMonth(paymentDataModel.getPlanDate()) == paymentDataRequest.getMonth();
            }
            return false;
        }).collect(Collectors.toList());
        //本月数据统计
        double monthPlanMoney = 0d;
        double monthWorkMoney = 0d;
        if (monthPaymentList.size() > 0) {
            monthPlanMoney = monthPaymentList.stream().mapToDouble(
                    paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getPlanMoney())
            ).sum();
            monthWorkMoney = monthPaymentList.stream().mapToDouble(
                    paymentDataModel -> DataStatisticsUtil.getDoubleValue(paymentDataModel.getWorkMoney())
            ).sum();
        }
        paymentStatusToMoney.put(1, monthPlanMoney);
        paymentStatusToMoney.put(2, monthWorkMoney);
        paymentStatusToMoney.put(3, beforeBeyondMoney);
        paymentStatusToMoney.put(4,monthPlanMoney + beforeBeyondMoney);
        //计算之前的超期总和
        return RestResponse.success(paymentStatusToMoney);
    }

}
