package nckd.jxccl.sit.hcsi.business.coordination;


import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.org.utils.DynamicObjectUtils;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import nckd.jxccl.sit.hcsi.common.constant.SitConstant;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Tyx 2025-12-15
 * 社保变动单拆单帮助类
 */
public class SinsurCoordSplitService {

    private static final Log logger = LogFactory.getLog(SinsurCoordSplitService.class);
    Long billId;
    DynamicObject bill;

    public SinsurCoordSplitService(Long billId, DynamicObject bill) {
        this.billId = billId;
        this.bill = bill;
    }

    /**
     * <p> 执行拆单
     * <p> 根据参保单位判断：
     * <p> 1.单头和分录参保单位的交集部分 直接调用标品的提交生效
     * <p> 2.单头和分录参保单位的差集部分 生成新的核定单
     */
    public void doSplit () {
        // DynamicObject bill = SitConstant.COORDVERIFYBILL_HELPER.loadOne(billId);
        // 单头参保单位
        Long welfArePayerId = bill.getLong("welfarepayer_r31.id");
        // 分录
        DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("nckd_entryentity");
        // 根据参保单位分组
        Map<Long, List<DynamicObject>> welfGroupMap = entryCols.stream()
                .filter(obj -> obj.getLong("nckd_welfarepayer.id") != welfArePayerId)
                .collect(Collectors.groupingBy(obj -> obj.getLong("nckd_welfarepayer.id")));
        doCopy(bill, welfGroupMap);
    }

    /**
     * 复制单据
     */
    public void doCopy(DynamicObject bill, Map<Long, List<DynamicObject>> welfGroupMap) {
        DynamicObjectCollection newBillCol = new DynamicObjectCollection();
        for (Long welfId : welfGroupMap.keySet()) {
            List<DynamicObject> entryList = welfGroupMap.get(welfId);
            DynamicObject newBill = SitConstant.COORDVERIFYBILL_HELPER.generateEmptyDynamicObject(SitConstant.COORDVERIFYBILL_HELPER.getEntityName());
            // 忽略字段
            Set<String> ignoreFields = getIgnoreFields();
            // 复制
            DynamicObjectUtils.copy(bill, newBill, ignoreFields);
            // 复制后处理相关字段
            newBill.set("dealresult", "0");
            newBill.set("nckd_issplit", true);
            newBill.set("sinsurstd_r31", null);
            newBill.set("nckd_sourcebillid", bill.getLong("id"));
            // 处理分录数据
            DynamicObjectCollection entryCols = newBill.getDynamicObjectCollection("nckd_entryentity");
            entryCols.clear();
            for (DynamicObject oldEntry : entryList) {
                DynamicObject newEntry = entryCols.addNew();
                DynamicObjectUtils.copy(oldEntry, newEntry);
                newBill.set("welfarepayer_r31", oldEntry.getDynamicObject("nckd_welfarepayer"));
                newBill.set("welfarepayertheory_r31", oldEntry.getDynamicObject("nckd_welfarepayertheory"));
                newBill.set("sinsurstd_r31", getSinSurStdByWelfPayerId(oldEntry.getLong("nckd_welfarepayer.id")));
            }
            newBillCol.add(newBill);
        }
        if(newBillCol.size() > 0) {
            // 直接保存 不走校验 需要把参保标准清除掉 但是参保标准是必填字段
            SitConstant.COORDVERIFYBILL_HELPER.save(newBillCol);
//            OperationResult result = SaveServiceHelper.saveOperate(SitConstant.COORDVERIFYBILL_HELPER.getEntityName(), newBillCol.stream().toArray(DynamicObject[]::new), OperateOption.create());
//            if(!result.isSuccess()) {
//                throw new KDBizException(result.getMessage());
//            }
        }
        // 判断下当前单据是否有需要生效的数据
        Long welfArePayerId = bill.getLong("welfarepayer_r31.id");
        DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("nckd_entryentity");
        List<DynamicObject> welfGroupCurList = entryCols.stream()
                .filter(obj -> obj.getLong("nckd_welfarepayer.id") == welfArePayerId)
                .collect(Collectors.toList());
        // 如果分录中有跟表头参保单位一样的数据 则调用标品的提交生效
        if(welfGroupCurList.size() > 0) {
            doSubmitEffect(bill);
        }
        // 否则直接反写源单成无需处理
        else {
            writeBackSourceBill(bill);
        }
    }

    /**
     * 复制单据时排除的字段
     * @return
     */
    private Set<String> getIgnoreFields() {
        Set<String> ignoreFields = new HashSet<String>();
        ignoreFields.add("dealresult");
        ignoreFields.add("failmsg");
        ignoreFields.add("sinsurstd_r31");
        return ignoreFields;
    }


    /**
     * 调用标品的确认生效
     *
     * @param bill
     * @return
     */
    public void doSubmitEffect (DynamicObject bill) {
        if("0".equals(bill.getString("dealresult")) ) {
            OperateOption option = OperateOption.create();
            OperationResult result = OperationServiceHelper.executeOperate("confirmeffect", "hpdi_empcoordverifbill3", new DynamicObject[]{bill}, option);
            if (!result.isSuccess()) {
                String errorMessage = result.getAllErrorInfo().stream()
                        .map(dyx -> dyx.getMessage())
                        .collect(Collectors.joining(", "));
                throw new KDBizException(errorMessage);
            }
        }
    }

    /**
     * 反写源单， 把源单设置成无需处理
     * @param bill
     */
    public void writeBackSourceBill (DynamicObject bill) {
        bill.set("dealresult", "9");
        SitConstant.COORDVERIFYBILL_HELPER.update(new DynamicObject[]{bill});
    }

    /**
     * 判断是否需要拆单
     * @return
     */
    public boolean isNeedSplit () {
        boolean isNeedSplit = true;
        // DynamicObject bill = getCoordVerifyBillDyn();
        // 拆分单据直接返回true
        if(bill.getBoolean("nckd_issplit")) {
            return false;
        }
        // 获取到变动大类
        DynamicObject ruleParam = bill.getDynamicObject("coordruleparam");
        String chgNumber = ruleParam.getString("chgevent_z.number");
        // 非调动的情况下不需要拆单
        if(!chgNumber.equals("1020_S")) {
            return false;
        }
        // 获取到流动类型
        String flowType = ruleParam.getString("flowtype_y");
        // 非流入的情况下不需要拆单
        if(!flowType.equals("1")) {
            return false;
        }
        return isNeedSplit;
    }

    /**
     * 根据实际参保单位获取参保标准
     * 直接取参保单位上参保标准字段
     *
     * @param welfPayerId
     * @return
     */
    public DynamicObject getSinSurStdByWelfPayerId (Long welfPayerId) {
        DynamicObject dyn = SitConstant.WELFARETYPE_HELPER.loadOne(welfPayerId);
        return dyn.getDynamicObject("mulsinsurstd");
    }


    /**
     * 获取社保员工变动处理单数据包
     * @return
     */
    public DynamicObject getCoordVerifyBillDyn () {
        return SitConstant.COORDVERIFYBILL_HELPER.loadOne(billId);
    }
}
