package nckd.jxccl.hr.psms.plugin.operate.initial;

import com.google.common.collect.Lists;
import kd.bos.common.enums.EnableEnum;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.constant.StatusEnum;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.enums.AppraisalResultEnum;
import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.base.pm.helper.PerformanceManagerHelper;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;
import nckd.jxccl.hr.psms.common.bo.PositionAppointmentBO;
import nckd.jxccl.hr.psms.helper.PositionFileHelper;
import org.jetbrains.annotations.NotNull;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 人员初定操作插件基类
 * @author W.Y.C
 * @date 2025/9/15
 * @version 1.0
 */
public abstract class BaseInitialOperationPlugIn extends AbstractOperationServicePlugIn {
    
    protected final static Log logger = LogFactory.getLog(BaseInitialOperationPlugIn.class);

    public List<BaseInitialData> baseInitialData = Lists.newArrayList();

    /**
     * 基本信息数据对象
     */
    protected static class BaseInitialData {
        /** 开始时间 */
        Date beginDate;
        /** 备注 */
        String causeRemark;
        /** 总积分 */
        BigDecimal allSumScore;
        /** 聘任年限 */
        Integer employmentYears;
        /** 职称名称 */
        String rankName;
        /** 技能名称 */
        String jobStatusName;
        /** 员工 */
        DynamicObject person;
        /** 岗位 */
        DynamicObject positionHr;
        /** 所属公司 */
        DynamicObject company;
        /** 部门 */
        DynamicObject dep;
        /** 职位序列 */
        DynamicObject jobSeq;
        /** 职位序列（转换后） */
        DynamicObject convertJobSeq;
        /** 职位序列-编码 */
        String jobSeqNumber;
        /** 职位序列-名称 */
        String jobSeqName;
        /** 职位序列枚举 */
        JobSeqEnum jobSeqEnum;
        /** 职称等级 */
        DynamicObject proTitleLevel;
        /** 技能等级 */
        DynamicObject ocpQualLevel;
        /** 学历 */
        DynamicObject diploma;
        /** 任职经历 */
        DynamicObject empPosOrgRel;
        /** 本次入集团时间 */
        Date joinComDate;
        /** 上年度绩效考核结果*/
        DynamicObject lastYearAppraisalResult;
        /** 降级数 */
        int downgradeNum;
        /** 上年度绩效考核结果枚举 */
        AppraisalResultEnum lastYearAppraisalResultEnum;
        /** 备注 */
        boolean isExcellent;
    }

    /**
     * 积分数据
     */
    protected static class ScoreData {
        BigDecimal educationScore;
        BigDecimal proTitleScore;
        BigDecimal perOcpQualScore;
        DynamicObject dbProTitleLevel;
        DynamicObject dbOcpQualLevel;
    }

    /**
     * 提取基本信息（支持批量）
     * @param initialData 页面数据
     * @return: java.util.List<nckd.jxccl.hr.psms.plugin.operate.initial.BaseInitialOperationPlugIn.BaseInitialData>
     * @author W.Y.C
     * @date: 2025/10/12 14:20
     */
    protected List<BaseInitialData> extractBasicInfo(DynamicObject initialData) {
        List<BaseInitialData> dataList = new ArrayList<>();
        if(initialData.containsProperty(FormConstant.NCKD_ENTRYENTITY)){
            DynamicObjectCollection dynamicObjectCollection = initialData.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
            for (DynamicObject dynamicObject : dynamicObjectCollection) {
                //批量初定
                BaseInitialData data = getBaseInitialData(dynamicObject);
                dataList.add(data);
                baseInitialData.add(data);
            }
        }else{
            BaseInitialData data = getBaseInitialData(initialData);
            dataList.add(data);
            baseInitialData.add(data);
        }
        return dataList;
    }

    @NotNull
    private BaseInitialData getBaseInitialData(DynamicObject initialData) {
        BaseInitialData data = new BaseInitialData();

        data.beginDate = initialData.getDate(PositionStructureConstant.NCKD_BEGINDATE);
        data.causeRemark = initialData.getString(PositionStructureConstant.KEY_NCKD_CAUSEREMARK);
        data.person = initialData.getDynamicObject(PositionStructureConstant.NCKD_PERSON);

        PositionAppointmentBO positionAppointment = PositionFileHelper.positionAppointmentQuery(data.person.getLong(FormConstant.ID_KEY), data.beginDate);
        // 学历
        DynamicObject perEduExp = positionAppointment.getPerEduExp();
        if (perEduExp != null) {
            // 学历
            long diplomaId = perEduExp.getLong(String.join(".", FormConstant.EDUCATION_KEY, FormConstant.ID_KEY));
            if(diplomaId > 0) {
                DynamicObject diploma = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_DIPLOMA);
                diploma.set(FormConstant.ID_KEY, diplomaId);
                data.diploma = diploma;
            }
        }
        // 职称信息
        DynamicObject perProTitle = positionAppointment.getPerProTitle();
        if (perProTitle != null) {
            data.rankName = perProTitle.getString(String.join(".", FormConstant.PROFESSIONAL_KEY, FormConstant.NAME_KEY));
            // 职称等级
            long perProTitleId = perProTitle.getLong(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.ID_KEY));
            if(perProTitleId > 0) {
                DynamicObject proTitleLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_PROTITLELEVEL);
                proTitleLevel.set(FormConstant.ID_KEY, perProTitleId);
                data.proTitleLevel = proTitleLevel;
            }
        }

        // 技能信息
        DynamicObject perOcpQual = positionAppointment.getPerOcpQual();
        if (perOcpQual != null) {
            data.jobStatusName = perOcpQual.getString(String.join(".", FormConstant.QUALIFICATION_KEY, FormConstant.NAME_KEY));
            // 技能等级
            long quaLevelId = perOcpQual.getLong(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.ID_KEY));
            if(quaLevelId > 0) {
                DynamicObject ocpQualLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_OCPQUALLEVEL);
                ocpQualLevel.set(FormConstant.ID_KEY, quaLevelId);
                data.ocpQualLevel = ocpQualLevel;
            }

        }
        // 任职信息
        DynamicObject empPosOrgRel = positionAppointment.getEmpPosOrgRel();
        if (empPosOrgRel != null) {
            data.empPosOrgRel = empPosOrgRel;
            //岗位
            long positionId = empPosOrgRel.getLong(String.join(".", FormConstant.POSITION_KEY, FormConstant.ID_KEY));
            if(positionId > 0) {
                DynamicObject position = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBPM_POSITIONHR);
                position.set(FormConstant.ID_KEY, positionId);
                position.set(FormConstant.NAME_KEY, empPosOrgRel.getString(String.join(".", FormConstant.POSITION_KEY, FormConstant.NAME_KEY)));
                data.positionHr = position;
            }

            long companyId = empPosOrgRel.getLong(String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY));
            if(companyId > 0) {
                DynamicObject company = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORGHR_ENTITYID);
                company.set(FormConstant.ID_KEY, companyId);
                data.company = company;
            }
            long adminOrgId = empPosOrgRel.getLong(String.join(".", FormConstant.ADMINORG, FormConstant.ID_KEY));
            if(adminOrgId > 0) {
                DynamicObject dep = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORGHR_ENTITYID);
                dep.set(FormConstant.ID_KEY, adminOrgId);
                data.dep = dep;
            }

            // 职位序列
            Long jobSeqId = empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY));
            if(jobSeqId > 0) {
                String jobSeqNumber = empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NUMBER_KEY));
                String jobSeqName = empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NAME_KEY));
                DynamicObject jobSeq = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBJM_JOBSEQHR);
                jobSeq.set(FormConstant.ID_KEY, jobSeqId);
                jobSeq.set(FormConstant.NUMBER_KEY, jobSeqNumber);
                jobSeq.set(FormConstant.NAME_KEY, jobSeqName);
                data.jobSeq = jobSeq;
                data.jobSeqNumber = jobSeqNumber;
                data.jobSeqName = jobSeqName;
                data.jobSeqEnum = JobSeqEnum.getByCode(data.jobSeqNumber);
            }



            //本次加入集团时间
            data.joinComDate = empPosOrgRel.getDate(String.join(".", FormConstant.HRPI_PERSERLEN, FormConstant.JOINCOMDATE_KEY));
        }
        // TODO 【待修改】优秀生
        // data.isExcellent = initialData.getBoolean(PositionStructureConstant.NCKD_EXCELLENT);


        // 特定字段由子类处理
        extractSpecificFields(data, initialData);
        return data;
    }

    /**
     * 提取特定字段（由子类实现）
     */
    protected abstract void extractSpecificFields(BaseInitialData data, DynamicObject initialData);

    /**
     * 获取上年度绩效结果
     */
    protected void getPreviousYearPerformance(BaseInitialData data, String logPrefix) {
        LocalDateTime lastYearDateTime = DateUtil.minusYears(DateUtil.toLocalDateTime(data.beginDate), 1);
        data.lastYearAppraisalResult = PerformanceManagerHelper.getPerformanceResult(
                data.person.getLong(FormConstant.ID_KEY), lastYearDateTime);
        
        AppraisalResultEnum lastYearAppraisalResultEnum = AppraisalResultEnum.NONE;
        if(data.lastYearAppraisalResult != null) {
            String lastAppraisalResultNumber = data.lastYearAppraisalResult.getString(FormConstant.NUMBER_KEY);
            lastYearAppraisalResultEnum = AppraisalResultEnum.getByCode(lastAppraisalResultNumber);
        }
        data.lastYearAppraisalResultEnum = lastYearAppraisalResultEnum;
        
        // 降级数
        data.downgradeNum = 0;
        if (lastYearAppraisalResultEnum == AppraisalResultEnum.BASICALLY_QUALIFIED) {
            // "基本合格"降1级
            data.downgradeNum = 1;
        } else if (lastYearAppraisalResultEnum == AppraisalResultEnum.UN_QUALIFIED) {
            // "不合格"降2级
            data.downgradeNum = 2;
        }

        logger.info("{}-上年度考核结果【{}】-降级数【{}】",
                logPrefix, lastYearAppraisalResultEnum.getName(), data.downgradeNum);
    }

    /**
     * 获取积分数据
     */
    protected ScoreData getScoreData(BaseInitialData data, String logPrefix) {
        ScoreData scoreData = new ScoreData();

        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberNameWithExtras(FormConstant.NCKD_SCORE);

        // 学历积分
        scoreData.educationScore = BigDecimal.ZERO;
        if (data.diploma != null) {
            DynamicObject education = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_DIPLOMA,
                    queryFieldBuilder.buildSelect(),
                    new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.diploma.getLong(FormConstant.ID_KEY))});
            if (education != null) {
                scoreData.educationScore = education.getBigDecimal(FormConstant.NCKD_SCORE);
                logger.info("{}-学历【{}】-积分【{}】", logPrefix, education.getString(FormConstant.NAME_KEY), scoreData.educationScore);
            } else {
                logger.warn("{}-未找到学历信息", logPrefix);
            }
        } else {
            logger.warn("{}-无学历信息", logPrefix);
        }

        // 职称积分
        scoreData.proTitleScore = BigDecimal.ZERO;
        // 技能积分
        scoreData.perOcpQualScore = BigDecimal.ZERO;
        scoreData.dbProTitleLevel = null;
        scoreData.dbOcpQualLevel = null;



        if (data.jobSeqEnum != JobSeqEnum.SKILL && data.proTitleLevel != null) {
            // 非技能序列获取职称积分
            scoreData.dbProTitleLevel = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_PROTITLELEVEL,
                    queryFieldBuilder.buildSelect(),
                    new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.proTitleLevel.getLong(FormConstant.ID_KEY))});
            if (scoreData.dbProTitleLevel != null) {
                scoreData.proTitleScore = scoreData.dbProTitleLevel.getBigDecimal(FormConstant.NCKD_SCORE);
                data.jobStatusName = null;
            }
        } else if (data.jobSeqEnum == JobSeqEnum.SKILL && data.ocpQualLevel != null) {
            // 技能序列获取技能积分
            scoreData.dbOcpQualLevel = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_OCPQUALLEVEL,
                    queryFieldBuilder.buildSelect(),
                    new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.ocpQualLevel.getLong(FormConstant.ID_KEY))});
            if (scoreData.dbOcpQualLevel != null) {
                scoreData.perOcpQualScore = scoreData.dbOcpQualLevel.getBigDecimal(FormConstant.NCKD_SCORE);
                data.rankName = null;
            }
        }

        logger.info("{}-初定职位序列【{}】-职称积分【{}】-技能积分【{}】",
                logPrefix, data.jobSeqName, scoreData.proTitleScore, scoreData.perOcpQualScore);

        return scoreData;
    }

    /**
     * 计算累计积分池
     */
    protected BigDecimal calculateSumScore(BigDecimal allSumScore, ScoreData scoreData, String logPrefix) {
        // 累计积分池 = 累计总积分【前端传入】 - (职称分/技能分) - 学历分
        BigDecimal sumScore = allSumScore
                .subtract(scoreData.proTitleScore != null ? scoreData.proTitleScore : BigDecimal.ZERO)
                .subtract(scoreData.perOcpQualScore != null ? scoreData.perOcpQualScore : BigDecimal.ZERO)
                .subtract(scoreData.educationScore != null ? scoreData.educationScore : BigDecimal.ZERO);

        // 如果为负数则赋值为0
        if (sumScore.compareTo(BigDecimal.ZERO) < 0) {
            sumScore = BigDecimal.ZERO;
        }

        logger.info("{}-累计积分计算结果 = {}", logPrefix, sumScore);
        return sumScore;
    }

    /**
     * 创建并保存职位档案
     */
    protected void createAndSavePersonPosFile(BaseInitialData data, ScoreData scoreData, 
                                             BigDecimal allSumScore, BigDecimal sumScore, 
                                             DynamicObject jobLeve, String logPrefix, String typeState) {
        // 优秀生得2分
        BigDecimal excellentScore = data.isExcellent ? new BigDecimal(2) : BigDecimal.ZERO;

        // 构建职位档案并存入数据库
        DynamicObject personPosFile = BusinessDataServiceHelper.newDynamicObject(
                PositionStructureConstant.PERSONPOSFILE_ENTITYID);

        personPosFile.set(PositionStructureConstant.NCKD_PERSON, data.person);
        personPosFile.set(PositionStructureConstant.NCKD_FIRSTRANK, EnableEnum.YES.getCode());
        personPosFile.set(PositionStructureConstant.NCKD_BEGINDATE, data.beginDate);
        personPosFile.set(PositionStructureConstant.NCKD_APPRAISALRESULT, data.lastYearAppraisalResult);
        personPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, data.convertJobSeq);
        personPosFile.set(PositionStructureConstant.NCKD_POSITIONHR, data.positionHr);
        /*personPosFile.set(PositionStructureConstant.USEORG_KEY, data.company);
        personPosFile.set(PositionStructureConstant.CREATEORG_KEY, data.dep);
        personPosFile.set(PositionStructureConstant.ORG_KEY, data.dep);*/

       /* personPosFile.set(PositionStructureConstant.ORG_KEY, UserServiceHelper.getUserMainOrgId(UserServiceHelper.getCurrentUserId()));
        personPosFile.set(PositionStructureConstant.SRCCREATEORG_KEY, data.company);
        personPosFile.set(PositionStructureConstant.CREATEORG_KEY, data.company);
        personPosFile.set(PositionStructureConstant.USEORG_KEY, data.dep);*/

        personPosFile.set(PositionStructureConstant.NCKD_DEP, data.dep);

        personPosFile.set(PositionStructureConstant.NCKD_ALLSUMSCORE, allSumScore);
        personPosFile.set(PositionStructureConstant.NCKD_SUMSCORE, sumScore);
        personPosFile.set(PositionStructureConstant.NCKD_RANKNAME, data.rankName);
        personPosFile.set(PositionStructureConstant.NCKD_PROTITLELEVEL, scoreData.dbProTitleLevel);
        personPosFile.set(PositionStructureConstant.NCKD_RANKSCORE, scoreData.proTitleScore);
        personPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSNAME, data.jobStatusName);
        personPosFile.set(PositionStructureConstant.NCKD_OCPQUALLEVEL, scoreData.dbOcpQualLevel);
        personPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSSCORE, scoreData.perOcpQualScore);
        personPosFile.set(PositionStructureConstant.NCKD_JOBLEVELHR, jobLeve);
        personPosFile.set(PositionStructureConstant.NCKD_DIPLOMA, data.diploma);
        personPosFile.set(PositionStructureConstant.NCKD_TYPESTATE, typeState);
        personPosFile.set(PositionStructureConstant.NCKD_DIPLOMASCORE, scoreData.educationScore);
        personPosFile.set(PositionStructureConstant.NCKD_EXECUTEYEAR, DateUtil.getYear(data.beginDate));
        personPosFile.set(PositionStructureConstant.NCKD_ORGINSSCORE, excellentScore);
        personPosFile.set(PositionStructureConstant.NCKD_EMPLOYMENTYEARS, data.employmentYears);
        personPosFile.set(PositionStructureConstant.KEY_NCKD_CAUSEREMARK, data.causeRemark);
        personPosFile.set(PositionStructureConstant.NCKD_DISABLE, EnableEnum.NO.getCode());
        personPosFile.set(PositionStructureConstant.NCKD_ISCURRENTNEWEST, EnableEnum.YES.getCode());
        personPosFile.set(PositionStructureConstant.STATUS, StatusEnum.C.toString());
        personPosFile.set(PositionStructureConstant.ENABLE, EnableEnum.YES.getCode());
        personPosFile.set(PositionStructureConstant.CREATOR_KEY, RequestContext.get().getCurrUserId());


        SaveServiceHelper.save(new DynamicObject[]{personPosFile});
    }

    /**
     * 设置操作结果中的职级信息
     */
    protected void setJobLevelResult(DynamicObject person, DynamicObject jobLeve) {
        String jobLeveStr = StrFormatter.format("{}：{}（{}级）", 
                person.getString(FormConstant.NAME_KEY),
                jobLeve.getString(FormConstant.NAME_KEY),
                jobLeve.getString(FormConstant.JOBLEVELSEQ));
        
        Map<String, String> customData = this.getOperationResult().getCustomData();
        if(customData == null) {
            this.getOperationResult().setCustomData(new HashMap<>());
            customData = this.getOperationResult().getCustomData();
        }
        
        String oldJobLeveStr = customData.get(PositionStructureConstant.NCKD_JOBLEVELHR);
        if (oldJobLeveStr == null || oldJobLeveStr.isEmpty()) {
            customData.put(PositionStructureConstant.NCKD_JOBLEVELHR, jobLeveStr);
        } else {
            customData.put(PositionStructureConstant.NCKD_JOBLEVELHR, oldJobLeveStr + StrFormatter.LINE_SEPARATOR + jobLeveStr);
        }
    }
}
