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

import com.alibaba.fastjson.JSON;
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.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.validate.BillStatus;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.servicehelper.DispatchServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
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.base.entity.helper.EntityHelper;
import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
import nckd.jxccl.hr.excells.common.ExcellsConstant;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* 优秀生-推送调薪
* 实体标识：nckd_excellentssallowance
* @author W.Y.C
* @date 2026/1/3 15:11
* @version 1.0
*/
public class PushAdjustOpPlugin extends AbstractOperationServicePlugIn implements Plugin {

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

    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        super.onAddValidators(e);
    }

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        e.getFieldKeys().addAll(this.billEntityType.getAllFields().keySet());
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        Long salaryItemId = EntityHelper.getIdByNumber(FormConstant.HSBS_STANDARDITEM, "jt007");
        Long billTypeId = EntityHelper.getIdByNumber(FormConstant.BOS_BILLTYPE, FormConstant.HCDM_APPLYBILL_BT_ADJ);
        Long countryId = EntityHelper.getIdByNumber(FormConstant.BD_COUNTRY, "001");
        Long salaryAdjuStrSnId = EntityHelper.getIdByNumber(FormConstant.HSBS_SALARYADJUSTRSN, "youxiusheng");
        Long currencyId = EntityHelper.getIdByNumber(FormConstant.BD_CURRENCY, "CNY");
        Long adjApproveScmId = EntityHelper.getLatestIdByNumber(FormConstant.HCDM_ADJAPPROVESCM, "dingtiaoxin");
        Long exRateTableId = EntityHelper.getIdByNumber(FormConstant.BD_EXRATETABLE, "ERT-01");
        Long calFrequencyId = EntityHelper.getIdByNumber(FormConstant.HSBS_CALFREQUENCY, "000_m_001");

        List<Long> ids = new ArrayList<>();
        List<Long> personIds = new ArrayList<>();
        for (DynamicObject data : e.getDataEntities()) {
            DynamicObjectCollection entitys = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
            for (DynamicObject entity : entitys) {
                personIds.add(entity.getLong(String.join(".",FormConstant.NCKD_PERSON,FormConstant.ID_KEY)));
            }
            ids.add(data.getLong(FormConstant.ID_KEY));
        }

        //获取员工最新任职
        Map<Long, DynamicObject> empPosOrgRelByEmployeesMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
        List<Long> allEmpPosOrgRelIds = empPosOrgRelByEmployeesMap.values().stream()
                .map(result -> result.getLong(FormConstant.ID_KEY))
                .collect(Collectors.toList());

        Map<String, Object> adjFileParams = new HashMap<>();
        adjFileParams.put("employees", personIds);
        List<String> status = new ArrayList<>();
        status.add(BillStatus.C.toString());
        adjFileParams.put("status", status);
        //获取人员定薪档案
        Map<String, Object> adjFileResult = DispatchServiceHelper.invokeBizService("swc", "hcdm", "IAdjFileInfoService", "queryAdjFileBoByEmp", adjFileParams);
        Map<Long,Long> adjFileIdMap = new HashMap<>();
        //key：定调薪档案ID，Value：发薪组织ID
        Map<Long,Long> adjFileOrgIdMap = new HashMap<>();
        if (ConvertUtil.toBoolean(adjFileResult.get("success"))) {
            List<Map> list = ConvertUtil.toList(adjFileResult.get("data"), ArrayList::new);
            for (Map map : list) {
                Long id = ConvertUtil.toLong(map.get(FormConstant.ID_KEY));
                //根据员工任职匹配
                Long empPosOrgRelId = ConvertUtil.toLong(map.get("empposorgrel_id"));
                if (allEmpPosOrgRelIds.contains(empPosOrgRelId)) {
                    adjFileIdMap.put(ConvertUtil.toLong(map.get("employee_id")),id);
                    adjFileOrgIdMap.put(id,ConvertUtil.toLong(map.get("org_id")));
                }
            }
        }
        //多人可能存在不同发薪组织，按单据和组织拆分定调薪单据。key：单据id-组织ID，value：申请单数据
        Map<String,Map<String, Object>> applyBillMap = new HashMap<>();
        for (DynamicObject data : e.getDataEntities()) {
            boolean isSalAdjPush = data.getBoolean(PositionStructureConstant.NCKD_ISSALADJPUSH);
            if(isSalAdjPush){
                logger.warn("优秀生津贴单据号【{}】已推送过优秀生津贴申请单，忽略此次执行。",data.getString(FormConstant.BILL_NO_KEY));
                continue;
            }
            long id = data.getLong(FormConstant.ID_KEY);
            DynamicObject org = data.getDynamicObject(FormConstant.NCKD_ORG);
            DynamicObject creator = data.getDynamicObject(FormConstant.CREATOR_KEY);

            DynamicObjectCollection entitys = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
            for (DynamicObject entity : entitys) {
                DynamicObject person = entity.getDynamicObject(FormConstant.NCKD_PERSON);
                Long employeeId = person.getLong(FormConstant.ID_KEY);
                Long adjFileId = adjFileIdMap.get(employeeId);
                Long orgId = adjFileOrgIdMap.get(adjFileId);
                Map<String, Object> applyBill = applyBillMap.computeIfAbsent(id+"-"+orgId, k -> new HashMap<>());
                applyBill.put("billname", StrFormatter.format("【{}】申请的优秀生津贴，申请单号：【{}】",creator.getString(FormConstant.NAME_KEY),data.getString(FormConstant.BILL_NO_KEY)));
                applyBill.put("_uniquecode", data.getLong(FormConstant.ID_KEY));
                applyBill.put("org", orgId);
                //定调薪明细字段显示方案   调薪明细字段
                applyBill.put("billtype", billTypeId);
                //国家
                applyBill.put("billcountry", countryId);
                //定调薪类型（优秀生津贴）
                applyBill.put("salaryadjrsn", salaryAdjuStrSnId);
                //默认币种
                applyBill.put("billcurrency", currencyId);
                //定调薪方案
                applyBill.put("salaryadjscm", adjApproveScmId);
                //汇率日期
                applyBill.put("exchangeratedate", new Date());
                //汇率表
                applyBill.put("exctable", exRateTableId);
                //默认生效日期
                applyBill.put("effectivedate", data.getDate(FormConstant.CREATE_TIME_KEY));
                //草稿状态
                applyBill.put("isdraft", "1");
                //审核状态
                applyBill.put("auditstatus", "A");
                //申请单数据来源   //1:手工新增  2:接口写入
                applyBill.put("datasource", "2");
                applyBill.put("description",  StrFormatter.format("【{}】申请的优秀生津贴，申请单号：【{}】，申请日期：【{}】",creator.getString(FormConstant.NAME_KEY),data.getString(FormConstant.BILL_NO_KEY), DateUtil.format(data.getDate(FormConstant.CREATE_TIME_KEY),DateUtil.NORM_DATETIME_PATTERN)));
                List<Map<String, Object>> applyBillEntryData = (List<Map<String, Object>>) applyBill.computeIfAbsent("applybillent", k -> new ArrayList<Map<String, Object>>());

                DynamicObject position = entity.getDynamicObject(FormConstant.NCKD_POSITION_KEY);
                Map<String, Object> applyBillEntry = new HashMap<>();
                applyBillEntry.put("adjfile", adjFileId);
                applyBillEntry.put("employee", employeeId);
                applyBillEntry.put("standarditem", salaryItemId);    //定调薪项目
                applyBillEntry.put("frequency", calFrequencyId);       //频度  月
                applyBillEntry.put("amount", entity.getBigDecimal(FormConstant.NCKD_MONEY));
                applyBillEntry.put("position", position.getLong(FormConstant.ID_KEY));
                applyBillEntry.put("reason", entity.getString(ExcellsConstant.NCKD_DESC));
                applyBillEntry.put("startdate", entity.getDate(ExcellsConstant.NCKD_EFFDT));
                applyBillEntry.put("enddate", entity.getDate(ExcellsConstant.NCKD_LEFFDT) == null ? DateUtil.getMaxDateAsDate() : entity.getDate(ExcellsConstant.NCKD_LEFFDT));
                applyBillEntryData.add(applyBillEntry);
                applyBill.put("applybillent", applyBillEntryData);
                applyBillMap.put(id+"-"+orgId, applyBill);
            }
        }
        if(!applyBillMap.isEmpty()) {


            Map<String, Object> papams = new HashMap<>();
            List<Map<String, Object>> applybillList = new ArrayList<>();
            for (Map.Entry<String, Map<String, Object>> stringMapEntry : applyBillMap.entrySet()) {
                applybillList.add(stringMapEntry.getValue());
            }
            papams.put("data", applybillList);
            papams.put("isUseMatchAmount", Boolean.TRUE);
            List<DynamicObject> saveDynamicObjects = new ArrayList<>();
            TXHandle tx = TX.requiresNew();
            try {
                Map<String, Object> result = DispatchServiceHelper.invokeService("nckd.jxccl.swc.hcdm.servicehelper", "hcdm", "ISwcService", "saveDraftApplyBill", papams);
                logger.info("推送定调薪结果：{}", JSON.toJSONString(result));

                if (!ConvertUtil.toBoolean(result.get("success")) || result.get("data") == null || ConvertUtil.toList(result.get("data")).isEmpty()) {
                    logger.error("推送定调薪失败，原因：{}", JSON.toJSONString(result));
                    throw new ValidationException("推送定调薪失败，原因：" + JSON.toJSONString(result));
                } else {
                    MainEntityType depEmpEntityType = EntityMetadataCache.getDataEntityType(ExcellsConstant.EXCELLENTSSALLOWANCE_ENTITYID);
                    List<Map<String, Object>> list = ConvertUtil.toList(result.get("data"));
                    for (DynamicObject dynamicObject : e.getDataEntities()) {
                        long id = dynamicObject.getLong(FormConstant.ID_KEY);
                        for (Map<String, Object> dataMap : list) {
                            Long uniqueCode = ConvertUtil.toLong(dataMap.get("_uniquecode"));
                            if (id == uniqueCode) {
                                dynamicObject.set(PositionStructureConstant.NCKD_ISSALADJPUSH, Boolean.TRUE);
                                dynamicObject.set(PositionStructureConstant.NCKD_SALADJPUSHTIME, new Date());
//                                dynamicObject.set(PositionStructureConstant.NCKD_SALADJID, adjInfoId);

                            }
                            logger.info("成功推送的定调薪申请单，申请单ID: {}", uniqueCode);
                            saveDynamicObjects.add(dynamicObject);
                        }
                    }
                    tx.commit();
                }
            } catch (Exception ex) {
                tx.markRollback();
                throw ex;
            }finally {
                tx.close();
            }

            if (!saveDynamicObjects.isEmpty()) {
                SaveServiceHelper.update(saveDynamicObjects.toArray(new DynamicObject[0]));
                /*OperationResult operationResult = SaveServiceHelper.saveOperate(ExcellsConstant.EXCELLENTSSALLOWANCE_ENTITYID, saveDynamicObjects.toArray(new DynamicObject[0]), OperateOption.create());
                if (!operationResult.isSuccess()) {
                    StringJoiner errorMsg = new StringJoiner("\n");
                    for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                        errorMsg.add(error.getMessage());
                    }
                    if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
                        errorMsg.add(operationResult.getMessage());
                    }
                    logger.error("保存职位津贴失败，原因：{}", errorMsg.toString());
                    throw new ValidationException("保存职位津贴失败，原因：" + errorMsg.toString());
                } else {
                    logger.info("成功保存 {} 条职位津贴记录", saveDynamicObjects.size());
                }*/
            }
        }
    }



}