package com.fjhx.sale.service.dept.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.utils.Assert;
import com.fjhx.sale.entity.DeptPerfReporting;
import com.fjhx.sale.entity.dept.dto.DeptPerfDto;
import com.fjhx.sale.entity.dept.dto.DeptPerfSelectDto;
import com.fjhx.sale.entity.dept.po.DeptPerf;
import com.fjhx.sale.entity.dept.vo.DeptPerfVo;
import com.fjhx.sale.mapper.dept.DeptPerfMapper;
import com.fjhx.sale.service.dept.DeptPerfService;
import com.ruoyi.common.exception.ServiceException;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门绩效 服务实现类
 * </p>
 *
 * @author
 * @since 2024-01-21
 */
@Service
public class DeptPerfServiceImpl extends ServiceImpl<DeptPerfMapper, DeptPerf> implements DeptPerfService {

    @Override
    public List<DeptPerfVo> getList(DeptPerfDto dto) {
        Assert.notEmpty(dto.getYears(), "年份不能为空！");

        List<DeptPerfVo> list = this.baseMapper.getList(dto);
        for (DeptPerfVo deptPerfVo : list) {
            if (ObjectUtil.isEmpty(deptPerfVo.getId())) {
                deptPerfVo.setId(IdWorker.getId());
            }
        }
        return list;
    }

    @Override
    public void edit(DeptPerfDto dto) {
        Assert.notEmpty(dto.getId(), "Id不能为空！");
        Assert.notEmpty(dto.getYears(), "年份不能为空！");
        Assert.notEmpty(dto.getDeptId(), "部门Id不能为空！");
        Assert.notEmpty(dto.getGroupId(), "组id不能为空！");

        this.saveOrUpdate(dto);
    }

    /**
     * 月报表
     */
    @Override
    public List<JSONObject> monthlyReporting(DeptPerfSelectDto dto) {
        Date date = dto.getBeginTime();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(date);

        String[] split = format.split("-");

        int years = Integer.valueOf(split[0]);
        int month = Integer.valueOf(split[1]);

        List<DeptPerfReporting> dayRepo = baseMapper.getDayRepo(dto);
        Map<Long, List<DeptPerfReporting>> dayRepoMap = dayRepo.stream().collect(Collectors.groupingBy(DeptPerfReporting::getDeptId));


        List<DeptPerfReporting> deptPerfReports = baseMapper.monthlyReporting(dto);

        //获取组目标金额
        Map<Long, DeptPerf> deptPerfMap = this.mapKEntity(DeptPerf::getGroupId, q -> q.eq(DeptPerf::getYears, years));

        for (DeptPerfReporting deptPerfReporting : deptPerfReports) {
            //月金额求和
            deptPerfReporting.setSumAmount(deptPerfReporting.getSumContractAmount().add(deptPerfReporting.getSumJstAmount()));

            //赋值目标金额
            DeptPerf deptPerf = deptPerfMap.get(deptPerfReporting.getGroupId());
            if (ObjectUtil.isNotEmpty(deptPerf)) {
                BigDecimal targetAmount = getTargetAmount(deptPerf, month);
                deptPerfReporting.setTargetAmount(targetAmount.multiply(BigDecimal.valueOf(10000)));
            }

            //赋值完成率
            BigDecimal targetAmount = deptPerfReporting.getTargetAmount();
            if (ObjectUtil.isNotEmpty(targetAmount) && targetAmount.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal sumAmount = deptPerfReporting.getSumAmount();
                BigDecimal multiply = sumAmount.divide(targetAmount, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(0.1));
                deptPerfReporting.setFinishRate(multiply);
            }

        }

        //按金额排序
        Collections.sort(deptPerfReports, new Comparator<DeptPerfReporting>() {
            @Override
            public int compare(DeptPerfReporting p1, DeptPerfReporting p2) {
                return p2.getSumAmount().compareTo(p1.getSumAmount());
            }
        });
        //赋值排名
        for (int i = 0; i < deptPerfReports.size(); i++) {
            DeptPerfReporting deptPerfReporting = deptPerfReports.get(i);
            deptPerfReporting.setRanking(i + 1);
        }

        //按部门排序
        Collections.sort(deptPerfReports, new Comparator<DeptPerfReporting>() {
            @Override
            public int compare(DeptPerfReporting p1, DeptPerfReporting p2) {
                return p1.getDeptId().compareTo(p2.getDeptId());
            }
        });


        //赋值每日信息
        List<JSONObject> reData = new ArrayList<>();

        for (DeptPerfReporting deptPerfReport : deptPerfReports) {
            List<DeptPerfReporting> deptPerfReportList = dayRepoMap.getOrDefault(deptPerfReport.getGroupId(), new ArrayList<>());

            Map<String, DeptPerfReporting> collect = deptPerfReportList.stream().collect(Collectors.toMap(DeptPerfReporting::getDayStr, Function.identity()));

            String s = JSONObject.toJSONString(deptPerfReport);
            JSONObject parse = JSONObject.parse(s);

            List<DateTime> dateTimes = DateUtil.rangeToList(dto.getBeginTime(), dto.getEndTime(), DateField.DAY_OF_MONTH, 1);
            for (DateTime dateTime : dateTimes) {
                String dayStr = sdf.format(dateTime);
                DeptPerfReporting deptPerfRepoList = collect.getOrDefault(dayStr, new DeptPerfReporting());

                parse.put(dayStr, deptPerfRepoList);
            }
            reData.add(parse);
        }


        return reData;
    }

    private BigDecimal getTargetAmount(DeptPerf deptPerf, int month) {
        switch (month) {
            case 1:
                return deptPerf.getJanuary();
            case 2:
                return deptPerf.getFebruary();
            case 3:
                return deptPerf.getMarch();
            case 4:
                return deptPerf.getApril();
            case 5:
                return deptPerf.getMay();
            case 6:
                return deptPerf.getJune();
            case 7:
                return deptPerf.getJuly();
            case 8:
                return deptPerf.getAugust();
            case 9:
                return deptPerf.getSeptember();
            case 10:
                return deptPerf.getOctober();
            case 11:
                return deptPerf.getNovember();
            case 12:
                return deptPerf.getDecember();
            default:
                throw new ServiceException("未知月份：" + month);
        }
    }

}
