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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.esign.SealCollection;
import com.kingdee.eas.custom.esign.SealInfo;
import com.kingdee.eas.custom.esign.bizEnum.EsignConfigEnum;
import com.kingdee.eas.custom.esign.bizEnum.SealBizTypeEnum;
import com.kingdee.eas.custom.esign.bizEnum.SealStatusEnum;
import com.kingdee.eas.custom.esign.bizEnum.SealStyleEnum;
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.EsignConfig;
import com.kingdee.eas.custom.esign.util.EsignHttpUtil;
import com.kingdee.eas.framework.CoreBaseCollection;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.sql.Time;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SealControllerBean extends AbstractSealControllerBean {
    private static Logger logger = Logger.getLogger(SealControllerBean.class);
    //查询企业内部印章
    private static final EsignConfigEnum OWNSEALLIST = EsignConfigEnum.org_own_seal_list;
    //查询被外部企业授权印章
    private static final EsignConfigEnum AUTHORIZEDSEALLIST = EsignConfigEnum.org_authorized_seal_list;
    //查询企业内部印章
    private String queryOwnSealListUrl = null;
    //查询被外部企业授权印章
    private String queryAuthorizedSealListUrl = null;
    //机构账号ID
    private String orgId = null;
    private int pageSize = 20;


    public SealControllerBean() {
        EsignConfig esignConfig = EsignConfig.getInstance();
        //查询企业内部印章
        queryOwnSealListUrl = esignConfig.get(OWNSEALLIST.getValue());
        //查询被外部企业授权印章
        queryAuthorizedSealListUrl = esignConfig.get(AUTHORIZEDSEALLIST.getValue());
        //机构账号ID
        orgId = esignConfig.get("orgId");
    }

    /**
     * 同步印章
     *
     * @param ctx
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _syncSeals(Context ctx) throws BOSException, EASBizException {
        super._syncSeals(ctx);
        List<String> errorList = new ArrayList<String>();
        if (StringUtils.isBlank(queryOwnSealListUrl)) {
            errorList.add("查询企业内部印章");
        }
        if (StringUtils.isBlank(queryAuthorizedSealListUrl)) {
            errorList.add("查询被外部企业授权印章");
        }
        if (StringUtils.isBlank(orgId)) {
            errorList.add("机构账号ID");
        }
        if (!errorList.isEmpty()) {
            throw new BOSException(String.join("、", errorList) + "配置为空，请检查配置文件esignConfig.properties");
        }
        try {
            //获取e签宝印章数据
            SealCollection sealCollection = getSealCollection(ctx);
            CoreBaseCollection colls = new CoreBaseCollection();
            Map<String, SealInfo> sealMap = new HashMap<String, SealInfo>();
            for (int i = 0; i < sealCollection.size(); i++) {
                SealInfo sealInfo = sealCollection.get(i);
                sealMap.put(sealInfo.getSealId(), sealInfo);
            }
            //获取企业内部章
            getOwnSealList(ctx, 1, sealMap, colls);
            //获取授权印章列表
            getAuthorizedSealList(ctx, 1, sealMap, colls);
            //保存
            save(ctx, colls);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BOSException(e);
        }
    }


    /**
     * 获取企业自有印章列表，并根据印章ID将印章信息分类到新增或更新列表中。
     *
     * @param ctx     当前上下文环境，用于HTTP请求等操作
     * @param pageNum 当前页码，用于分页获取数据
     * @param sealMap 已存在的印章映射表，key为印章ID，value为印章信息对象
     * @param colls
     * @throws EsignException 电子签章相关异常
     * @throws BOSException   业务操作相关异常
     */
    protected void getOwnSealList(Context ctx, int pageNum, Map<String, SealInfo> sealMap, CoreBaseCollection colls)
            throws EsignException, BOSException {
        try {
            logger.error("getOwnSealList  start--------------------------------------------------------------------");
            logger.error("getOwnSealList  pageNum: " + pageNum);

            // 查询企业内部印章接口地址并发起GET请求
            String apiUrl = MessageFormat.format(queryOwnSealListUrl, orgId, pageNum, pageSize);
            EsignHttpResponse response = EsignHttpUtil.GET(ctx, apiUrl, null, null, OWNSEALLIST);
            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");
            JSONArray seals = data.getJSONArray("seals");
            logger.error("getOwnSealList  seals: " + seals.size());
            if (seals == null) {
                return;
            }
            // 遍历当前页所有印章信息
            for (int i = 0; i < seals.size(); i++) {
                JSONObject seal = seals.getJSONObject(i);

                // 提取关键字段信息
                String sealId = seal.getString("sealId");
                String sealImageDownloadUrl = seal.getString("sealImageDownloadUrl");
                SealInfo sealInfo = null;
                // 根据是否存在该印章ID判断是新增还是更新
                if (sealMap.containsKey(sealId)) {
                    sealInfo = sealMap.get(sealId);
                } else {
                    sealInfo = new SealInfo();
                    sealInfo.setSealId(sealId);
                    sealInfo.setOrgId(orgId);
                    // 是否被外部授权印章，默认设置为false
                    sealInfo.setAuthorizer(false);
                }
                colls.add(sealInfo);
                // 设置通用属性
                sealInfo.setSealName(seal.getString("sealName"));
                sealInfo.setName(seal.getString("sealName"));
                Boolean defaultSealFlag = seal.getBoolean("defaultSealFlag");
                if (defaultSealFlag != null) {
                    sealInfo.setDefaultSealFlag(defaultSealFlag);
                }
                // 印章业务类型转换处理
                String sealBizType = seal.getString("sealBizType");
                if (StringUtils.isNotBlank(sealBizType)) {
                    sealInfo.setSealBizType(SealBizTypeEnum.getEnum(sealBizType));
                }

                // 印章制作方式转换处理
                Integer sealStyle = seal.getInteger("sealStyle");
                if (sealStyle != null) {
                    sealInfo.setSealStyle(SealStyleEnum.getEnum(sealStyle));
                }

                // 尺寸、创建时间及状态相关信息赋值
                sealInfo.setSealWidth(seal.getInteger("sealWidth"));
                sealInfo.setSealHeight(seal.getInteger("sealHeight"));

                Long sealCreateTime = seal.getLong("sealCreateTime");
                if (sealCreateTime != null) {
                    sealInfo.setSealCreateTime(new Time(sealCreateTime));
                }

                sealInfo.setSealBizTypeDescription(seal.getString("sealBizTypeDescription"));

                Integer sealStatus = seal.getInteger("sealStatus");
                if (sealStatus != null) {
                    sealInfo.setSealStatus(SealStatusEnum.getEnum(sealStatus));
                }
            }
            // 计算总页数，若未达末页则递归调用下一页
            Integer total = data.getInteger("total");
            int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
            if (pageNum < totalPage) {
                getOwnSealList(ctx, ++pageNum, sealMap, colls);
            }

            logger.error("getOwnSealList  end--------------------------------------------------------------------");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }


    /**
     * 获取授权印章列表，并根据分页数据递归拉取所有印章信息。
     * 将获取到的印章分为新增印章(addSeals)和需要更新的印章(updateSeals)，并填充对应的SealInfo对象属性。
     *
     * @param ctx     当前上下文环境，用于HTTP请求等操作
     * @param pageNum 当前请求的页码
     * @param sealMap 已存在的印章映射，key为sealId，value为SealInfo对象
     * @throws EsignException 电子签名相关异常
     * @throws BOSException   业务操作相关异常
     */
    protected void getAuthorizedSealList(Context ctx, int pageNum, Map<String, SealInfo> sealMap, CoreBaseCollection colls)
            throws EsignException, BOSException {
        try {
            logger.error("getAuthorizedSealList  start--------------------------------------------------------------------");
            logger.error("getAuthorizedSealList  pageNum: " + pageNum);

            // 查询企业内部已授权的印章列表
            String apiUrl = MessageFormat.format(queryAuthorizedSealListUrl, orgId, pageNum, pageSize);
            EsignHttpResponse response = EsignHttpUtil.GET(ctx, apiUrl, null, null, AUTHORIZEDSEALLIST);
            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");
            JSONArray seals = data.getJSONArray("seals");
            logger.error("getAuthorizedSealList  seals: " + seals.size());
            if (seals == null) {
                return;
            }
            // 遍历当前页的所有印章信息
            for (int i = 0; i < seals.size(); i++) {
                JSONObject seal = seals.getJSONObject(i);

                // 提取关键字段
                String sealId = seal.getString("sealId");
                String sealImageDownloadUrl = seal.getString("sealImageDownloadUrl");
                SealInfo sealInfo = null;
                // 判断是新增还是更新
                if (sealMap.containsKey(sealId)) {
                    sealInfo = sealMap.get(sealId);
                } else {
                    sealInfo = new SealInfo();
                    sealInfo.setSealId(sealId);
                    sealInfo.setOrgId(orgId);
                    // 标记为外部授权印章
                    sealInfo.setAuthorizer(true);
                }
                colls.add(sealInfo);
                // 填充印章基本信息
                sealInfo.setSealName(seal.getString("sealName"));
                sealInfo.setName(seal.getString("sealName"));
                Boolean defaultSealFlag = seal.getBoolean("defaultSealFlag");
                if (defaultSealFlag != null) {
                    sealInfo.setDefaultSealFlag(defaultSealFlag);
                }
                // 设置印章业务类型
                String sealBizType = seal.getString("sealBizType");
                if (StringUtils.isNotBlank(sealBizType)) {
                    sealInfo.setSealBizType(SealBizTypeEnum.getEnum(sealBizType));
                }

                // 设置印章样式、尺寸等信息
                Integer sealStyle = seal.getInteger("sealStyle");
                if (sealStyle != null) {
                    sealInfo.setSealStyle(SealStyleEnum.getEnum(sealStyle));
                }

                sealInfo.setSealWidth(seal.getInteger("sealWidth"));
                sealInfo.setSealHeight(seal.getInteger("sealHeight"));

                // 时间戳处理
                Long sealCreateTime = seal.getLong("sealCreateTime");
                if (sealCreateTime != null) {
                    sealInfo.setSealCreateTime(new Time(sealCreateTime));
                }

                sealInfo.setSealBizTypeDescription(seal.getString("sealBizTypeDescription"));

                // 设置印章状态
                Integer sealStatus = seal.getInteger("sealStatus");
                if (sealStatus != null) {
                    sealInfo.setSealStatus(SealStatusEnum.getEnum(sealStatus));
                }

                // 授权相关信息设置
                sealInfo.setAuthorizerOrgId(seal.getString("authorizerOrgId"));
                sealInfo.setAuthorizerOrgName(seal.getString("authorizerOrgName"));
                sealInfo.setSealAuthBizId(seal.getString("sealAuthBizId"));

                // 授权生效与失效时间
                Long effectiveTime = seal.getLong("effectiveTime");
                if (effectiveTime != null) {
                    sealInfo.setEffectiveTime(new Time(effectiveTime));
                }

                Long expireTime = seal.getLong("expireTime");
                if (expireTime != null) {
                    sealInfo.setExpireTime(new Time(expireTime));
                }
            }

            // 分页逻辑判断是否继续下一页
            Integer total = data.getInteger("total");
            int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
            if (pageNum < totalPage) {
                getAuthorizedSealList(ctx, ++pageNum, sealMap, colls);
            }

            logger.error("getAuthorizedSealList  end--------------------------------------------------------------------");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }
}