package nckd.jxccl.hr.hstu.plugin.operate;

import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.db.tx.TX;
import kd.bos.db.tx.TXHandle;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.constant.StatusEnum;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.exception.KDBizException;
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.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.enums.PerfPlanRoleEnum;
import nckd.jxccl.base.common.exception.ValidationException;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.entity.helper.EntityHelper;
import nckd.jxccl.base.org.helper.PersonHelper;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.hr.hstu.common.HonorStudentConstant;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
* 【优秀生】-综合测评问卷-生成问卷操作插件
* @author W.Y.C
* @date 2025/8/15 15:28
* @version 1.0
*/
public class EvalQuestGenerateQuestOperationPlugin extends AbstractOperationServicePlugIn implements Plugin {

    private static final Log logger = LogFactory.getLog(EvalQuestGenerateQuestOperationPlugin.class);

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        // 获取选中行数据（DynamicObject数组）
        DynamicObject[] selectedRows = e.getDataEntities();
        if (selectedRows != null && selectedRows.length > 0) {
            List<Long> selectedRowIds = new ArrayList<>(selectedRows.length);
            for (DynamicObject row : selectedRows) {
                // 获取单据ID（主键）
                Long id = (Long) row.getPkValue();
                selectedRowIds.add(id);
            }
            generateQuest(selectedRowIds);
        }
    }

    /**
     * 生成问卷
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/22 11:25
     */
   private void generateQuest(List<Long> selectedRowIds) {
        logger.info("【优秀生考评】-生成问卷-开始，选择的问卷ID：{}",selectedRowIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
        StringJoiner fields = new StringJoiner(",");
        fields.add(FormConstant.ID_KEY);
        //评测状态
        fields.add(HonorStudentConstant.NCKD_PERIODSTATE);
        //问卷模板
        fields.add(HonorStudentConstant.NCKD_EVALQUESTTPL+"."+FormConstant.ID_KEY);
        //被评价人
        fields.add(HonorStudentConstant.NCKD_EVALPERSON+"."+FormConstant.PERSON+"."+FormConstant.ID_KEY);
        fields.add(HonorStudentConstant.NCKD_EVALPERSON+"."+FormConstant.PERSON+"."+FormConstant.NAME_KEY);
        //分录
        fields.add(HonorStudentConstant.NCKD_EVALQUESTENTRY+"."+FormConstant.ID_KEY);
        fields.add(HonorStudentConstant.NCKD_EVALQUESTENTRY+"."+HonorStudentConstant.NCKD_PERSON+"."+FormConstant.ID_KEY);
        fields.add(HonorStudentConstant.NCKD_EVALQUESTENTRY+"."+HonorStudentConstant.NCKD_PERSON+"."+HonorStudentConstant.PERSON+"."+FormConstant.ID_KEY);
        fields.add(HonorStudentConstant.NCKD_EVALQUESTENTRY+"."+HonorStudentConstant.NCKD_PERFPLANROLE);
        DynamicObject[] evalQuestArray = BusinessDataServiceHelper.load(HonorStudentConstant.NCKD_EVALQUEST_ENTITYID,
                fields.toString(),
                new QFilter[]{QFilterCommonHelper.getIdInFilter(selectedRowIds)});

        // 1.校验状态
        StringJoiner errorJoin = new StringJoiner("\n");
        Arrays.stream(evalQuestArray).forEach(evalQuest -> {
            String periodState = evalQuest.getString(HonorStudentConstant.NCKD_PERIODSTATE);
            if(!periodState.equals("0")){
                DynamicObject person = evalQuest.getDynamicObject(HonorStudentConstant.NCKD_EVALPERSON).getDynamicObject(FormConstant.PERSON);
                errorJoin.add(StrFormatter.format("评价对象【{}】的测评状态非【未开始】，只有【未开始】状态的才能生成问卷",person.getString(FormConstant.NAME_KEY)));
            }
        });
        if(errorJoin.length() > 0){
            logger.warn("【优秀生考评】-生成问卷-业务校验异常：{}",errorJoin.toString());
            throw new ValidationException(errorJoin.toString());
        }

        // 2.校验打分人是否有领导和上级
        validateEvaluatorRoles(evalQuestArray);

        // 3.构建并保存答卷
        buildAndSaveEvalResult(evalQuestArray);

        logger.info("【优秀生考评】-生成问卷-完成");
    }

    /**
     * 校验评分人是否有领导和上级评分人
     * @param load 选择的问卷
     * @return: java.lang.String
     * @author W.Y.C
     * @date: 2025/07/16 16:19
     */
    private static void validateEvaluatorRoles(DynamicObject[] load) throws ValidationException {
        StringJoiner errorMsg = new StringJoiner("\n");
        Arrays.stream(load).forEach(dynamicObject -> {
            DynamicObject person = dynamicObject.getDynamicObject(HonorStudentConstant.NCKD_EVALPERSON).getDynamicObject(FormConstant.PERSON);
            DynamicObjectCollection entryColl = dynamicObject.getDynamicObjectCollection(HonorStudentConstant.NCKD_EVALQUESTENTRY);

            long leadCount = entryColl.stream()
                    .filter(entry -> PerfPlanRoleEnum.LEAD.getCode().equals(entry.getString(HonorStudentConstant.NCKD_PERFPLANROLE)))
                    .count();

            long superiorCount = entryColl.stream()
                    .filter(entry -> PerfPlanRoleEnum.SUPERIOR.getCode().equals(entry.getString(HonorStudentConstant.NCKD_PERFPLANROLE)))
                    .count();

            if (leadCount < 1) {
                errorMsg.add(StrFormatter.format(
                        "评价对象【{}】缺少领导评分人",
                        person.getString(FormConstant.NAME_KEY)));
            }

            if (superiorCount < 1) {
                errorMsg.add(StrFormatter.format(
                        "评价对象【{}】缺少上级评分人",
                        person.getString(FormConstant.NAME_KEY)));
            }
        });
        if(errorMsg.length() > 0){
            logger.warn("【优秀生考评】-生成问卷-业务校验异常：{}",errorMsg.toString());
            throw new ValidationException(errorMsg.toString());
        }
    }

    /**
     * 构建并保存答卷
     * @param evalQuestArray 问卷列表
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/16 20:38
     */
    private void buildAndSaveEvalResult(DynamicObject[] evalQuestArray) throws KDBizException {
        Long currUserId =  RequestContext.get().getCurrUserId();
        Long currOrgId =  RequestContext.get().getOrgId();
        //当前登录用户
        DynamicObject currUser = UserServiceHelper.getUserInfoByID(currUserId, HonorStudentConstant.ID_KEY);

        // 获取苍穹平台组织实体元数据
        MainEntityType bosOrgEntityType = EntityMetadataCache.getDataEntityType(FormConstant.BOS_ORG);
        // 基于元数据创建 DynamicObject
        DynamicObject org = new DynamicObject(bosOrgEntityType);
        org.set(FormConstant.ID_KEY,currOrgId);


        //获取所有问卷模板
        Set<Long> evalQuestTplSet = new HashSet<>();
        Map<Long,List<DynamicObject>> evalQuestTplMap = new HashMap<>();
        Arrays.stream(evalQuestArray).forEach(evalQuest -> {
            long evalQuestTplId = evalQuest.getDynamicObject(HonorStudentConstant.NCKD_EVALQUESTTPL).getLong(FormConstant.ID_KEY);
            evalQuestTplSet.add(evalQuestTplId);
        });
        DynamicObjectCollection evalQuestTplColl = QueryServiceHelper.query(HonorStudentConstant.NCKD_EVALQUESTTPL_ENTITYID,"id,NCKD_EVALQUESTTPLENTRY.*",new QFilter[]{new QFilter(FormConstant.ID_KEY, QCP.in,evalQuestTplSet)});
        for (DynamicObject evalQuestTpl : evalQuestTplColl) {
            long id = evalQuestTpl.getLong(HonorStudentConstant.ID_KEY);
            evalQuestTplMap.computeIfAbsent(id, k -> new ArrayList<>()).add(evalQuestTpl);
        }

        //构建答卷
        MainEntityType depEmpEntityType = EntityMetadataCache.getDataEntityType(PersonHelper.DEP_EMP_ENTITY_ID);
        MainEntityType evalQuestTplEntryEntityType = EntityMetadataCache.getDataEntityType(HonorStudentConstant.NCKD_EVALQUESTTPLENTRYBAS_ENTITYID);
        List<DynamicObject> evalResultToSaveList = new ArrayList<>();
        Arrays.stream(evalQuestArray).forEach(evalQuest -> {
            //评价对象
            DynamicObject evalPerson = evalQuest.getDynamicObject(HonorStudentConstant.NCKD_EVALPERSON);
            //循环评分人
            DynamicObjectCollection entryColl = evalQuest.getDynamicObjectCollection(HonorStudentConstant.NCKD_EVALQUESTENTRY);
            entryColl.forEach(entry -> {
                //获取分录数据
                long entryId = entry.getLong(FormConstant.ID_KEY);
                DynamicObject personDynamicObject = QueryServiceHelper.queryOne(HonorStudentConstant.NCKD_EVALQUEST_ENTITYID,
                        HonorStudentConstant.NCKD_EVALQUESTENTRY+"."+HonorStudentConstant.NCKD_PERSON+"."+FormConstant.ID_KEY+" personId",
                        new QFilter[]{new QFilter(HonorStudentConstant.NCKD_EVALQUESTENTRY+"."+FormConstant.ID_KEY, QCP.equals, entryId)});
                //评分人
                long scorerId = personDynamicObject.getLong("personId");

                DynamicObject buildEvalResult = EntityHelper.newAvailableBasicEntity(HonorStudentConstant.NCKD_EVALRESULT_ENTITYID);
                buildEvalResult.set(FormConstant.STATUS, StatusEnum.B.toString());
                buildEvalResult(evalQuest,entry, buildEvalResult, evalPerson, depEmpEntityType, scorerId);

                //构建答卷分录
                DynamicObjectCollection entryEntity = buildEvalResult.getDynamicObjectCollection(HonorStudentConstant.NCKD_EVALRESULTENTRY);
                long evalQuestTplId = evalQuest.getDynamicObject(HonorStudentConstant.NCKD_EVALQUESTTPL).getLong(FormConstant.ID_KEY);
                List<DynamicObject> evalQuestTplList = evalQuestTplMap.get(evalQuestTplId);
                if (evalQuestTplList != null) {
                    evalQuestTplList.sort(Comparator.comparingInt(
                            obj -> obj.getInt("nckd_evalquesttplentry.seq")
                    ));
                    for (DynamicObject evalQuestTpl : evalQuestTplList) {
                        DynamicObject resultEntry = entryEntity.addNew();
                        long evalQuestTplEntryId = evalQuestTpl.getLong("nckd_evalquesttplentry.id");
                        DynamicObject evalQuestTplEntry = new DynamicObject(evalQuestTplEntryEntityType);
                        evalQuestTplEntry.set(FormConstant.ID_KEY, evalQuestTplEntryId);
                        resultEntry.set(HonorStudentConstant.NCKD_EVALQUESTTPLENTRY,evalQuestTplEntry);

                    }
                }
                evalResultToSaveList.add(buildEvalResult);
            });
        });
        OperateOption option = OperateOption.create();
        // 忽消息提示
        option.setVariableValue(OperateOptionConst.ISSHOWMESSAGE, Boolean.TRUE.toString());
        //开启事务确保事务一致性
        try (TXHandle t = TX.required(HonorStudentConstant.OP_GENERATE_QUEST)) {
            try {
                OperationResult operationResult = SaveServiceHelper.saveOperate(FormConstant.SAVE_OP,HonorStudentConstant.NCKD_EVALQUEST_ENTITYID, evalResultToSaveList.toArray(new DynamicObject[0]), option);
                if (!operationResult.isSuccess()) {
                    StringJoiner errorMsg = new StringJoiner("\n");
                    for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                        errorMsg.add(error.getMessage());
                    }
                    logger.warn("【优秀生考评】-生成问卷-业务异常：{}",errorMsg.toString());
                    throw new ValidationException(errorMsg.toString());
                }
                //修改问卷状态
                for (DynamicObject evalQuest : evalQuestArray) {
                    //问卷修改为就绪状态
                    evalQuest.set(HonorStudentConstant.NCKD_PERIODSTATE,"3");
                }
                SaveServiceHelper.update(evalQuestArray);
            } catch (Throwable e) {
                logger.error("【优秀生考评】-生成问卷-系统异常：{}",e);
                // 异常回滚
                t.markRollback();
                throw e;
            }
        }

    }

    private static void buildEvalResult(DynamicObject evalQuest,DynamicObject evalQuestEntry, DynamicObject mainObj, DynamicObject evalPerson, MainEntityType depEmpEntityType, long scorerId) {
        //评价对象
        mainObj.set(HonorStudentConstant.NCKD_PERSON, evalPerson);
        //评分人
        DynamicObject scorerPerson = new DynamicObject(depEmpEntityType);
        scorerPerson.set(FormConstant.ID_KEY, scorerId);
        mainObj.set(HonorStudentConstant.NCKD_SCORER, scorerPerson);
        //对应问卷
        mainObj.set(HonorStudentConstant.NCKD_EVALQUEST, evalQuest);
        mainObj.set(HonorStudentConstant.NCKD_EVALQUESTENTRY, evalQuestEntry);
        //评分状态
        mainObj.set(HonorStudentConstant.NCKD_PERFPLANSTATE, "0");
    }
}