package nckd.jxccl.wtc.wtabm.web.service;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.QueryServiceHelper;
import nckd.jxccl.wtc.wtabm.web.common.constant.WtcConstant;
import nckd.jxccl.wtc.wtabm.web.common.util.WtcUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class VaApplyValidateService {

    private static final Log log = LogFactory.getLog(VaApplyValidateService.class);

    /**
     * 当员工当年事假N天以上，不允许进行当年度年假申请
     * @param bill 请假单数据包
     * @return
     */
    public static String checkOverTimeByPersonalLeave(DynamicObject bill) {
        String msg = null;
        // 先判断当前单据是否请年假
        //DynamicObjectCollection vaTypeCols = bill.getDynamicObjectCollection("vacationtypelist");
        //String vaTypeNumber = vaTypeCols.get(0).getDynamicObject("fbasedataid").getString("number");
        DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("entryentity");
        String vaTypeNumber = entryCols.get(0).getString("entryvacationtype.number");
        if(vaTypeNumber.equals(WtcConstant.ANNUALLEAVE_NUMBER)) {
            Map<String, String> params = WtcUtils.getWtcParams("WTC", WtcConstant.WTC_PARAM_ENTITY);
            // N天
            BigDecimal standardDays = new BigDecimal(params.get("PersonalStandardDays"));
            // 获取历史休事假信息
            List<String> vaTypeNumbers = new ArrayList<String>();
            vaTypeNumbers.add(WtcConstant.PERSONALLEAVE_NUMBER);
            DynamicObjectCollection hisBillCols = getVaApplyInfos(bill, vaTypeNumbers);
            // 汇总
            BigDecimal totalTime = hisBillCols.stream().map(dyn -> dyn.getBigDecimal("applytime")).reduce(BigDecimal.ZERO, BigDecimal::add);
            if(totalTime.compareTo(standardDays) >= 0) {
                msg = String.format("本年度已请事假(%s)天，不允许申请年假！", totalTime);
            }
        }
        return msg;
    }

    /**
     * 社会工龄1年以上10年以下的员工，当年病假累计2个月以上，不允许进行当年度年假申请
     * @param bill 请假单数据包
     * @return
     */
    public static String checkOverTimeByAnnualSickLeave (DynamicObject bill) {
        String msg = "";
        Long employeeId = bill.getLong("attfilebasef7.employee.id");
        // 获取社会工龄：人员档案-服务年限-参加工作年限
        BigDecimal workYear = getWorkYearByEmployeeId(employeeId);
        // 判断是否在1-10年之间
        if(workYear.compareTo(new BigDecimal("1")) >= 0 && workYear.compareTo(new BigDecimal("10")) <= 0) {
            // 先判断当前单据是否请年假
            //DynamicObjectCollection vaTypeCols = bill.getDynamicObjectCollection("vacationtypelist");
            //String vaTypeNumber = vaTypeCols.get(0).getDynamicObject("fbasedataid").getString("number");
            DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("entryentity");
            String vaTypeNumber = entryCols.get(0).getString("entryvacationtype.number");
            if (vaTypeNumber.equals(WtcConstant.ANNUALLEAVE_NUMBER)) {
                Map<String, String> params = WtcUtils.getWtcParams("WTC", WtcConstant.WTC_PARAM_ENTITY);
                BigDecimal standardDays = new BigDecimal(params.get("AnnualSickStandardDays"));
                // 获取历史休事假信息
                List<String> vaTypeNumbers = new ArrayList<String>();
                vaTypeNumbers.add(WtcConstant.ANNUALLEAVE_NUMBER);
                vaTypeNumbers.add(WtcConstant.SICKLEAVE_NUMBER);
                DynamicObjectCollection hisBillCols = getVaApplyInfos(bill, vaTypeNumbers);
                // 汇总
                BigDecimal totalTime = hisBillCols.stream().map(dyn -> dyn.getBigDecimal("applytime")).reduce(BigDecimal.ZERO, BigDecimal::add);
                if (totalTime.compareTo(standardDays) >= 0) {
                    msg = String.format("本年度年病假已超过(%s)天，不允许申请年假！", standardDays);
                }
            }
        }
        return msg;
    }

    /**
     * 获取当年度休假单数据包
     *
     * @param bill
     * @return
     */
    public static DynamicObjectCollection getVaApplyInfos (DynamicObject bill, List<String> vaTypeNumbers) {
        Long employeeId = bill.getLong("attfilebasef7.employee.id");
        Date date = bill.getDate("startdate");
        if(vaTypeNumbers.size() == 0) {
            DynamicObjectCollection vaTypeCols = bill.getDynamicObjectCollection("vacationtypelist");
            vaTypeNumbers.add(vaTypeCols.get(0).getDynamicObject("fbasedataid").getString("number"));
        }
        // 获取date所在年份的第一天和最后一天
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate startDate = LocalDate.of(localDate.getYear(), 1, 1);
        LocalDate endDate = LocalDate.of(localDate.getYear(), 12, 31);

        // 日期过滤
        QFilter dateFilter = new QFilter("enddate", QCP.large_equals, startDate);
        dateFilter.and("enddate", QCP.less_equals, endDate);

        // 人员
        QFilter personFilter = new QFilter("attfilebasef7.employee.id", QCP.equals, employeeId);

        // 单据版本过滤（存在变更，取最新的且时长不为0的），这里直接取审批通过的
        QFilter statusFilter = new QFilter("billstatus", QCP.in, new String[]{"A","B","C"});

        // 休假类型过滤
        QFilter typeFilter = new QFilter("entryentity.entryvacationtype.number", QCP.in, vaTypeNumbers);

        // 排除当前单据
        QFilter idFilter = new QFilter("id", QCP.not_equals, bill.getPkValue());

        // 查询字段
        String selectFields = "startdate,enddate,applytime,billstatus,entryentity.entryvacationtype.name";

        // 查询数据
        DynamicObjectCollection billCols = QueryServiceHelper.query("wtabm_vaapply", selectFields, new QFilter[]{dateFilter, personFilter, statusFilter, typeFilter, idFilter});
        return billCols;
    }

    /**
     * 获取人员服务年限
     * @param employeeId
     * @return
     */
    public static BigDecimal getWorkYearByEmployeeId (Long employeeId) {
        BigDecimal workYear = BigDecimal.ZERO;
        QFilter filter = new QFilter("employee.id", QCP.equals, employeeId);
        String selectFields = "workyear";
        DynamicObject[] cols = WtcConstant.PERSERLEN_HELPER.load(selectFields, new QFilter[]{filter});
        if(cols.length > 0) {
            workYear = cols[0].getBigDecimal("workyear");
        }
        return workYear;
    }

}
