package nckd.jxccl.hr.psms.plugin.form.adjust;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.FormShowParameter;
import kd.bos.form.MessageBoxOptions;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.exception.ValidationException;
import nckd.jxccl.base.common.utils.ConvertUtil;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.hr.psms.business.JobLevelCalculatorService;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;
import nckd.jxccl.hr.psms.common.bo.PositionAppointmentBO;
import nckd.jxccl.hr.psms.helper.PositionFileHelper;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.EventObject;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;

/**
* 新建动态调整（弹窗）-插件
* @author W.Y.C
* @date 2025/9/17 15:56
* @version 1.0
*/
public class NewDynamicAdjustmentDiaLogFormPlugin extends AbstractFormPlugin {

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
    }

    @Override
    public void afterCreateNewData(EventObject e) {
        this.getView().setEnable(false, FormConstant.BTN_OK_OP);
        // 获取当前页面的FormShowParameter对象
        FormShowParameter formShowParameter = this.getView().getFormShowParameter();
        // 获取列表选择的人员
        Object personId = formShowParameter.getCustomParam(FormConstant.NCKD_PERSON);
        if(personId != null) {
            //赋值表单人员
            this.getModel().setValue(FormConstant.NCKD_PERSON, personId);
            this.getView().updateView();
        }
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String fieldKey = e.getProperty().getName();
        ChangeData[] changeSet = e.getChangeSet();

        //【员工】或【调整日期】发生变更则重新获取员工任职信息
        if (PositionStructureConstant.NCKD_ADJUSTDATE.equalsIgnoreCase(fieldKey) || FormConstant.NCKD_PERSON.equalsIgnoreCase(fieldKey)) {
            if (changeSet != null && changeSet.length > 0) {
                ChangeData changeData = changeSet[0];
                Object oldValue = changeData.getOldValue();
                Object newValue = changeData.getNewValue();
                if (!Objects.equals(oldValue, newValue)) {
                    //【员工】或【调整日期】发生变更
                    Date adjustDate = ConvertUtil.toDate(this.getModel().getValue(PositionStructureConstant.NCKD_ADJUSTDATE));
                    DynamicObject person = ConvertUtil.toDynamicObject(this.getModel().getValue(PositionStructureConstant.NCKD_PERSON));
                    if(adjustDate != null && person.getDataEntityType() != null){
                        DynamicObject latsPersonPosFileByPerson = PositionFileHelper.getLatsPersonPosFileByPerson(person.getLong(FormConstant.ID_KEY));
                        if(latsPersonPosFileByPerson == null){
                            this.getView().showErrorNotification(StrFormatter.format("当前无法为【{}】进行动态调整，因为他/她尚未建立职位档案。请前往“职位及积分初定” -> 进行初定！", person.getString(FormConstant.NAME_KEY)));
                            clearFormInfo();
                        }else{
                            try{
                                LocalDateTime endDay = DateUtil.endOfDay(DateUtil.toLocalDateTime(adjustDate));
                                PositionAppointmentBO positionAppointment = PositionFileHelper.positionAppointmentQuery(person.getLong(FormConstant.ID_KEY), DateUtil.toDate(endDay));
                                JobLevelCalculatorService.JobLevelResult jobLevelResult = getJobLevel(person, adjustDate,positionAppointment);

                                updateFormInfo(person, adjustDate, latsPersonPosFileByPerson,jobLevelResult,positionAppointment);
                                this.getView().showSuccessNotification("信息加载完成");
                            }catch (ValidationException ex){
                               clearFormInfo();
                               this.getView().showErrorNotification(ex.getMessage());
                            }
                        }
                    }
                }
            }
        }
    }



    public static JobLevelCalculatorService.JobLevelResult getJobLevel(DynamicObject person,Date date,PositionAppointmentBO positionAppointment){
        //移植代码：com.kingdee.shr.customer.web.handler.ContributeScore.PersonpositionfileFluctuationListHandler#selaboutJobGradeAction
        long personId = person.getLong(FormConstant.ID_KEY);
        String personName = person.getString(FormConstant.NAME_KEY);
        // 1、获取员工职位档案信息
        // 对应SHR：personpositionfileInfo & appraisalCollection
        DynamicObject currentPersonPosFile = PositionFileHelper.getLatsPersonPosFileByPerson(personId);
        if (currentPersonPosFile == null || currentPersonPosFile.getDataEntityType() == null) {
            throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整，因为他/她尚未建立职位档案。请前往“职位及积分初定” -> 进行初定！", personName));
        }
        // 2、验证调整日期是否在上一次调整日期之后
        Date lastDate = currentPersonPosFile.getDate(PositionStructureConstant.NCKD_BEGINDATE);
        if (date.compareTo(lastDate) <=0) {
            throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整，因为最近调整时间为【{}】，不能早于最近一次职位调整时间。", personName,DateUtil.format(lastDate,DateUtil.NORM_DATE_PATTERN)));
        }

        // BigDecimal sumScore = currentPersonPosFile.getBigDecimal(PositionStructureConstant.NCKD_SUMSCORE);

        LocalDateTime endDay = DateUtil.endOfDay(DateUtil.toLocalDateTime(date));
        // 3、根据时间获取员工信息（任职经历、聘任、学历）
        //对应SHR：resultMap
        // DynamicObject positionAppointment = PositionStructureHelper.positionAppointmentQuery(personId, DateUtil.toDate(endDay));
        if(positionAppointment == null || positionAppointment.getEmpPosOrgRel() == null){
            throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整，因为根据时间【{}】未获取到人员任职和聘任信息！", personName,DateUtil.format(date,DateUtil.NORM_DATE_PATTERN)));
        }

        // 4、获取职位序列（如是管理序列则转职能序列）
        /*long jobSeqId = positionAppointment.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY));
        if(jobSeqId == 0){
            throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整，因为人员主任职没有职位序列", personName));
        }
        DynamicObject jobSeq = BusinessDataServiceHelper.loadSingle(jobSeqId, FormConstant.HBJM_JOBSEQHR);
        DynamicObject newJobSeq = JobLevelCalculatorService.handleJobSeq(jobSeq);
        //对应SHR：hrjobfamilynumber
        String jobSeqNumber = newJobSeq.getString(FormConstant.NUMBER_KEY);*/

        // 5、处理职称等级分和技能等级分
        // JobLevelCalculatorService.JobScoreInfo jobScoreInfo = JobLevelCalculatorService.handleJobScores(newJobSeq, currentPersonPosFile, positionAppointment);

        // 6、处理学历分数计算
        // BigDecimal diplomaScore = JobLevelCalculatorService.handleDiplomaScore(currentPersonPosFile, positionAppointment);

        /*sumScore = sumScore.add(diplomaScore)
                .add(jobScoreInfo.perProTitleScore)
                .add(jobScoreInfo.quaLevelScore);*/

        // 7、获取职级相关信息
        JobLevelCalculatorService.JobLevelResult jobLevelResult = JobLevelCalculatorService.calculateJobLevel(person, date, positionAppointment);


        // 8、检查指定年份是否存在未生效的年度调整记录
        int currentYear = DateUtil.getYear(new Date());
        int year = DateUtil.getYear(date);
        DynamicObject[] personPosFileByPersonAndState = PositionFileHelper.getPersonPosFileByPersonAndState(personId,
                new String[]{"3"},
                null,
                new QFilter(PositionStructureConstant.NCKD_ADJUSTTYPE, QCP.not_in, new String[]{"1", "2"}).and(new QFilter(PositionStructureConstant.NCKD_EXECUTEYEAR, QCP.in, new Integer[]{currentYear, year})));
        if(personPosFileByPersonAndState != null && personPosFileByPersonAndState.length > 0){
            StringJoiner yearJoin = new StringJoiner("，");
            for (DynamicObject dynamicObject : personPosFileByPersonAndState) {
                int executeYear = dynamicObject.getInt(PositionStructureConstant.NCKD_EXECUTEYEAR);
                yearJoin.add(executeYear+"");
            }
            throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整，因为人员存在【{}】年未生效的年度调整记录，请先前往【职位及积分年度调整】中进行处理！", personName,yearJoin.toString()));
        }

        // 9、处理考核结果
        // DynamicObject appraisalResult = currentPersonPosFile.getDynamicObject(PositionStructureConstant.NCKD_APPRAISALRESULT);
        // String appraisalResultNumber = appraisalResult != null ? appraisalResult.getString(FormConstant.NUMBER_KEY) : null;
        // String newAppraisalResultNumber = JobLevelCalculatorService.validateAppraisalResultConsistency(date, personId, personName, appraisalResultNumber);

        // 10、处理R排名百分比
        // JobLevelCalculatorService.RankingResult rankingInfo = JobLevelCalculatorService.getRankingInfo(personId, personName, date);

        return jobLevelResult;
    }

    @Override
    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
        String operateKey = afterDoOperationEventArgs.getOperateKey();
        boolean success = afterDoOperationEventArgs.getOperationResult() != null && afterDoOperationEventArgs.getOperationResult().isSuccess();
        if(success && PositionStructureConstant.OP_CONFIRMADJUST.equalsIgnoreCase(operateKey)){
            Map<String, String> customData = afterDoOperationEventArgs.getOperationResult().getCustomData();
            String jobLeveStr = customData.get(PositionStructureConstant.NCKD_JOBLEVELHR);
            this.getView().returnDataToParent("true");
            this.getView().showConfirm("提示","新建调整成功，职位档案已生成。",jobLeveStr, MessageBoxOptions.OK,null,null,null,null);
        }
    }

    private void updateFormInfo(DynamicObject person, Date adjustDate, DynamicObject personPosFile, JobLevelCalculatorService.JobLevelResult jobLevelResult, PositionAppointmentBO positionAppointment) {
        LocalDateTime endDay = DateUtil.endOfDay(DateUtil.toLocalDateTime(adjustDate));
        this.getModel().setValue(PositionStructureConstant.NCKD_POSITIONHR,
                positionAppointment.getEmpPosOrgRel().getLong(String.join(".", FormConstant.POSITION_KEY, FormConstant.ID_KEY)));
        if (jobLevelResult != null) {
            if (jobLevelResult.rankingResultInfo != null) {
                this.getModel().setValue(PositionStructureConstant.NCKD_ALLOWANCERANKMARK,
                        jobLevelResult.rankingResultInfo.allowanceRankMark);
                this.getModel().setValue(PositionStructureConstant.NCKD_ALLOWANCERANKPERCENT,
                        jobLevelResult.rankingResultInfo.allowanceRankPercent);
            }
            if (jobLevelResult.jobScoreInfo != null) {
                this.getModel().setValue(PositionStructureConstant.NCKD_RANKNAME,
                        jobLevelResult.jobScoreInfo.rankName);
                this.getModel().setValue(PositionStructureConstant.NCKD_PERPROTITLENAME,
                        jobLevelResult.jobScoreInfo.perProTitleName);
                this.getModel().setValue(PositionStructureConstant.NCKD_QUALEVELNAME,
                        jobLevelResult.jobScoreInfo.quaLevelName);
                this.getModel().setValue(PositionStructureConstant.NCKD_JOBSTATUSNAME,
                        jobLevelResult.jobScoreInfo.jobStatusName);
                this.getModel().setValue(PositionStructureConstant.NCKD_DIPLOMA, jobLevelResult.jobScoreInfo.diplomaId);
            }

            this.getModel().setValue(PositionStructureConstant.NCKD_JOBLEVEL, jobLevelResult.jobLevel);
        }
        this.getModel().setValue(PositionStructureConstant.PERSONPOSFILE_ENTITYID, personPosFile);

        this.getView().setEnable(true, FormConstant.BTN_OK_OP);

    }

    private void clearFormInfo() {
        this.getModel().setValue(PositionStructureConstant.PERSONPOSFILE_ENTITYID, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_POSITIONHR, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_ALLOWANCERANKMARK, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_ALLOWANCERANKPERCENT, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_RANKNAME, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_PERPROTITLENAME, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_QUALEVELNAME, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_JOBSTATUSNAME, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_JOBLEVEL, null);
        this.getModel().setValue(PositionStructureConstant.NCKD_DIPLOMA, null);
        this.getView().setEnable(false, FormConstant.BTN_OK_OP);
    }
}