package nckd.jimin.jyyy.fi.plugin.operate;

import com.google.common.collect.Lists;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.db.tx.TX;
import kd.bos.db.tx.TXHandle;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.operate.result.OperateErrorInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.AfterOperationArgs;
import kd.bos.entity.plugin.args.InitOperationArgs;
import kd.bos.entity.validate.ErrorLevel;
import kd.bos.exception.KDBizException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import nckd.jimin.jyyy.fi.common.constant.PersonReimSyncTaskConstant;
import nckd.jimin.jyyy.fi.plugin.operate.Helper.PersonReimQuotaHelper;

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

public class PersonReimSyncQuotaTaskOp extends AbstractOperationServicePlugIn {
    private static final Log logger = LogFactory.getLog(PersonReimSyncQuotaTaskOp.class);

    protected PersonReimQuotaHelper personReimQuotaHelper;
    @Override
    public void initialize(InitOperationArgs e) {
        super.initialize(e);
        personReimQuotaHelper = new PersonReimQuotaHelper();
    }

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        super.onPreparePropertys(e);
    }

    @Override
    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
        super.afterExecuteOperationTransaction(e);
        DynamicObject[] dataEntities = e.getDataEntities();
        String operationKey = e.getOperationKey();

        List<Object> billIdList = Arrays.stream(dataEntities).map(r -> r.get(PersonReimSyncTaskConstant.ID)).collect(Collectors.toList());
        // 同步个人额度
        if(PersonReimSyncTaskConstant.OPERATE.SYNCPERSONREIM.equals(operationKey)){
            List<List<Object>> patchList = Lists.partition(billIdList, 50);
            for(List<Object> patchBillList : patchList){
                DynamicObject[] billDatas = BusinessDataServiceHelper.load(patchBillList.toArray(), EntityMetadataCache.getDataEntityType(PersonReimSyncTaskConstant.ENTITYID));
                Arrays.stream(billDatas).forEach(r -> doSyncPersonReim(r));
            }
        }

    }
    protected void doSyncPersonReim(DynamicObject billInfo){
        // 校验数据是否合格
////        DynamicObject user = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_USER);
////        DynamicObject org = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_ORG);
////        DynamicObject preOrg = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_ORG_PRE);
////        DynamicObject position = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_POSITIONHR);
////        DynamicObject prePosition = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_POSITIONHR_PRE);
////        DynamicObject jobLever = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_JOBLEVELHR);
////        DynamicObject preJobLever = billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_JOBLEVELHR_PRE);
////
////        int year = billInfo.getInt(PersonReimSyncTaskConstant.KEY_NCKD_YEAR);
////        // 增加事务控制，如果发生异常，回滚生成的额度信息，保持数据一致
////        try(TXHandle h = TX.requiresNew(getClass().getName()+"doSyncPersonReim")){
////            try {
////                // 校验数据
////                checkData(billInfo);
////                // 获取总额度  费用项目、职级、岗位
////                Map<Long, Map<Long, BigDecimal>> currencyReimJobAmount = personReimQuotaHelper.getExpenseJobAmount(position.getPkValue(), jobLever.getPkValue());
////                // 判断组织是否存在便变更，组织变更则作废原组织
////                if(!org.getPkValue().equals(preOrg.getPkValue())){
////                    personReimQuotaHelper.doInvalidPersonReim(user.getLong(PersonReimSyncTaskConstant.ID),preOrg.getLong(PersonReimSyncTaskConstant.ID),null,null,year);
////                }
////
////                // 变更前岗位、职位为空，直接新增
////                if(prePosition == null || preJobLever == null){
////                    personReimQuotaHelper.createPersonReimDirect(billInfo,currencyReimJobAmount);
////                }else{
////                    Map<Long, Map<Long, BigDecimal>> sourceCurrencyReimJobAmount = personReimQuotaHelper.getExpenseJobAmount(prePosition.getPkValue(), preJobLever.getPkValue());
////                    Set<Long> invalidCurrencySet = sourceCurrencyReimJobAmount.keySet().stream()
////                            .filter(r -> !currencyReimJobAmount.keySet().contains(r)).collect(Collectors.toSet());
////                    // 作废已删除的币别数据
////                    logger.info(String.format("需要作废的币别ID为：" + StringUtils.join(",",invalidCurrencySet)));
////                    invalidCurrencySet.forEach(r -> personReimQuotaHelper.doInvalidPersonReim(user.getLong(PersonReimSyncTaskConstant.ID),org.getLong(PersonReimSyncTaskConstant.ID),null,r,year));
////                    for(Map.Entry<Long, Map<Long, BigDecimal>> currencyRow : currencyReimJobAmount.entrySet()){
////                        Long currencyId = currencyRow.getKey();
////                        Map<Long, BigDecimal> expenseJobAmount = currencyRow.getValue();
////                        if(sourceCurrencyReimJobAmount.containsKey(currencyId)){
////                            Set<Long> invalidExpenseSet = sourceCurrencyReimJobAmount.get(currencyId).keySet().stream()
////                                    .filter(r -> !expenseJobAmount.keySet().contains(r)).collect(Collectors.toSet());
////                            logger.info(String.format("需要作废的费用类型ID为：" + StringUtils.join(",",invalidExpenseSet)));
////                            invalidExpenseSet.forEach(r -> personReimQuotaHelper.doInvalidPersonReim(user.getLong(PersonReimSyncTaskConstant.ID),org.getLong(PersonReimSyncTaskConstant.ID),r,currencyId,year));
////                        }
////                        for(Map.Entry<Long, BigDecimal> dataRow : expenseJobAmount.entrySet()){
////                            Long expenseItemId = dataRow.getKey();
////                            BigDecimal amount = dataRow.getValue();
////                            personReimQuotaHelper.createPersonReimByExpense(billInfo,currencyId,expenseItemId,amount);
////                        }
////                    }
////                }
//                addRecord(billInfo,"创建成功。",Boolean.TRUE);
//            }catch (Exception e){
//                logger.error(String.format("单据%s同步额度失败",billInfo.getString(PersonReimSyncTaskConstant.KEY_NUMBER)),e);
//                String errorMsg = StringUtils.isEmpty(e.getMessage())?"同步额度时发生未知异常，请用traceid在monitor通过任务编码查看日志详情。":e.getMessage();
//                addRecord(billInfo,errorMsg,Boolean.FALSE);
//                h.markRollback();
//            }
//        }
//        SaveServiceHelper.save(new DynamicObject[]{billInfo});
    }




    protected void checkData(DynamicObject billInfo){
        if(billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_USER) == null){
            throw new KDBizException("同步人员不能为空。");
        }
        if(billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_ORG) == null){
            throw new KDBizException("组织不能为空。");
        }
        if(billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_POSITIONHR) == null){
            throw new KDBizException("岗位人员不能为空。");
        }
        if(billInfo.getDynamicObject(PersonReimSyncTaskConstant.KEY_NCKD_JOBLEVELHR) == null){
            throw new KDBizException("职级不能为空。");
        }
    }







    protected void addRecord(DynamicObject billInfo , String successMsg , Boolean isSuccess){
        DynamicObjectCollection recordEntryCol = billInfo.getDynamicObjectCollection(PersonReimSyncTaskConstant.NCKD_RECORDENTRY.ENTITYID);
        DynamicObject record = recordEntryCol.addNew();
        record.set(PersonReimSyncTaskConstant.NCKD_RECORDENTRY.KEY_NCKD_SYNC_DATE,new Date());
        record.set(PersonReimSyncTaskConstant.NCKD_RECORDENTRY.KEY_NCKD_TRACEID, RequestContext.get().getTraceId());
        record.set(PersonReimSyncTaskConstant.NCKD_RECORDENTRY.KEY_NCKD_SYNC_ISSUCCESS,isSuccess?1:0);
        record.set(PersonReimSyncTaskConstant.NCKD_RECORDENTRY.KEY_NCKD_SYNC_MSG, StringUtils.substring(successMsg,0,500));

        billInfo.set(PersonReimSyncTaskConstant.KEY_NCKD_SYNCSTATUS,isSuccess?"40":"30");

        if(!isSuccess){
            OperationResult operationResult = this.getOperationResult();
            operationResult.setSuccess(false);
            operationResult.getSuccessPkIds().removeIf(r -> billInfo.getPkValue().equals(r));
            OperateErrorInfo operateErrorInfo = new OperateErrorInfo();
            operateErrorInfo.setMessage(successMsg);
            operateErrorInfo.setLevel(ErrorLevel.Error);
            operationResult.addErrorInfo(operateErrorInfo);
        }


    }


}
