package com.engine.salary.timer;

import com.engine.common.util.ServiceUtil;
import com.engine.salary.entity.salaryBill.param.SalarySendGrantParam;
import com.engine.salary.entity.salaryBill.po.SalarySendInfoPO;
import com.engine.salary.entity.salaryBill.po.SalarySendPO;
import com.engine.salary.entity.salaryBill.po.SalaryTemplatePO;
import com.engine.salary.service.SalaryBillService;
import com.engine.salary.service.SalarySendService;
import com.engine.salary.service.SalaryTemplateService;
import com.engine.salary.service.impl.SalaryBillServiceImpl;
import com.engine.salary.service.impl.SalarySendServiceImpl;
import com.engine.salary.service.impl.SalaryTemplateServiceImpl;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import weaver.hrm.User;
import weaver.interfaces.schedule.BaseCronJob;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Harryxzy
 * @ClassName AutoSendSalaryJob
 * @date 2023/07/03 10:39
 * @description 自动发送工资单
 */
public class AutoSendSalaryJob extends BaseCronJob {

    private SalarySendService getSalarySendService(User user) {
        return ServiceUtil.getService(SalarySendServiceImpl.class, user);
    }

    private SalaryTemplateService getSalaryTemplateService(User user) {
        return ServiceUtil.getService(SalaryTemplateServiceImpl.class, user);
    }

    private SalaryBillService getSalaryBillService(User user) {
        return ServiceUtil.getService(SalaryBillServiceImpl.class, user);
    }

    @Override
    public void execute() {
        User tempUser = new User();
        tempUser.setUid(1);
        tempUser.setLoginid("sysadmin");
        // 获取所有设置了定时发送的默认工资单模板
        List<SalaryTemplatePO> autoSendTemplate = getSalaryTemplateService(tempUser).getAutoSendTemplate();
        Map<Long, SalaryTemplatePO> autoSendTypeMap = SalaryEntityUtil.convert2Map(autoSendTemplate, SalaryTemplatePO::getSalarySobId);
        List<Long> salarySobIds = autoSendTemplate.stream().map(SalaryTemplatePO::getSalarySobId).collect(Collectors.toList());
        // 获取这些模板下未发放完的正常(非补发、非冻结)工资单
        List<SalarySendPO> salarySendList = getSalarySendService(tempUser).getNeedSendListBySalarySobIds(salarySobIds);

        LocalDateTime nowLocalDateTime = SalaryDateUtil.dateToLocalDateTime(new Date());
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
        List<Long> needSendIds = salarySendList.stream().filter(sendPO -> {
            SalaryTemplatePO templatePO = autoSendTypeMap.get(sendPO.getSalarySobId());
            if (templatePO == null) {
                return false;
            }
            LocalDate autoSendDate = null;
            if (templatePO.getAutoSendCycleType() == 1) {
                // 薪资所属月当月
                autoSendDate = SalaryDateUtil.dateToLocalDate(sendPO.getSalaryMonth());
            } else {
                // 薪资所属月下月
                autoSendDate = SalaryDateUtil.dateToLocalDate(sendPO.getSalaryMonth()).plusMonths(1);
            }
            int maxDays = autoSendDate.lengthOfMonth();
            Integer sendDays = Integer.valueOf(templatePO.getAutoSendDayOfMonth());
            if (sendDays.intValue() > maxDays) {
                sendDays = maxDays;
            }
            autoSendDate = autoSendDate.withDayOfMonth(sendDays);
            LocalDateTime autoSendDateTime = null;
            try {
                // 加上时间
                autoSendDateTime = autoSendDate.atTime(SalaryDateUtil.dateToLocalDateTime(timeFormat.parse(templatePO.getAutoSendTimeOfDay())).toLocalTime());
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            if (!autoSendDateTime.isAfter(nowLocalDateTime)) {
                // 自动发放时间早于或等于现在的发放记录
                return true;
            }
            return false;
        }).map(SalarySendPO::getId).collect(Collectors.toList());

        // 获取工资单发放记录下需要发放的工资单明细
        List<SalarySendInfoPO> needSendInfoList = getSalarySendService(tempUser).getNeedSendInfoList(needSendIds);
        Map<Long, Set<Long>> sendMap = SalaryEntityUtil.group2Map(needSendInfoList, SalarySendInfoPO::getSalarySendId, SalarySendInfoPO::getId);
        for(Map.Entry<Long, Set<Long>> entry : sendMap.entrySet()){
            // 发放
            getSalaryBillService(tempUser).grant(SalarySendGrantParam.builder().salarySendId(entry.getKey()).ids(new ArrayList<Long>(entry.getValue())).build());
        }
    }
}
