package com.ruoyi.system.service.statistics.impl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.loan.LoanApplication;
import com.ruoyi.system.mapper.LoanApplicationMapper;
import com.ruoyi.system.service.statistics.IStatisticsService;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.constant.CommonConstants.*;

/**
 * @Author: tjf
 * @Date: 2024/5/7 14:26
 * @Describe:
 */
@Service
public class StatisticsServiceImpl implements IStatisticsService {
    @Autowired
    private LoanApplicationMapper loanApplicationMapper;

    /**
     * 后台首页统计
     *
     * @return
     */
    @Override
    public AjaxResult loan(LoanApplication loanApplication) {
        //type = 1按年度统计  =2 按月份统计

        //定义返回值
        Map<String, Object> map = new HashMap<>(6);
        //业务审核
        map.put("ywsh", 0);
        //业务完结
        map.put("ywwj", 0);
        //申报审核
        map.put("sbsh", 0);
        //申报完结
        map.put("sbwj", 0);
        //待放款
        map.put("dfk", 0);
        //已放款
        map.put("yfk", 0);
        //查询所有
        List<LoanApplication> loanApplications = loanApplicationMapper.selectLoanApplicationListStatistics(loanApplication);
        if (loanApplications != null && loanApplications.size() > 0) {
            //贷款申请状态 1：暂存 2：正常 3：回收站 4：归档 进行分组
            Map<String, List<LoanApplication>> loanApplicationType = loanApplications.stream().collect(Collectors.groupingBy(LoanApplication::getLoanApplicationType));
            List<LoanApplication> loanApplicationsTwoMap = loanApplicationType.get(TWO);
            if (loanApplicationsTwoMap != null && loanApplicationsTwoMap.size() > 0) {
                map.put("ywsh", loanApplicationsTwoMap.size());
                map.put("sbsh", loanApplicationsTwoMap.size());
                map.put("dfk", loanApplicationsTwoMap.stream().mapToDouble(LoanApplication::getApplicationAmount).sum());
            }
            List<LoanApplication> loanApplicationsForMap = loanApplicationType.get(FOR);
            if (loanApplicationsForMap != null && loanApplicationsForMap.size() > 0) {
                map.put("ywwj", loanApplicationsForMap.size());
                map.put("sbwj", loanApplicationsForMap.size());
                map.put("yfk", loanApplicationsForMap.stream().mapToDouble(LoanApplication::getApplicationAmount).sum());
            }
        }
        return AjaxResult.success(map);
    }

    /**
     * 本月数据
     *
     * @param loanApplication
     * @return
     */
    @Override
    public AjaxResult loanMonth(LoanApplication loanApplication) {
        //type = 1按年度统计  =2 按月份统计
        String beginTime = (String) loanApplication.getParams().get("beginTime");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Map<String, Object> map = new HashMap<>(20);
        double sdje = 0;
        double sdjeLast = 0;
        double fdje = 0;
        double fdjeLast = 0;
        double ywsb = 0;
        double ywsbLast = 0;
        double gd = 0;
        double gdLast = 0;
        double newMonth = 0;
        double newLast = 0;
        double small = 0;
        double smallLast = 0;
        List<Double> list = new ArrayList<>();
        list.add(0D);
        list.add(0D);
        list.add(0D);
        list.add(0D);
        list.add(0D);
        map.put("y", list);
        try {
            DecimalFormat df = new DecimalFormat("##.##%");
            Date date = sdf.parse(beginTime);
            LocalDate localDate = DateUtils.toLocalDate(date);
            //上月
            String lastMonth = formatter.format(localDate.minusMonths(1));
            //本月数据
            List<LoanApplication> loanApplications = loanApplicationMapper.selectLoanApplicationListStatistics(loanApplication);
            loanApplication.getParams().put("beginTime", lastMonth);
            //上月数据
            List<LoanApplication> loanApplicationsLast = loanApplicationMapper.selectLoanApplicationListStatistics(loanApplication);

            //获取本月数据
            if (loanApplications != null && loanApplications.size() > 0) {
                Map<String, List<LoanApplication>> loanApplicationType = loanApplications.stream().collect(Collectors.groupingBy(LoanApplication::getLoanApplicationType));
                List<LoanApplication> loanApplicationsTwoMap = loanApplicationType.get(TWO);
                if (loanApplicationsTwoMap != null && loanApplicationsTwoMap.size() > 0) {
                    //本月申请贷款
                    sdje = loanApplicationsTwoMap.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();

                    //计算Y轴申请贷款金额/每周
                    Map<Date, List<LoanApplication>> collectDate = loanApplicationsTwoMap.stream().collect(Collectors.groupingBy(LoanApplication::getApplicationTime));
                    //第几周的数据
                    double a = 0;
                    double b = 0;
                    double c = 0;
                    double d = 0;
                    double e = 0;
                    for (Date dateTime : collectDate.keySet()) {
                        int weekOfMonth = DateUtils.getWeekOfMonth(dateTime);
                        switch (weekOfMonth) {
                            case 1:
                                a = a + collectDate.get(dateTime).stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                                break;
                            case 2:
                                b = b + collectDate.get(dateTime).stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                                break;
                            case 3:
                                c = c + collectDate.get(dateTime).stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                                break;
                            case 4:
                                d = d + collectDate.get(dateTime).stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                                break;
                            case 5:
                                e = e + collectDate.get(dateTime).stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                                break;
                            default:
                                break;
                        }
                    }

                    List<Double> listDouble = new ArrayList<>();
                    listDouble.add(a);
                    listDouble.add(b);
                    listDouble.add(c);
                    listDouble.add(d);
                    listDouble.add(e);
                    map.put("y", listDouble);
                    ywsb = loanApplicationsTwoMap.size();
                    newMonth = loanApplicationsTwoMap.stream().filter(s -> "Y".equals(s.getIsNew())).count();
                    small = loanApplicationsTwoMap.stream().filter(s -> "Y".equals(s.getIsSmall())).count();
                }
                List<LoanApplication> loanApplicationsForMap = loanApplicationType.get(FOR);
                if (loanApplicationsForMap != null && loanApplicationsForMap.size() > 0) {
                    //本月申请贷款
                    fdje = loanApplicationsForMap.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                    gd = loanApplicationsForMap.size();
                }
            }
            //获取上月数据
            if (loanApplicationsLast != null && loanApplicationsLast.size() > 0) {
                Map<String, List<LoanApplication>> loanApplicationType = loanApplicationsLast.stream().collect(Collectors.groupingBy(LoanApplication::getLoanApplicationType));
                List<LoanApplication> loanApplicationsTwoMap = loanApplicationType.get(TWO);
                if (loanApplicationsTwoMap != null && loanApplicationsTwoMap.size() > 0) {
                    //本月申请贷款
                    sdjeLast = loanApplicationsTwoMap.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                    ywsbLast = loanApplicationsTwoMap.size();
                    newLast = loanApplicationsTwoMap.stream().filter(s -> "Y".equals(s.getIsNew())).count();
                    smallLast = loanApplicationsTwoMap.stream().filter(s -> "Y".equals(s.getIsSmall())).count();
                }
                List<LoanApplication> loanApplicationsForMap = loanApplicationType.get(FOR);
                if (loanApplicationsForMap != null && loanApplicationsForMap.size() > 0) {
                    //本月申请贷款
                    fdjeLast = loanApplicationsForMap.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                    gdLast = loanApplicationsForMap.size();
                }
            }
            //申贷金额
            map.put("sdje", sdje);
            map.put("sdjePt", getNumPt(sdje, sdjeLast, df).get("pt"));
            map.put("sdjePtStatus", getNumPt(sdje, sdjeLast, df).get("ptStatus"));
            //放贷金额
            map.put("fdje", fdje);
            map.put("fdjePt", getNumPt(fdje, fdjeLast, df).get("pt"));
            map.put("fdjePtStatus", getNumPt(fdje, fdjeLast, df).get("ptStatus"));
            //业务申报
            map.put("ywsb", ywsb);
            map.put("ywsbPt", getNumPt(ywsb, ywsbLast, df).get("pt"));
            map.put("ywsbPtStatus", getNumPt(ywsb, ywsbLast, df).get("ptStatus"));
            //归档
            map.put("gd", gd);
            map.put("gdPt", getNumPt(gd, gdLast, df).get("pt"));
            map.put("gdPtStatus", getNumPt(gd, gdLast, df).get("ptStatus"));
            //精特新
            map.put("new", newMonth);
            map.put("newPt", getNumPt(newMonth, newLast, df).get("pt"));
            map.put("newPtStatus", getNumPt(newMonth, newLast, df).get("ptStatus"));
            //小微企业
            map.put("small", small);
            map.put("smallPt", getNumPt(small, smallLast, df).get("pt"));
            map.put("smallPtStatus", getNumPt(small, smallLast, df).get("ptStatus"));
            List<String> xlist = new ArrayList<>();
            xlist.add("第一周");
            xlist.add("第二周");
            xlist.add("第三周");
            xlist.add("第四周");
            xlist.add("第五周");
            map.put("x", xlist);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //定义返回值
        return AjaxResult.success(map);
    }

    /**
     * 季度数据
     *
     * @param loanApplication
     * @return
     */
    @Override
    public AjaxResult loanQuarter(LoanApplication loanApplication) {
        Map<String, Object> map = new HashMap<>(5);
        Map<String, Object> params = loanApplication.getParams();
        params.put("beginTime", DateUtils.getYear());
        //查询本年度所有数据
        loanApplication.setType(ONE);
        loanApplication.setParams(params);
        List<LoanApplication> loanApplications = loanApplicationMapper.selectLoanApplicationListStatistics(loanApplication);
        List<Double> allList = new ArrayList();
        allList.add(0D);
        allList.add(0D);

        List<Double> oneList = new ArrayList();
        oneList.add(0D);
        oneList.add(0D);

        List<Double> twoList = new ArrayList();
        twoList.add(0D);
        twoList.add(0D);

        List<Double> thrList = new ArrayList();
        thrList.add(0D);
        thrList.add(0D);

        List<Double> forList = new ArrayList();
        forList.add(0D);
        forList.add(0D);

        //获取每个季度对应的数据
        if (loanApplications != null && loanApplications.size() > 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("MM");
            //根据贷款申请状态先进行分组
            Map<String, List<LoanApplication>> loanApplicationType = loanApplications.stream().collect(Collectors.groupingBy(LoanApplication::getLoanApplicationType));
            List<LoanApplication> loanApplicationsTwo = loanApplicationType.get(TWO);
            if (loanApplicationsTwo != null && loanApplicationsTwo.size() > 0) {
                //总申请贷款金额
                double sumDFK = loanApplicationsTwo.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                allList.set(0, sumDFK);
                Map<Integer, List<LoanApplication>> collectMap = loanApplicationsTwo.stream().collect(Collectors.groupingBy(e -> (Integer.parseInt(sdf.format(e.getApplicationTime())) - 1) / 3 + 1));
                if (collectMap != null && collectMap.size() > 0) {
                    for (int i = 1; i < 5; i++) {
                        List<LoanApplication> loanApplicationsI = collectMap.get(i);
                        if (loanApplicationsI != null && loanApplicationsI.size() > 0) {
                            double sum = loanApplicationsI.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                            switch (i) {
                                case 1:
                                    oneList.set(0, sum);
                                    break;
                                case 2:
                                    twoList.set(0, sum);
                                    break;
                                case 3:
                                    thrList.set(0, sum);
                                    break;
                                case 4:
                                    forList.set(0, sum);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
            List<LoanApplication> loanApplicationsFor = loanApplicationType.get(FOR);
            if (loanApplicationsFor != null && loanApplicationsFor.size() > 0) {
                //放贷金额
                double sumYFK = loanApplicationsFor.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                allList.set(1, sumYFK);
                Map<Integer, List<LoanApplication>> collectMap = loanApplicationsFor.stream().collect(Collectors.groupingBy(e -> (Integer.parseInt(sdf.format(e.getApplicationTime())) - 1) / 3 + 1));
                if (collectMap != null && collectMap.size() > 0) {
                    for (int i = 1; i < 5; i++) {
                        List<LoanApplication> loanApplicationsI = collectMap.get(i);
                        if (loanApplicationsI != null && loanApplicationsI.size() > 0) {
                            double sum = loanApplicationsI.stream().mapToDouble(LoanApplication::getApplicationAmount).sum();
                            switch (i) {
                                case 1:
                                    oneList.set(1, sum);
                                    break;
                                case 2:
                                    twoList.set(1, sum);
                                    break;
                                case 3:
                                    thrList.set(1, sum);
                                    break;
                                case 4:
                                    forList.set(1, sum);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }

        }
        map.put("all", allList);
        map.put("one", oneList);
        map.put("two", twoList);
        map.put("thr", thrList);
        map.put("for", forList);
        return AjaxResult.success(map);
    }

    //计算两个数的百分比和是上升还是下降
    public static Map<String, String> getNumPt(double a, double b, DecimalFormat df) {
        Map<String, String> map = new HashMap<>(2);
        if (a > 0 && b < 1) {
            map.put("ptStatus", ONE);
            map.put("pt", "100.00%");
            return map;
        } else if (a < 1 && b > 0) {
            map.put("ptStatus", TWO);
            map.put("pt", "100.00%");
            return map;
        } else if (a < 1 && b < 1) {
            map.put("ptStatus", ONE);
            map.put("pt", "0.00%");
            return map;
        } else if (a > 0 && b > 0) {
            if (a > b) {
                map.put("ptStatus", ONE);
                String format = df.format((a - b) / b);
                map.put("pt", format);
            }
            if (b > a) {
                map.put("ptStatus", TWO);
                String format = df.format((b - a) / b);
                map.put("pt", format);
            }
        }
        return map;
    }
}
