package com.kingdee.eas.custom.compensation.handler;

import com.google.common.collect.Maps;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.metadata.entity.LinkPropertyInfo;
import com.kingdee.bos.metadata.entity.PropertyInfo;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.base.attachment.AttachmentFactory;
import com.kingdee.eas.base.attachment.AttachmentInfo;
import com.kingdee.eas.base.attachment.IAttachment;
import com.kingdee.eas.basedata.org.HROrgUnitInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.compensation.*;
import com.kingdee.eas.custom.compensation.utils.TemplateUtil;
import com.kingdee.eas.framework.CoreBaseInfo;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
import com.kingdee.shr.base.syssetting.util.MetaDataUtil;
import com.kingdee.shr.base.syssetting.util.SelectItem;
import com.kingdee.shr.base.syssetting.web.handler.EditHandler;
import com.kingdee.shr.compensation.app.integrate.*;
import com.kingdee.shr.ml.util.SHRServerResource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @Description 提报套打模板EditHandler
 * @Date 2025/9/15 17:24
 * @Created by heyuan
 */
public class SubmitShemeTemplateEditHandler extends EditHandler {
    private static final Set hidenFields = new HashSet();
    private static final Map<String, String> approveFieldMap = new HashMap<>();
    private final String RESOURCECLASS = "com.kingdee.eas.custom.compensation.SubmitShemeTemplateResource";

    public SubmitShemeTemplateEditHandler() {
        super();
        hidenFields.add("id");
        hidenFields.add("tempId");
        hidenFields.add("entry");
        hidenFields.add("lastUpdateTime");
        hidenFields.add("lastUpdateUser");
        hidenFields.add("createTime");
        hidenFields.add("CU");
        hidenFields.add("creator");
        hidenFields.add("sourceBillId");
        hidenFields.add("hasEffected");
        hidenFields.add("isMultiEntry");
        hidenFields.add("hrOrgUnit");
        hidenFields.add("costType");
        hidenFields.add("datasource");
        hidenFields.add("isInner");
        hidenFields.add("isSsc");
        hidenFields.add("approveType");
        hidenFields.add("handler");
        hidenFields.add("auditor");
        hidenFields.add("sourceFunction");
        hidenFields.add("billSource");
        hidenFields.add("codingRuleHelper");
        //分录
        hidenFields.add("entry.bill");
        hidenFields.add("entry.id");
        hidenFields.add("entry.CU");
        hidenFields.add("entry.lastUpdateTime");
        hidenFields.add("entry.lastUpdateUser");
        hidenFields.add("entry.createTime");
        hidenFields.add("entry.creator");
        hidenFields.add("entry.useDefault");
        hidenFields.add("entry.ifsalaryshow");
        hidenFields.add("entry.dealStatus");
        hidenFields.add("entry.isCal");
        hidenFields.add("entry.description");
        hidenFields.add("entry.cmpEmpORelation");
        hidenFields.add("entry.transTime");
        hidenFields.add("entry.hrOrgUnit");

        hidenFields.add("entry.s81");
        hidenFields.add("entry.s66");
        hidenFields.add("entry.s76");
        hidenFields.add("entry.s70");
        hidenFields.add("entry.s69");
        hidenFields.add("entry.s68");
        hidenFields.add("entry.s67");
        hidenFields.add("entry.s62");
        hidenFields.add("entry.s61");
        hidenFields.add("entry.s65");
        hidenFields.add("entry.s64");
        hidenFields.add("entry.s63");
        hidenFields.add("entry.s75");
        hidenFields.add("entry.s74");
        hidenFields.add("entry.s73");
        hidenFields.add("entry.s72");
        hidenFields.add("entry.s20");
        hidenFields.add("entry.s79");
        hidenFields.add("entry.s77");
        hidenFields.add("entry.s80");
        hidenFields.add("entry.s71");
        hidenFields.add("entry.s78");
        hidenFields.add("entry.s73");
        hidenFields.add("entry.s73");
        hidenFields.add("entry.s73");
        hidenFields.add("entry.s73");

        approveFieldMap.put("approveHis.multiapprove.createtime", "审批时间");
        approveFieldMap.put("approveHis.personid.name", "审批人");
        approveFieldMap.put("approveHis.assigndetail.actdefname", "任务");
        approveFieldMap.put("approveHis.multiapprove.handleropinion", "处理策略");
        approveFieldMap.put("approveHis.multiapprove.opinion", "审批意见");

    }

    /**
     * 创建新模型后的处理方法
     *
     * @param request      HTTP请求对象
     * @param response     HTTP响应对象
     * @param coreBaseInfo 核心基础信息对象
     * @throws SHRWebException SHRWeb异常
     */
    @Override
    protected void afterCreateNewModel(
            HttpServletRequest request,
            HttpServletResponse response,
            CoreBaseInfo coreBaseInfo
    ) throws SHRWebException {
        super.afterCreateNewModel(request, response, coreBaseInfo);
        SubmitShemeTemplateInfo info = (SubmitShemeTemplateInfo) coreBaseInfo;
        HROrgUnitInfo hrOrgUnitInfo = new HROrgUnitInfo();
        hrOrgUnitInfo.setId(BOSUuid.read("00000000-0000-0000-0000-000000000000CCE7AED4"));
        info.setHrOrgUnit(hrOrgUnitInfo);
    }

    /**
     * 获取提报方案字段
     *
     * @param submitSchemeId 提报方案id
     * @return
     * @throws SHRWebException
     */
    public List<SelectItem> getSubmitSchemeIdFields(String submitSchemeId) throws SHRWebException {
        Context ctx = this.getContext();
        if (StringUtils.isBlank(submitSchemeId)) {
            throw new ShrWebBizException("提报方案id不能为空！</br> The reported proposal ID must not be blank!");
        }
        //获取提报方案字段
        boolean dynamicColmunRequired = true;
        Map<String, Object> params = Maps.newHashMap();
        params.put("datasource", 1);
        params.put("costTypeId", "");
        params.put("dynamicColmunRequired", dynamicColmunRequired);
        params.put("hrOrgUnitId", "");
        Map<String, PropertyInfo> properties = MetaDataUtil.getProperties(getContext(), new BatchSubmitShemeBill().getName());
        Map<String, PropertyInfo> entryInfoProperties = MetaDataUtil.getProperties(getContext(), new BatchSubmitShemeBillEntry().getName());
        List<SelectItem> list = new ArrayList();
        for (String name : properties.keySet()) {
            if (hidenFields.contains(name)) {
                continue;
            }
            PropertyInfo propertyInfo = properties.get(name);
            String alias = propertyInfo.getAlias();
            if (propertyInfo instanceof LinkPropertyInfo) {
                //连接属性
                SelectItem nameItem = new SelectItem();
                nameItem.setValue(name + ".name");
                setSelectAlias(ctx, nameItem, alias + ".Name", alias + ".名称");
                list.add(nameItem);
                //连接属性
                SelectItem numberItem = new SelectItem();
                numberItem.setValue(name + ".number");
                setSelectAlias(ctx, numberItem, alias + ".Code", alias + ".编码");
                list.add(numberItem);
            } else {
                SelectItem item = new SelectItem();
                item.setValue(name);
                item.setAlias(alias);
                list.add(item);
            }
        }
        //2.分录属性
        SelectItem snItem = new SelectItem();
        snItem.setValue("entry.SN");
        setSelectAlias(ctx, snItem, "Entry.SN", "分录.序号");
        list.add(snItem);
        for (String name : entryInfoProperties.keySet()) {
            PropertyInfo propertyInfo = entryInfoProperties.get(name);
            String entryPropertyName = "entry." + name;
            if (hidenFields.contains(entryPropertyName)) {
                continue;
            }
            if (propertyInfo instanceof LinkPropertyInfo) {
                //连接属性
                SelectItem nameItem = new SelectItem();
                nameItem.setValue(entryPropertyName + ".name");
                setSelectAlias(ctx, nameItem,
                        "Entry." + propertyInfo.getAlias() + ".Name",
                        "分录." + propertyInfo.getAlias() + ".名称");
                list.add(nameItem);
                SelectItem numberItem = new SelectItem();
                numberItem.setValue(entryPropertyName + ".number");
                setSelectAlias(ctx, numberItem,
                        "Entry." + propertyInfo.getAlias() + ".Code",
                        "分录." + propertyInfo.getAlias() + ".编码");
                list.add(numberItem);
            } else {
                SelectItem item = new SelectItem();
                item.setValue(entryPropertyName);
                setSelectAlias(ctx, item, "Entry." + propertyInfo.getAlias(), "分录." + propertyInfo.getAlias());
                list.add(item);
            }
        }
        //3.获取提报方案项
        CalSubmitSchemeItemCollection schemeItemCols;
        try {
            schemeItemCols = CalSubmitSchemeItemFactory.getLocalInstance(ctx).getCalSubmitSchemeItemCollection("select calSubmitItem.*,isRequired where calSubmitScheme = '" + submitSchemeId + "' and isShow = 1 and state = 1 order by sortSn asc");
        } catch (BOSException e) {
            throw new SHRWebException(e.getMessage(), e);
        }
        for (int i = 0; i < schemeItemCols.size(); ++i) {
            CalSubmitSchemeItemInfo calSchemeItem = schemeItemCols.get(i);
            CalSubmitItemInfo calItem = calSchemeItem.getCalSubmitItem();
            String alias = calItem.getName();
            String propName = "schemeItem.S" + calItem.getFieldSn();
            //多语言资源
            SelectItem item = new SelectItem();
            //连接属性
            item.setValue(propName);
            setSelectAlias(ctx, item, "Entry." + alias, "分录." + alias);
            list.add(item);
        }
        //4.获取审批人信息字段
        for (String name : approveFieldMap.keySet()) {
            SelectItem item = new SelectItem();
            String localName = SHRServerResource.getString(RESOURCECLASS, name, ctx);
            item.setValue(name);
            if (StringUtils.isNotBlank(localName) && !"Missing Resource".equalsIgnoreCase(localName)) {
                item.setAlias(localName);
            } else {
                item.setAlias("审批历史." + approveFieldMap.get(name));
            }
            list.add(item);
        }
        //返回数据
        return list;
    }

    private void setSelectAlias(Context ctx, SelectItem item, String enName, String cnName) {
        if (ctx.getLocale().getLanguage().equalsIgnoreCase("l1")) {
            item.setAlias(enName);
        } else {
            item.setAlias(cnName);
        }
    }

    /**
     * 创建新模型数据
     *
     * @param request
     * @param response
     * @param modelMap
     * @return
     * @throws SHRWebException
     */
    public void addEntryDataAction(
            HttpServletRequest request,
            HttpServletResponse response,
            ModelMap modelMap
    ) throws SHRWebException {
        //附件id
        String attachmentId = request.getParameter("attachmentId");
        //提报方案id
        String submitSchemeId = request.getParameter("submitSchemeId");
        if (StringUtils.isBlank(attachmentId)) {
            throw new ShrWebBizException("附件id不能为空！</br> Attachment ID cannot be empty!");
        }
        if (StringUtils.isBlank(submitSchemeId)) {
            throw new ShrWebBizException("提报方案id不能为空！</br> Submission Plan ID cannot be empty!");
        }
        Context ctx = this.getContext();
        try {
            IAttachment iAttachment = AttachmentFactory.getLocalInstance(ctx);
            //获取附件信息
            AttachmentInfo attachmentInfo = iAttachment.getAttachmentInfo(new ObjectUuidPK(attachmentId));
            byte[] file = attachmentInfo.getFile();
            if (file == null) {
                throw new ShrWebBizException("附件为空！</br> The attachment is empty!");
            }
            //提取模板字段
            Set<String> fields = TemplateUtil.extractVariablesFromWord(file);
            if (fields.isEmpty()) {
                throw new ShrWebBizException("未匹配到模板字段! </br> No template field matched!");
            }
            List<SubmitShemeTemplateEntryInfo> entryInfos = new ArrayList<SubmitShemeTemplateEntryInfo>();
            for (String field : fields) {
                //提报套打模板分录
                SubmitShemeTemplateEntryInfo entryInfo = new SubmitShemeTemplateEntryInfo();
                //必须创建id,不然表单页面表格因为没有id会报错
                entryInfo.setId(BOSUuid.create(entryInfo.getBOSType()));
                entryInfo.setTemplateField(field);
                entryInfos.add(entryInfo);
            }
            //获取提报方案字段
            List<SelectItem> submitSchemeIdFields = getSubmitSchemeIdFields(submitSchemeId);
            modelMap.put("submitSchemeFields", submitSchemeIdFields);
            modelMap.put("entryInfos", entryInfos);
            //返回数据
            this.writeSuccessData(modelMap);
        } catch (BOSException e) {
            throw new ShrWebBizException(e);
        } catch (EASBizException e) {
            throw new ShrWebBizException(e);
        } catch (IOException e) {
            throw new ShrWebBizException(e);
        }
    }

    /**
     *
     * @param request
     * @param response
     * @param model
     * @throws SHRWebException
     */
    @Override
    protected void beforeSave(
            HttpServletRequest request,
            HttpServletResponse response,
            CoreBaseInfo model
    ) throws SHRWebException {
        super.beforeSave(request, response, model);
        SubmitShemeTemplateInfo info = (SubmitShemeTemplateInfo) model;
        //提报方案
        SubmitShemeTemplateEntryCollection entry = info.getEntry();
        Set<String> billProperties = new HashSet<String>();
        Set<String> entryProperties = new HashSet<String>();
        Set<String> schemeItemProperties = new HashSet<String>();
        Set<String> selectItemCol = new HashSet<String>();
        for (int i = 0; i < entry.size(); i++) {
            SubmitShemeTemplateEntryInfo entryInfo = entry.get(i);
            String column = entryInfo.getColumn();
            if (StringUtils.isBlank(column)) {
                throw new ShrWebBizException("请选择字段！</br> Please select a field!");
            }
            if (column.contains("entry.")) {
                entryProperties.add(column);
            } else if (column.contains("schemeItem.")) {
                schemeItemProperties.add(column.substring("schemeItem.".length()));
            } else if (column.contains("approveHis.")) {
                continue;
            } else {
                billProperties.add(column);
            }
        }
        selectItemCol.addAll(billProperties);
        selectItemCol.addAll(entryProperties);
        info.setBillProperties(StringUtils.join(billProperties, ","));
        info.setEntryProperties(StringUtils.join(entryProperties, ","));
        info.setSelectItemCol(StringUtils.join(selectItemCol, ","));
        info.setSchemeItems(StringUtils.join(schemeItemProperties, ","));
    }

    /**
     * 初始化模型数据
     *
     * @param request
     * @param response
     * @param coreBaseInfo
     * @throws SHRWebException
     */
    @Override
    protected void afterInitModel(
            HttpServletRequest request,
            HttpServletResponse response,
            CoreBaseInfo coreBaseInfo
    ) throws SHRWebException {
        super.afterInitModel(request, response, coreBaseInfo);
        String operateStatus = (String) request.getAttribute("operateState");
        SubmitShemeTemplateInfo info = (SubmitShemeTemplateInfo) coreBaseInfo;
        CalSubmitSchemeInfo calSubmitScheme = info.getCalSubmitScheme();
        if (calSubmitScheme != null) {
            String submitSchemeId = calSubmitScheme.getId().toString();
            //当页面状态查看或编辑状态时，把自定义枚举字段的value改为枚举名称
            if ("view".equalsIgnoreCase(operateStatus) || "edit".equalsIgnoreCase(operateStatus)) {
                SubmitShemeTemplateEntryCollection entrys = info.getEntry();
                //获取提报方案字段
                List<SelectItem> submitSchemeFields = getSubmitSchemeIdFields(submitSchemeId);
                //当页面状态为编辑状态时，获取提报方案字段
                if ("edit".equalsIgnoreCase(operateStatus)) {
                    Map initData = (Map) request.getAttribute("view_initData");
                    initData.put("submitSchemeFields", submitSchemeFields);
                }
                for (int i = 0; i < entrys.size(); i++) {
                    SubmitShemeTemplateEntryInfo submitShemeTemplateEntryInfo = entrys.get(i);
                    String column = submitShemeTemplateEntryInfo.getColumn();
                    submitSchemeFields.stream().filter(
                            item -> item.getValue().equals(column)
                    ).findFirst().ifPresent(
                            item -> submitShemeTemplateEntryInfo.setColumn(item.getAlias()
                            )
                    );
                }
            }
        }
    }

    /**
     * 校验模型数据
     *
     * @param request
     * @param response
     * @param model
     * @throws SHRWebException
     */
    @Override
    protected void verifyModel(
            HttpServletRequest request,
            HttpServletResponse response,
            CoreBaseInfo model
    ) throws SHRWebException {
        super.verifyModel(request, response, model);
        SubmitShemeTemplateInfo info = (SubmitShemeTemplateInfo) model;
        //提报方案
        CalSubmitSchemeInfo calSubmitScheme = info.getCalSubmitScheme();
        if (calSubmitScheme == null) {
            throw new ShrWebBizException("提报方案不能为空! ！</br> Submission Plan cannot be empty!");
        }
        SubmitShemeTemplateEntryCollection entrys = info.getEntry();
        if (entrys.isEmpty()) {
            throw new ShrWebBizException("分录字段不能为空! </br> The accounting entry field cannot be empty!");
        }
    }
}
