package nckd.jimin.jyyy.fi.task;

import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.exception.KDException;
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.schedule.api.StopTask;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.CollectionUtils;
import nckd.jimin.jyyy.fi.common.constant.BillTypeConstants;
import nckd.jimin.jyyy.fi.common.constant.JobPositionBakBillConstant;
import nckd.jimin.jyyy.fi.common.util.CommonUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 人员岗位职级备份任务
 */
public class PersonJobPositionBakTask extends AbstractTask implements StopTask {
    private static final Log logger = LogFactory.getLog(PersonJobPositionBakTask.class);
    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        logger.info("PersonJobPositionBakTask begin ");
        // 将备份表中最新的岗位、职级信息保存
        Map<Long, DynamicObject> hisBakBillMap = getHisPersonJobPositionBak();
        List<Object> hisBakBillIdList = hisBakBillMap.values().stream().map(r -> r.getPkValue()).collect(Collectors.toList());

        logger.info("hisBakBillIdList size " + hisBakBillIdList.size());

        // 创建最新的人员表
        List<DynamicObject> newJobPosotionBakBill = createNewJobPosotionBakBill(hisBakBillMap);

        logger.info("newJobPosotionBakBill size " + newJobPosotionBakBill.size());

        SaveServiceHelper.save(newJobPosotionBakBill.toArray(new DynamicObject[0]));
        DeleteServiceHelper.delete(JobPositionBakBillConstant.ENTITYID,new QFilter(JobPositionBakBillConstant.ID, QCP.in,hisBakBillIdList).toArray());

        logger.info("PersonJobPositionBakTask end ");

    }

    protected List<DynamicObject> createNewJobPosotionBakBill(Map<Long, DynamicObject> hisBakBillMap){
        List<DynamicObject> bakBillList = new ArrayList<>();
        Date syncDate = new Date();
        // 查询当前生效的人员岗位信息
        DynamicObjectCollection positionCol = QueryServiceHelper.query(BillTypeConstants.HRPI_EMPPOSORGREL, "person.id,position.id,company.id", new QFilter[]{
                new QFilter("businessstatus", QCP.equals, "1"),
                new QFilter("iscurrentversion", QCP.equals, "1"),
                new QFilter("datastatus", QCP.equals, "1"),
                new QFilter("isprimary", QCP.equals, "1")
        });

        // 查询最新的同步时间是不是当前月，是的历史岗位、职级信息不变
        DynamicObjectCollection newestBakBillCol = QueryServiceHelper.query(JobPositionBakBillConstant.ENTITYID, JobPositionBakBillConstant.KEY_NCKD_UPDATETIME, QFilter.isNotNull(JobPositionBakBillConstant.ID).toArray(), "nckd_updatetime desc", 1);
        // 是否更新
        boolean isOnlyUpdateNew = false;
//        if(newestBakBillCol != null && newestBakBillCol.size() > 0){
//            Date updateTime = newestBakBillCol.get(0).getDate(JobPositionBakBillConstant.KEY_NCKD_UPDATETIME);
//            if(updateTime != null
//                    && updateTime.getYear() == Calendar.getInstance().get(Calendar.YEAR)
//                    && updateTime.getMonth() == Calendar.getInstance().get(Calendar.MONTH)){
//                isOnlyUpdateNew = true;
//            }
//        }


        // 查询当前生效的人员职级信息
        Map<Long, Long> personJobMap = QueryServiceHelper.query(BillTypeConstants.HRPI_EMPJOBREL, "person.id,joblevel.id", new QFilter[]{
                new QFilter("businessstatus", QCP.equals, "1"),
                new QFilter("datastatus", QCP.equals, "1"),
                new QFilter("iscurrentversion", QCP.equals, "1")
        }).stream().collect(Collectors.toMap(r -> r.getLong("person.id"), r -> r.getLong("joblevel.id"), (k1, k2) -> k1));
        for(DynamicObject position : positionCol){
            long personId = position.getLong("person.id");
            DynamicObject userInfo = CommonUtils.getUserByHrPersonId(personId);
            Long userId = userInfo.getLong("id");
            if(userInfo != null) {
                DynamicObject bakBillInfo = BusinessDataServiceHelper.newDynamicObject(JobPositionBakBillConstant.ENTITYID);
                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_USER, userInfo);
                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW, position.getLong("company.id"));
                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_POSITION_NEW, position.getLong("position.id"));
                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_UPDATETIME, syncDate);
                if(personJobMap.containsKey(personId)){
                    bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_NEW, personJobMap.get(personId));
                }
                bakBillList.add(bakBillInfo);

                // 备份表数据为空，则新旧数据相同
                if(CollectionUtils.isEmpty(newestBakBillCol)){
                    bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_ORG_OLD, bakBillInfo.get(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW));
                    bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_POSITION_OLD, bakBillInfo.get(JobPositionBakBillConstant.KEY_NCKD_POSITION_NEW));
                    bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_OLD, bakBillInfo.get(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_NEW));
                }else{
                    if(hisBakBillMap.containsKey(userId)){
                        DynamicObject hisBakInfo = hisBakBillMap.get(userId);
                        if(hisBakInfo != null){
                            if(isOnlyUpdateNew){
                                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_ORG_OLD, hisBakInfo.get(JobPositionBakBillConstant.KEY_NCKD_ORG_OLD));
                                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_POSITION_OLD, hisBakInfo.get(JobPositionBakBillConstant.KEY_NCKD_POSITION_OLD));
                                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_OLD, hisBakInfo.get(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_OLD));
                            }else{
                                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_ORG_OLD, hisBakInfo.get(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW));
                                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_POSITION_OLD, hisBakInfo.get(JobPositionBakBillConstant.KEY_NCKD_POSITION_NEW));
                                bakBillInfo.set(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_OLD, hisBakInfo.get(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_NEW));
                            }
                        }
                    }
                }
            }
        }
        return bakBillList;
    }

    protected Map<Long, DynamicObject> getHisPersonJobPositionBak(){
        Set<Long> bakBillIdSet = QueryServiceHelper.query(JobPositionBakBillConstant.ENTITYID, JobPositionBakBillConstant.ID, QFilter.isNotNull(JobPositionBakBillConstant.ID).toArray())
                .stream()
                .map(r -> r.getLong(JobPositionBakBillConstant.ID))
                .collect(Collectors.toSet());
        return Arrays.stream(BusinessDataServiceHelper.load(bakBillIdSet.toArray(new Long[0]), EntityMetadataCache.getDataEntityType(JobPositionBakBillConstant.ENTITYID)))
                .collect(Collectors.toMap(r -> r.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_USER).getLong(JobPositionBakBillConstant.ID), r -> r, (a, b) -> a));
    }
}
