package nckd.jxccl.hr.gzbb;

import kd.bos.bill.BillShowParameter;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.datamodel.ListSelectedRow;
import kd.bos.entity.datamodel.ListSelectedRowCollection;
import kd.bos.entity.datamodel.events.PackageDataEvent;
import kd.bos.form.*;
import kd.bos.form.events.BeforeCreateListDataProviderArgs;
import kd.bos.form.events.BeforeDoOperationEventArgs;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.form.events.MessageBoxClosedEvent;
import kd.bos.form.operate.FormOperate;
import kd.bos.form.operatecol.OperationColItem;
import kd.bos.list.column.ListOperationColumnDesc;
import kd.bos.list.events.BillClosedCallBackEvent;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.login.utils.DateUtils;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

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

/**
 * 央国企人事云》国资报表ext》单据》数据填报
 * 数据填报列表插件
 * nckd_sjtbrw
 * duanyuqi
 * */
public class SjtbCheckFormListPlugin extends AbstractListPlugin {
    private static final Log logger = LogFactory.getLog(SjtbCheckFormListPlugin.class);

    @Override
    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
        FormOperate operate = (FormOperate)args.getSource();
        if ("nckd_xfrw".equals(operate.getOperateKey())) {// 下发任务
            ListSelectedRowCollection listRows = args.getListSelectedData();
            if (listRows.size() != 1) {
                this.getView().showErrorNotification("请选择一行数据进行操作");
                args.setCancel(true);
                return;
            } else {
                ListSelectedRow listSelectedRow = listRows.get(0);
                Object pkValue = listSelectedRow.getPrimaryKeyValue();
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(pkValue, "nckd_sjtbrw");
                String billstatus = dynamicObject.getString("billstatus");// 单据状态
                String nckd_rwzt = dynamicObject.getString("nckd_rwzt");// 任务状态
                // 单据暂存中且任务状态为待上报或已打回
                if ("A".equals(billstatus) && ("1".equals(nckd_rwzt) || "4".equals(nckd_rwzt))) {
                    Map<String, Object> customParamMap = new HashMap<>();
                    customParamMap.put("sjtbrwId", pkValue);// 数据填报任务id
                    customParamMap.put("sjtbrwEntry", "nckd_sjtbrw");// 数据填报任务实体
                    //创建弹出单据页面对象，并赋值
                    BillShowParameter billShowParameter = new BillShowParameter();
                    //设置弹出子单据页面的标识
                    billShowParameter.setFormId("nckd_sjcjrw");
                    //设置弹出子单据页面的标题
                    billShowParameter.setCaption("数据采集任务");
                    //设置弹出子单据页面的打开方式
                    billShowParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
                    //设置子页面关闭回调对象，回调本插件，标识为常量KEY_LEAVE_DAYS对应的值
                    billShowParameter.setCloseCallBack(new CloseCallBack(this, "KEY_NCKD_XFRW_BTN"));
                    // 给子单据传值
                    billShowParameter.setCustomParams(customParamMap);
                    //弹窗子页面和父页面绑定
                    this.getView().showForm(billShowParameter);
                } else {
                    this.getView().showErrorNotification("请选择暂存中的数据进行下发");
                    args.setCancel(true);
                    this.getView().invokeOperation("refresh");
                    return;
                }
            }
        } else if ("nckd_hzbtn".equals(operate.getOperateKey())) { // 汇总
            ListSelectedRowCollection listRows = args.getListSelectedData();
            List<DynamicObject> copyList = new ArrayList<DynamicObject>();
            Date firstDate = null;
            int flag = 0;
            for (int i = 0; i < listRows.size(); i++) {
                Object pkValue = listRows.get(i).getPrimaryKeyValue();
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(pkValue, "nckd_sjtbrw");
                String billstatus = dynamicObject.getString("billstatus");// 单据状态
                String nckd_rwzt = dynamicObject.getString("nckd_rwzt");// 任务状态
                Date nckd_tbsjny = dynamicObject.getDate("nckd_tbsjny");// 数据填报年月
                if (firstDate == null) {
                    firstDate = nckd_tbsjny;
                } else {
                    String firstDateStr = DateUtils.formatDate(firstDate, "yyyy-MM");
                    String nckd_tbsjnyStr = DateUtils.formatDate(nckd_tbsjny, "yyyy-MM");
                    if (!firstDateStr.equals(nckd_tbsjnyStr)) {
                        flag = 1;
                        break;
                    }
                }
                if (!"C".equals(billstatus) || !"2".equals(nckd_rwzt)) { // 非已审核或非已上报
                    flag = 2;
                    break;
                }
                copyList.add(dynamicObject);
            }
            if (flag != 0) {
                if (flag == 1) {
                    this.getView().showErrorNotification("请选择同一年月的数据进行操作");
                    return;
                } else {
                    this.getView().showErrorNotification("请选择已审核且已上报的数据进行操作");
                    return;
                }
            } else {
               boolean saveResult = PushSjcjDataUtils.saveMergeSjtbBill(copyList);
               if (saveResult) {
                   this.getView().showSuccessNotification("汇总成功");
                   this.getView().invokeOperation("refresh");
               } else {
                   this.getView().showErrorNotification("汇总失败");
               }
            }
        } else if ("nckd_lbdhbtn".equals(operate.getOperateKey())) { // 打回
            //上报操作前让用户选择是否继续上报操作，在用户点击确认框上的按钮后，系统会调用confirmCallBack方法
            ConfirmCallBackListener confirmCallBackListener = new ConfirmCallBackListener("querendahuiOp", this);
            //设置页面确认框，参数为：标题，选项框类型，回调监听
            this.getView().showConfirm("请确认是否打回？", MessageBoxOptions.YesNo, confirmCallBackListener);
        } else if ("nckd_lbdhokbtn".equals(operate.getOperateKey())) { // 确认打回
            int saveResult = 0;
            String detail = "";
            ListSelectedRowCollection listRows = args.getListSelectedData();
            for (int i = 0; i < listRows.size(); i++) {
                Object pkValue = listRows.get(i).getPrimaryKeyValue();
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(pkValue, "nckd_sjtbrw");
                String billstatus = dynamicObject.getString("billstatus");// 单据状态
                String nckd_rwzt = dynamicObject.getString("nckd_rwzt");// 任务状态
                if ("C".equals(billstatus) && "2".equals(nckd_rwzt)) { // 已审核且已上报
                    dynamicObject.set("billstatus", "A");// 暂存
                    dynamicObject.set("nckd_rwzt", "1");//待上报
                    SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
                    saveResult ++;
                } else {
                    detail = detail +"单据"+dynamicObject.getString("billno")+" 单据状态不是已审核或任务状态不是已上报 \r\n";
                }
            }
            if (listRows.size() == saveResult) {
                this.getView().showSuccessNotification("打回成功");
            } else {
                this.getView().showConfirm(saveResult + "条数据处理成功，" + (listRows.size() - saveResult) + "条数据处理失败", detail, MessageBoxOptions.OK, ConfirmTypes.Save,null,new HashMap<>(),null);
            }
            this.getView().invokeOperation("refresh");
        } else if ("nckd_lbsbbtn".equals(operate.getOperateKey())) { // 上报
            //上报操作前让用户选择是否继续上报操作，在用户点击确认框上的按钮后，系统会调用confirmCallBack方法
            ConfirmCallBackListener confirmCallBackListener = new ConfirmCallBackListener("querenshangbaoOpt", this);
            //设置页面确认框，参数为：标题，选项框类型，回调监听
            this.getView().showConfirm("请确认是否上报？", MessageBoxOptions.YesNo, confirmCallBackListener);
        } else if ("nckd_lbsbokbtn".equals(operate.getOperateKey())) { // 确认上报
            int saveResult = 0;
            String detail = "";
            ListSelectedRowCollection listRows = args.getListSelectedData();
            for (int i = 0; i < listRows.size(); i++) {
                Object pkValue = listRows.get(i).getPrimaryKeyValue();
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(pkValue, "nckd_sjtbrw");
                String billstatus = dynamicObject.getString("billstatus");// 单据状态
                String nckd_rwzt = dynamicObject.getString("nckd_rwzt");// 任务状态
                if ("C".equals(billstatus) && "1".equals(nckd_rwzt)) { // 已审核且待上报
                    dynamicObject.set("nckd_rwzt", "2");
                    SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
                    saveResult ++;
                } else {
                    detail = detail +"单据"+dynamicObject.getString("billno")+" 单据状态不是已审核或任务状态不是待上报 \r\n";
                }
            }
            if (listRows.size() == saveResult) {
                this.getView().showSuccessNotification("上报成功");
            } else {
                this.getView().showConfirm(saveResult + "条数据处理成功，" + (listRows.size() - saveResult) + "条数据处理失败", detail, MessageBoxOptions.OK, ConfirmTypes.Save,null,new HashMap<>(),null);
            }
            this.getView().invokeOperation("refresh");
        } else if ("nckd_cbtn".equals(operate.getOperateKey())) { // 催办
            //上报操作前让用户选择是否继续上报操作，在用户点击确认框上的按钮后，系统会调用confirmCallBack方法
            ConfirmCallBackListener confirmCallBackListener = new ConfirmCallBackListener("querencuibanOp", this);
            //设置页面确认框，参数为：标题，选项框类型，回调监听
            this.getView().showConfirm("请确认是否催办？", MessageBoxOptions.YesNo, confirmCallBackListener);
        } else if ("nckd_cboktn".equals(operate.getOperateKey())) { // 确认催办
            ListSelectedRowCollection listRows = args.getListSelectedData();
            if (listRows.size() != 1) {
                this.getView().showErrorNotification("请选择一行数据进行操作");
                args.setCancel(true);
                return;
            } else {
                ListSelectedRow listSelectedRow = listRows.get(0);
                Object pkValue = listSelectedRow.getPrimaryKeyValue();
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(pkValue, "nckd_sjtbrw");
                String nckd_rwzt = dynamicObject.getString("nckd_rwzt");// 任务状态
                if ("1".equals(nckd_rwzt)) {// 待上报
                    DynamicObjectCollection nckd_tztbry = dynamicObject.getDynamicObjectCollection("nckd_zrr");// 通知人员
                    if (nckd_tztbry.size() > 0) {
                        List<Long> receivers = nckd_tztbry.stream().map(tztbryObject -> tztbryObject.getLong("fbasedataid.id")).collect(Collectors.toList());
                        PushSjcjDataUtils.savePushCuiBanMsg(dynamicObject, receivers);
                    }
                }
                this.getView().showSuccessNotification("催办成功");
            }
        }
        super.beforeDoOperation(args);
    }

    @Override
    public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
        super.beforeCreateListDataProvider(args);
    }

    @Override
    public void packageData(PackageDataEvent e) {
        super.packageData(e);
        // 判断是操作列
        if (e.getSource() instanceof ListOperationColumnDesc) {
            DynamicObject rowData = e.getRowData();
            String columnKey = ((ListOperationColumnDesc) e.getSource()).getKey();
            // 获取操作列的所有操作项
            List<OperationColItem> operationColItems = (List<OperationColItem>) e.getFormatValue();
            if (StringUtils.equals("nckd_sjtbczl", columnKey)) {
                String billstatus = rowData.getString("billstatus");// 单据状态
                String nckd_rwzt = rowData.getString("nckd_rwzt");// 任务状态
                String nckd_bblx = rowData.getString("nckd_bblx");// 报表类型
                DynamicObjectCollection tztbryObjects = rowData.getDynamicObjectCollection("nckd_zrr");// 通知人员
                // 根据单据状态，设置操作列的按钮灰显
                for (OperationColItem item : operationColItems) {
                    if ("modify".equals(item.getOperationKey())) {// 填报按钮
                        // 单据暂存中且任务状态为待上报或已打回且是填报表
                        if ("A".equals(billstatus) && ("1".equals(nckd_rwzt) || "4".equals(nckd_rwzt)) && "1".equals(nckd_bblx)) {
                            item.setVisible(true);
                            //设置锁定解锁
                            //item.setLocked(false);
                        } else {
                           item.setVisible(false);
                        }
                    } else if ("nckd_xfrw".equals(item.getOperationKey())) {// 下发任务按钮
                        // 单据暂存中且任务状态为待上报或已打回且是填报表
                        if ("A".equals(billstatus) && ("1".equals(nckd_rwzt) || "4".equals(nckd_rwzt)) && "1".equals(nckd_bblx)) {
                            item.setVisible(true);
                        } else {
                            item.setVisible(false);
                        }
                    } else if ("nckd_cbtn".equals(item.getOperationKey())) {// 催办按钮
                        if ("1".equals(nckd_rwzt) && tztbryObjects.size() > 0) {
                            item.setVisible(true);
                        } else {
                            item.setVisible(false);
                        }
                    }
                }
            }
        }
    }

    /**
     * 子界面关闭时，触发父界面的closedCallBack事件；
     * 父界面的插件，可以在此事件，接收子界面返回的数据。
     * 特别说明：
     * 需要在显示子界面时，调用FormShowParameter参数的setCloseCallBack方法，设置回调属性，才会在子界面关闭时触发此事件：
     */
    @Override
    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
        super.closedCallBack(closedCallBackEvent);
        //返回数据不为空并且标识为常量KEY_LEAVE_DAYS对应的值，代表是我们所监控的子页面关闭事件
        if (StringUtils.equals("KEY_NCKD_XFRW_BTN", closedCallBackEvent.getActionId())) {
            this.getView().invokeOperation("refresh");
        }
    }

    @Override
    public void billClosedCallBack(BillClosedCallBackEvent e) {
        Object pkId = e.getPkId();
        if (pkId != null) {
            String closePkId = pkId.toString();
            if (!"0".equals(closePkId)) {
                boolean isDel = QueryServiceHelper.exists("nckd_sjtbrw", pkId);
                if (!isDel) {
                    this.getView().showSuccessNotification("删除成功");
                }
                this.getView().invokeOperation("refresh");
            }
        }
        super.billClosedCallBack(e);
    }

    @Override
    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {
        // TODO Auto-generated method stub
        super.confirmCallBack(messageBoxClosedEvent);
        //判断回调参数id
        if ("querendahuiOp".equals(messageBoxClosedEvent.getCallBackId())) {
            if (MessageBoxResult.Yes.equals(messageBoxClosedEvent.getResult())) {
                this.getView().invokeOperation("nckd_lbdhokbtn");
            }
        } else if ("querenshangbaoOpt".equals(messageBoxClosedEvent.getCallBackId())) {
            if (MessageBoxResult.Yes.equals(messageBoxClosedEvent.getResult())) {
                this.getView().invokeOperation("nckd_lbsbokbtn");
            }
        } else if ("querencuibanOp".equals(messageBoxClosedEvent.getCallBackId())) {
            if (MessageBoxResult.Yes.equals(messageBoxClosedEvent.getResult())) {
                this.getView().invokeOperation("nckd_cboktn");
            }
        }
    }
}
