package com.kingdee.eas.custom.esign.app;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.dao.IObjectValue;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemCollection;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.entity.SelectorItemCollection;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.custom.esign.*;
import com.kingdee.eas.custom.esign.bizEnum.ComponentTypeEnum;
import com.kingdee.eas.custom.esign.bizEnum.SyncStatusEnum;
import com.kingdee.eas.custom.esign.tsign.hz.comm.EsignHttpResponse;
import com.kingdee.eas.custom.esign.tsign.hz.exception.EsignException;
import com.kingdee.eas.custom.esign.util.EsignHttpUtil;
import com.kingdee.shr.base.syssetting.BaseItemStateEnum;
import com.kingdee.util.StringUtils;
import org.apache.log4j.Logger;

import com.kingdee.bos.*;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.eas.common.EASBizException;

import java.sql.Time;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ESignTemplateControllerBean extends AbstractESignTemplateControllerBean {
    private static Logger logger = Logger.getLogger(ESignTemplateControllerBean.class);
    //允许同步的控件类型
    private static final Set<Integer> ComponentTypeEnumSet = new HashSet<Integer>();


    static {
        ComponentTypeEnumSet.add(ComponentTypeEnum.SINGLELINETEXT_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.NUMBER_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.DATE_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.MULTILINETEXT_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.ID_CARD_NUMBER_VALUE);

        ComponentTypeEnumSet.add(ComponentTypeEnum.PHONE_NUMBER_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.SIGN_AREA_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.CHECKBOX_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.RADIOBUTTON_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.TICKBOX_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.COMBOBOX_VALUE);
        ComponentTypeEnumSet.add(ComponentTypeEnum.DATESIGNATURE_VALUE);
    }


    @Override
    protected IObjectPK _save(Context ctx, IObjectValue model) throws BOSException, EASBizException {
        ESignTemplateInfo info = (ESignTemplateInfo) model;
        String eSignTemplateNum = info.getESignTemplateNum();
        if (StringUtils.isEmpty(eSignTemplateNum)) {
            throw new BOSException("e 签宝模板编码不能为空!");
        }
        BOSUuid id = info.getId();
        FilterInfo filter = new FilterInfo();
        FilterItemCollection filterItems = filter.getFilterItems();
        if (id != null) {
            filterItems.add(new FilterItemInfo("id", id.toString(), CompareType.NOTEQUALS));
        }
        filterItems.add(new FilterItemInfo("eSignTemplateNum", eSignTemplateNum));
        if (exists(ctx, filter)) {
            throw new BOSException(String.format("e 签宝模板编码[%s]已经存在!", eSignTemplateNum));
        }
        return super._save(ctx, model);
    }

    /**
     * 更新电子签名模板数据
     * 修复页面保存后 字段列表丢失bug
     *
     * @param ctx   系统上下文对象
     * @param pk    要更新的数据主键
     * @param model 要更新的数据
     * @throws BOSException    业务操作异常
     * @throws EASBizException EAS业务异常
     */
    @Override
    protected void _update(Context ctx, IObjectPK pk, IObjectValue model) throws BOSException, EASBizException {
        ESignTemplateInfo info = (ESignTemplateInfo) model;
        // 判断是否是同步操作,同步操作则不处理字段列表
        boolean isSyncAction = info.getBoolean("isSyncAction");
        if (!isSyncAction) {
            SelectorItemCollection sic = new SelectorItemCollection();
            sic.add("entrys.id");
            sic.add("entrys.fields.*");
            ESignTemplateInfo oldInfo = getESignTemplateInfo(ctx, pk, sic);
            ESignTemplateFileEntryCollection oldEntrys = oldInfo.getEntrys();
            Map<String, ESignTemplateFileEntryFieldCollection> entryFieldCollectionMap = new HashMap<String, ESignTemplateFileEntryFieldCollection>();
            for (int i = 0; i < oldEntrys.size(); i++) {
                ESignTemplateFileEntryInfo oldEntryInfo = oldEntrys.get(i);
                entryFieldCollectionMap.put(oldEntryInfo.getId().toString(), oldEntryInfo.getFields());
            }
            ESignTemplateFileEntryCollection entrys = info.getEntrys();
            for (int i = 0; i < entrys.size(); i++) {
                ESignTemplateFileEntryInfo entryInfo = entrys.get(i);
                String entryId = entryInfo.getId().toString();
                ESignTemplateFileEntryFieldCollection fields = entryInfo.getFields();
                fields.clear();
                fields.addCollection(entryFieldCollectionMap.get(entryId));
//                for (int x = 0; x < oldFields.size(); x++) {
//                    ESignTemplateFileEntryFieldInfo xInfo = oldFields.get(x);
//                    if (!fields.contains(xInfo)) {
//                        fields.add(xInfo);
//                    }
//                }
            }
        }
        super._update(ctx, pk, model);
    }

    /**
     * 删除电子签名模板数据
     *
     * @param ctx 系统上下文对象
     * @param pk  要删除数据的主键
     * @throws BOSException    业务操作异常
     * @throws EASBizException EAS业务异常
     */
    @Override
    protected void _delete(Context ctx, IObjectPK pk) throws BOSException, EASBizException {
        // 获取电子签名模板信息并检查状态
        ESignTemplateInfo info = getESignTemplateInfo(ctx, pk);
        BaseItemStateEnum state = info.getState();
        if (BaseItemStateEnum.ENABLE.equals(state)) {
            throw new BOSException("启用的数据，不允许删除！");
        }
        super._delete(ctx, pk);
    }


    /**
     * 同步模板字段
     *
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _syncTemplateFields(Context ctx, String billId)
            throws BOSException, EASBizException {
        super._syncTemplateFields(ctx, billId);
        if (org.apache.commons.lang3.StringUtils.isBlank(billId)) {
            throw new EASBizException(EASBizException.CHECKBLANK, new Object[]{"单据id不能为空!"});
        }
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("id");
        sic.add("entrys.*");
        sic.add("entrys.fields.*");
        ESignTemplateInfo info = getESignTemplateInfo(ctx, new ObjectUuidPK(billId), sic);
        ESignTemplateFileEntryCollection entrys = info.getEntrys();
        for (int i = 0; i < entrys.size(); i++) {
            ESignTemplateFileEntryInfo entryInfo = entrys.get(i);
            String eSignTemplateId = entryInfo.getESignTemplateId();
            try {
                ESignTemplateFileEntryFieldCollection fields = entryInfo.getFields();

                Map<String, ESignTemplateFileEntryFieldInfo> fieldMap = new HashMap<String, ESignTemplateFileEntryFieldInfo>();
                for (int j = 0; j < fields.size(); j++) {
                    ESignTemplateFileEntryFieldInfo fieldInfo = fields.get(j);
                    fieldMap.put(fieldInfo.getTemplateFieldId(), fieldInfo);
                }
                if (org.apache.commons.lang3.StringUtils.isNotBlank(eSignTemplateId)) {
                    //throw new BOSException("e 签宝模板 id为空!");
                    //1.调用接口获取模板字段
                    EsignHttpResponse response = null;
                    try {
                        response = EsignHttpUtil.getDocTemplatesDetailById(ctx, eSignTemplateId);
                    } catch (EsignException e) {
                        e.printStackTrace();
                        throw new BOSException("调用e签宝接口报错: " + e.getMessage());
                    }
                    String body = response.getBody();
                    JSONObject jsonObject = JSONObject.parseObject(body);
                    if (0 != jsonObject.getInteger("code")) {
                        throw new BOSException(jsonObject.getString("message"));
                    }
                    JSONObject data = jsonObject.getJSONObject("data");
                    //附件下载地址
                    //String fileDownloadUrl = data.getString("fileDownloadUrl");
                    JSONArray components = data.getJSONArray("components");
                    //2.比较现有模板字段,如果新增字段则添加,删除字段就更新为失效
                    for (int j = 0; j < components.size(); j++) {
                        JSONObject component = components.getJSONObject(j);
                        //控件类型
                        Integer componentType = component.getInteger("componentType");
                        if (!ComponentTypeEnumSet.contains(componentType)) {
                            continue;
                        }
                        //组件id
                        String componentId = component.getString("componentId");
                        //组件编码(可以为空)
                        String componentKey = component.getString("componentKey");
                        //组件名称
                        String componentName = component.getString("componentName");
                        //是否必填
                        boolean isRrequired = component.getBoolean("required");
                        //组件排序,从1开始
                        int componentOrder = component.getInteger("componentOrder");
                        ESignTemplateFileEntryFieldInfo fieldInfo = fieldMap.get(componentId);
                        if (fieldInfo != null) {
                            fieldMap.remove(componentId);
                        } else {
                            fieldInfo = new ESignTemplateFileEntryFieldInfo();
                            fieldInfo.setTemplateFieldId(componentId);
                            fields.add(fieldInfo);
                        }
                        //修改字段名称
                        fieldInfo.setTemplateFieldName(componentName);
                        //修改字段排序
                        fieldInfo.setSeq(componentOrder);
                        //修改是否必填
                        fieldInfo.setRequired(isRrequired);
                        //组件编码
                        fieldInfo.setTemplateFieldKey(componentKey);
                        //控件类型
                        fieldInfo.setComponentType(ComponentTypeEnum.getEnum(componentType));
                        //控件数据格式
                        JSONObject componentSpecialAttribute = component.getJSONObject("componentSpecialAttribute");
                        fieldInfo.setDataFormat(componentSpecialAttribute.getString("dateFormat"));
//                        JSONObject componentPosition = component.getJSONObject("componentPosition");
//                        if (componentPosition != null) {
//                            BigDecimal componentPositionX = componentPosition.getBigDecimal("componentPositionX");
//                            BigDecimal componentPositionY = componentPosition.getBigDecimal("componentPositionY");
//                            if (null != componentPositionX && null != componentPositionY) {
//                                fieldInfo.setPositionX(componentPositionX);
//                                fieldInfo.setPositionY(componentPositionY);
//                                fieldInfo.setPageNum(componentPosition.getInteger("componentPageNum"));
//                                fieldInfo.setPageRange(componentPosition.getString("componentPageRange"));
//                            }
//                        }
                    }
                }
                if (!fieldMap.isEmpty()) {
                    //已经失效的字段
                    for (String componentId : fieldMap.keySet()) {
                        fieldMap.get(componentId).setInvalid(true);
                    }
                }
                entryInfo.setSyncStatus(SyncStatusEnum.SYNCED);
                entryInfo.setSyncResult("同步成功");
            } catch (BOSException e) {
                logger.error(e.getMessage(), e);
                entryInfo.setSyncStatus(SyncStatusEnum.SYNC_FAILED);
                entryInfo.setSyncResult(e.getMessage());
//                throw new RuntimeException(e);
            }
            entryInfo.setSyncTime(new Time(System.currentTimeMillis()));
        }
        //因为重写了更新方法,所以这里需要设置isSyncAction为true
        info.setBoolean("isSyncAction", true);
        update(ctx, new ObjectUuidPK(billId), info);
        //3.同步模板附件
        //syncTemplateAttachments(ctx, billId);
    }
}