package nckd.jxccl.sit.hcsi.formplugin.web.datacomparison;

import kd.bos.algo.DataSet;
import kd.bos.algo.Row;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.ObjectUtils;
import kd.bos.entity.datamodel.AbstractFormDataModel;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.TableValueSetter;
import kd.bos.form.IFormView;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.events.BeforeDoOperationEventArgs;
import kd.bos.form.operate.FormOperate;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import nckd.jxccl.sit.hcsi.business.datacomparison.DataComparisonPushService;
import nckd.jxccl.sit.hcsi.business.datacomparison.DataComparisonQueryService;
import nckd.jxccl.sit.hcsi.common.constant.SitConstant;
import org.apache.commons.lang3.StringUtils;

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

/**
 * Tyx 2025-10-31
 * 社保明细差异对比单表达插件
 */
public class DetailCompareBillEdit extends AbstractFormPlugin {
    private static final Log logger = LogFactory.getLog(DetailCompareBillEdit.class);
    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
    }

    /**
     * 新建单据的时候判断下是从向导界面过来还是直接列表进来的
     * 如果是向导界面过来的情况，自动携带期间跟参保单位
     * 如果是列表界面过来，不做任何处理
     * @param e
     */
    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);
        this.getModel().setValue("nckd_period", this.getView().getParentView().getFormShowParameter().getCustomParam("periodId"));
        this.getModel().setValue("nckd_welfarepayer", this.getView().getParentView().getFormShowParameter().getCustomParam("welfarepayerId"));
    }

    @Override
    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
        super.beforeDoOperation(args);
        FormOperate formOperate = (FormOperate)args.getSource();
        String key = formOperate.getOperateKey();
        switch (key) {
            case "donothing_query":
                beforeDoQueryVerify(args);
                break;
            case "donothing_confirm":
                beforeDoConfirmVerify(args);
                break;
            case "donothing_push":
                beforeDoPushVerify(args);
        }
    }

    /**
     * 推送算薪前校验
     * @param args
     */
    private void beforeDoPushVerify(BeforeDoOperationEventArgs args) {
        EntryGrid entryGrid = this.getControl("nckd_entryentity");
        int[] selectRows = entryGrid.getSelectRows();
        if(selectRows.length == 0 ) {
            args.setCancel(true);
            this.getView().showTipNotification("请先选中数据！");
        }

        //判断下是否推送过
        IDataModel model = this.getModel();
        DynamicObjectCollection entryCols = model.getEntryEntity("nckd_entryentity");
        List<Integer> pushedRows = new ArrayList();
        for(int rowIndex : selectRows) {
            String dataStatus = entryCols.get(rowIndex).getString("nckd_datastatus");
            if("C".equals(dataStatus)) {
                pushedRows.add(rowIndex+1);
            }
        }

        if(pushedRows.size() > 0) {
            args.setCancel(true);
            this.getView().showTipNotification("第"+StringUtils.join(pushedRows, ",")+"行数据已推送，请重新选择！");
        }


    }

    /**
     * 比对确认操作前校验
     * @param args
     */
    private void beforeDoConfirmVerify(BeforeDoOperationEventArgs args) {
        EntryGrid entryGrid = this.getControl("nckd_entryentity");
        int[] selectRows = entryGrid.getSelectRows();
        if(selectRows.length == 0 ) {
            args.setCancel(true);
            this.getView().showTipNotification("请先选中数据！");
        }
    }

    /**
     * 点击查询前校验：
     */
    private void beforeDoQueryVerify(BeforeDoOperationEventArgs args) {
        IDataModel model = this.getModel();
        DynamicObject dyn = model.getDataEntity();
        DynamicObject period = dyn.getDynamicObject("nckd_period");
        DynamicObject welfarepayer = dyn.getDynamicObject("nckd_welfarepayer");
        DynamicObjectCollection welfaretypeCols = dyn.getDynamicObjectCollection("nckd_welfaretype");
        if(ObjectUtils.isEmpty(period)) {
            args.setCancel(true);
            this.getView().showTipNotification("请先选择期间！");
        }
        if(ObjectUtils.isEmpty(welfarepayer)) {
            args.setCancel(true);
            this.getView().showTipNotification("请先选择参保单位！");
        }
        if(welfaretypeCols.size() == 0) {
            args.setCancel(true);
            this.getView().showTipNotification("请先选择险种！");
        }
    }



    @Override
    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
        super.afterDoOperation(afterDoOperationEventArgs);
        IDataModel model = this.getModel();
        IFormView view = this.getView();
        String key = afterDoOperationEventArgs.getOperateKey();
        switch (key) {
            case "donothing_query":
                model.deleteEntryData("nckd_entryentity");
                DataComparisonQueryService service = new DataComparisonQueryService(model, view);
                DataSet dataSet = service.doQuery();
                handleCompareData(dataSet);
                break;
            case "donothing_confirm":
                doConfirm();
                break;
            case "donothing_push":
                doPush();
        }
    }


    private void doPush() {
        logger.info("推送数据到前端业务数据");
        DataComparisonPushService service = new DataComparisonPushService();
        IDataModel model = this.getModel();
        Date bsed = model.getDataEntity(true).getDate("nckd_period.startdate");
        EntryGrid entryGrid = this.getControl("nckd_entryentity");
        int[] selectRows = entryGrid.getSelectRows();

        //2026-01-07 Tyx 这里调整成后台保存再调刷新
        Object pk = model.getDataEntity().getPkValue();
        HRBaseServiceHelper helper = new HRBaseServiceHelper(model.getDataEntityType().getName());
        DynamicObject bill = helper.loadOne(pk);
        DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("nckd_entryentity");


        List<DynamicObject> list = new ArrayList<>();
        for (int i : selectRows) {
            //list.add(model.getEntryEntity("nckd_entryentity").get(i));
            list.add(entryCols.get(i));
        }
        // 业务数据返回参数
        Map response = service.doPush(list, bsed);

        // 处理返回结果
        List<Map> result = (List<Map>) response.get("result");
        handlePushResult(result, list);
        helper.saveOne(bill);
        this.getView().invokeOperation("refresh");
        //this.getView().updateView("nckd_entryentity");
    }


    /**
     *
     * @param result，推送业务数据返回的结果，bizdatacode = 分录ID + _A / _B
     * @param entryList
     */
    private void handlePushResult (List<Map> result, List<DynamicObject> entryList) {
        // 根据bizdatacode提取
        Map map = result.stream().collect(Collectors.toMap((dyx) -> {
            return dyx.get("bizdatacode").toString();
        }, (dyx) -> {
            return dyx;
        }, (key1, key2) -> {
            return key2;
        }));

        for (DynamicObject entry : entryList) {
            String entryId = entry.getPkValue().toString();
            String keyA = entryId + SitConstant.SeparatorA;
            String keyB = entryId + SitConstant.SeparatorB;

            String errorMsgA = null,errorMsgB = null,statusA = "1",statusB = "1";

            Map actualMapA = (Map) map.get(keyA);

            if(!ObjectUtils.isEmpty(actualMapA)) {
                statusA = actualMapA.get("status").toString();
                if(!"1".equals(statusA)) {
                    errorMsgA = actualMapA.get("errormsg").toString();
                }
            }

            Map actualMapB = (Map) map.get(keyB);

            if(!ObjectUtils.isEmpty(actualMapB)) {
                statusB = actualMapA.get("status").toString();
                if(!"1".equals(statusB)) {
                    errorMsgB = actualMapB.get("errormsg").toString();
                }
            }

            if("1".equals(statusA) && "1".equals(statusB)) {
                entry.set("nckd_datastatus", "C");
                entry.set("nckd_pushlog", null);
            }
            else {
                String msg = StringUtils.defaultString(errorMsgA) + StringUtils.defaultString(errorMsgB);
                entry.set("nckd_pushlog", msg);
            }
        }


    }


    /**
     * 比对实际执行方法
     */
    private void doConfirm() {
        IDataModel model = this.getModel();
        EntryGrid entryGrid = this.getControl("nckd_entryentity");
        int[] selectRows = entryGrid.getSelectRows();
        for (int i : selectRows) {
            model.setValue("nckd_datastatus", "B", i);
        }
        this.getView().updateView("nckd_entryentity");
    }

    /**
     * 处理比对数据
     * @param dataSet
     */
    private void handleCompareData(DataSet dataSet) {
        TableValueSetter setter = new TableValueSetter();
        String[] columnName = dataSet.getRowMeta().getFieldNames();
        int rowIndex = 0;
        AbstractFormDataModel model = (AbstractFormDataModel) this.getModel();
        while(dataSet.hasNext()) {
            Row rowData = dataSet.next();
            List<String> excludeFields = Arrays.asList("type");

            // 比对，单位/个人缴费金额系统内<>单位/个人缴费金额系统外的话，比对结果=不一致
            BigDecimal value1 = rowData.getBigDecimal("companysysvalue") == null ? BigDecimal.ZERO : rowData.getBigDecimal("companysysvalue");
            BigDecimal value2 = rowData.getBigDecimal("companyoutvalue") == null ? BigDecimal.ZERO : rowData.getBigDecimal("companyoutvalue");
            BigDecimal value3 = rowData.getBigDecimal("personsysvalue") == null ? BigDecimal.ZERO : rowData.getBigDecimal("personsysvalue");
            BigDecimal value4 = rowData.getBigDecimal("personoutvalue") == null ? BigDecimal.ZERO : rowData.getBigDecimal("personoutvalue");

            if(value1.add(value2).add(value3).add(value4).compareTo(BigDecimal.ZERO) == 0) {
                continue;
            }

            // 赋值
            for(String columnKey : columnName) {
                if(excludeFields.contains(columnKey))
                    continue;
                setter.set(columnKey, rowData.get(columnKey), rowIndex);
            }


            if(value1.compareTo(value2) != 0 || value3.compareTo(value4) != 0) {
                setter.set("compareresult", "C", rowIndex);
            }

            rowIndex++;
        }
        model.beginInit();
        model.batchCreateNewEntryRow("nckd_entryentity", setter);
        model.endInit();
        this.getView().updateView("nckd_entryentity");
    }
}
