package nckd.jimin.jyyy.hr.swc.hcdm.formplugin.web;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.ObjectUtils;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.AfterOperationArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
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 kd.bos.servicehelper.user.UserServiceHelper;
import kd.sdk.plugin.Plugin;
import kd.swc.hcdm.business.salaryadjfile.DecAdjInfoServiceHelper;
import kd.tdc.tjga.business.task.ScheduleExecutor;
import nckd.jimin.jyyy.hr.swc.hsas.formplugin.web.helper.AdjSalFileHelper;

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

import static nckd.jimin.jyyy.hr.swc.hsas.formplugin.web.helper.AdjSalFileHelper.matchStdTableForBill;

/**
 * 批量职等调整单生效插件
 * 调用调度计划
 * Tyx
 * 2025-06-08
 */
public class AdjustJobBillEffectOp extends AbstractOperationServicePlugIn implements Plugin {
    private static DecAdjInfoServiceHelper helper = new DecAdjInfoServiceHelper();
    private static final Log log = LogFactory.getLog(AdjustJobBillEffectOp.class);

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        super.endOperationTransaction(e);
    }

    /**
     * 职级/定调薪信息调整
     * 如果表头是否调级 = 否，则只调整薪酬信息
     * 如果表头是否调级 = 是，则职级职等及薪酬信息都要调整，且薪酬信息调整要按照本单调整后的职级为准；
     * @param e
     */
    @Override
    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
        super.afterExecuteOperationTransaction(e);
        String key = e.getOperationKey();
        boolean isAdjustJob = false;
        Map<String, DynamicObject> jobMap = new HashMap();
        DynamicObject[] bills = e.getDataEntities();
        for (DynamicObject bill : bills) {
            if(!key.equals("customsubmiteffect")) {
                bill = BusinessDataServiceHelper.loadSingle(bill.getPkValue(), bill.getDataEntityType().getName());
            }
            //是否调级
            String isAdjustJobStr = bill.getString("nckd_isadjustjob");
            //如果是否调级 = 是，处理下职级调整分录的数据Map，key = 工号， value = 分录Dyn
            if("1".equals(isAdjustJobStr)) {
                isAdjustJob = true;
                DynamicObjectCollection jobEntryCols = bill.getDynamicObjectCollection("changeentry");
                jobMap = (Map) jobEntryCols.stream().collect(Collectors.toMap((dyx) -> {
                    return dyx.getString("number");
                }, (dyx) -> {
                    return dyx;
                }, (key1, key2) -> {
                    return key2;
                }));
            }

            DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("nckd_entryentity");
            if(entryCols.size() > 0) {
                int index = 0;
                int successCount = 0;
                for(DynamicObject entry : entryCols) {
                    if(entry.getString("nckd_salsyncstatus").equals("1"))
                        continue;
                    //需要调整的条数
                    index++;
                    //定调薪信息
                    Long adjRecordId = entry.getLong("nckd_adjrecord.id");
                    DynamicObject adjRecord = BusinessDataServiceHelper.loadSingle(adjRecordId, "hcdm_salaryadjrecord");
                    //定调薪档案
                    Long adjFileId = entry.getLong("nckd_adjfile.id");
                    //定调薪人员信息
                    Long relPersonId = adjRecord.getLong("relpersonid");
                    DynamicObject relPerson = BusinessDataServiceHelper.loadSingle(relPersonId, "hcdm_decadjrelperson");
                    Map map = buildContent(bill, entry, adjRecord, relPerson, isAdjustJob, jobMap);
                    if(!Boolean.valueOf(map.get("success").toString())) {
                        entry.set("nckd_synclog", map.get("msg").toString());
                    }
                    else {
                        List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("data");
                        Map<String, Object> returnMap = helper.saveDecAdjRecord(list);
                        if (!Boolean.valueOf(returnMap.get("success").toString())) {
                            List dataList = (List) returnMap.get("data");
                            Map dataMap = (Map) dataList.get(0);
                            entry.set("nckd_synclog", dataMap.get("errormsg").toString());
                        } else {
                            //成功条数
                            successCount++;
                            entry.set("nckd_salsyncstatus", "1");
                            entry.set("nckd_synclog", null);
                        }
                    }
                }

                if(successCount != index) {
                    bill.set("billstatus", "B");
                    SaveServiceHelper.save(new DynamicObject[]{bill});
                    throw new KDBizException("定调薪信息出错，请查看薪酬调整明细同步薪酬日志");
                }
                else {
                    bill.set("billstatus", "C");
                    bill.set("auditor", UserServiceHelper.getCurrentUserId());
                    bill.set("auditdate",new Date());
                    SaveServiceHelper.save(new DynamicObject[]{bill});
                }
            }
            else {
                bill.set("billstatus", "C");
                bill.set("auditor", UserServiceHelper.getCurrentUserId());
                bill.set("auditdate",new Date());
                SaveServiceHelper.save(new DynamicObject[]{bill});
            }
        }

        //职级生效
        ScheduleExecutor scheduleExecutor = new ScheduleExecutor();
        scheduleExecutor.setJobCustomParams("5/BIP+ZNTT/6", new HashMap(4));
        scheduleExecutor.dispatch("5/BIRZNR2F16", ScheduleExecutor.isSerialWithJobTask("5/BIP+ZNTT/6"));
    }

    /**
     * 构建参数
     *
     * @param bill
     * @param entry
     * @param adjRecord
     * @param relPerson
     * @return
     */
    public static Map buildContent(DynamicObject bill, DynamicObject entry, DynamicObject adjRecord,
                                                         DynamicObject relPerson, boolean isAdjustJob, Map<String,DynamicObject> jobMap) {
        Map returnMap = new HashMap();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map info = new HashMap();
        //数据模式 1-变更 2-禁用
        info.put("datamode", "1");
        //UUID码
        String uuid = UUID.randomUUID().toString().replace("-", "");
        info.put("uuid", uuid);
        info.put("uniquecode", uuid);
        info.put("calctype", adjRecord.getString("calctype"));
        info.put("salaryadjfile", adjRecord.getLong("salaryadjfile.id"));
        info.put("currency", adjRecord.getLong("currency.id"));
        info.put("salaryadjrsn", adjRecord.getLong("salaryadjrsn.id"));
        info.put("bsed", entry.getDate("nckd_salchangeeffdate"));
        info.put("datasource", adjRecord.getString("datasource"));
        info.put("businessid", bill.getPkValue().toString());
        info.put("standarditem", adjRecord.getLong("standarditem.id"));
        info.put("frequency", adjRecord.getLong("frequency.id"));
        info.put("nckd_fxxs", adjRecord.getBigDecimal("nckd_fxxs"));
        String personNo = entry.getString("nckd_salnumber");
        DynamicObject jobEntry = jobMap.get(personNo);
        //如果是否调级 = 是，则取职级调整分录中的调整后职级职等，如果按工号没找到数据则按定调薪信息的职级职等
        if(isAdjustJob && jobMap != null) {
            if(ObjectUtils.isEmpty(jobEntry)) {
                info.put("grade", adjRecord.getLong("grade.id"));
                info.put("rank", adjRecord.getLong("rank.id"));
            }
            else {
                Long jobLevelId = jobEntry.getLong("joblevel.id");
                Map matchMap = matchStdTableForBill(relPerson.getLong("stdscm.boid"),
                        relPerson.getLong("salaystructure.id"), adjRecord.getLong("standarditem.id"), jobLevelId);
                //判断是否匹配成功
                if(Boolean.valueOf(matchMap.get("success").toString())) {
                    info.put("grade", matchMap.get("grade"));
                    info.put("rank", matchMap.get("rank"));
                }
                else {
                    returnMap.put("success", false);
                    returnMap.put("msg", matchMap.get("msg").toString());
                    return returnMap;
                }
            }
        }
        else {
            info.put("grade", adjRecord.getLong("grade.id"));
            info.put("rank", adjRecord.getLong("rank.id"));
        }
        info.put("amount", entry.getBigDecimal("nckd_amount"));

        //人员相关信息
        Map relperson_data = new HashMap();
        relperson_data.put("personname", relPerson.getString("personname"));
        relperson_data.put("empnumber", relPerson.getString("empnumber"));
        relperson_data.put("org", relPerson.getLong("org.id"));
        relperson_data.put("adminorg", relPerson.getLong("adminorg.id"));
        relperson_data.put("assoadminorg", relPerson.getLong("assoadminorg.id"));
        relperson_data.put("depemp", relPerson.getLong("depemp.id"));
        relperson_data.put("country", 1000001L);
        if(isAdjustJob && jobMap != null && !ObjectUtils.isEmpty(jobEntry)) {
            relperson_data.put("joblevel", jobEntry.getLong("joblevel.id"));
            relperson_data.put("jobgrade", jobEntry.getLong("jobgrade.id"));
        }
        else {
            if(relPerson.getLong("joblevel.id") != 0L) {
                relperson_data.put("joblevel", relPerson.getLong("joblevel.id"));
            }
            if(relPerson.getLong("jobgrade.id") != 0L) {
                relperson_data.put("jobgrade", relPerson.getLong("jobgrade.id"));
            }
        }
        relperson_data.put("salaystructure", relPerson.getLong("salaystructure.id"));
        relperson_data.put("stdscm", relPerson.getLong("stdscm.id"));
        relperson_data.put("empgroup", 1019L);
        info.put("relperson_data", relperson_data);
        list.add(info);
        returnMap.put("data", list);
        returnMap.put("success", true);
        return returnMap;
    }

}