package com.seeyon.apps.esign.service;

import cn.hutool.json.JSONObject;
import com.cedarsoftware.io.JsonObject;
import com.seeyon.aicloud.common.JsonUtils;
import com.seeyon.apps.esign.config.EsignConfigProvider;
import com.seeyon.apps.esign.constants.EsignApiUrl;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import com.seeyon.apps.esign.po.esignapi.EsignApiHeader;
import com.seeyon.apps.esign.po.esignapi.EsignBaseResp;
import com.seeyon.apps.esign.po.seal.SealInfoVo;
import com.seeyon.apps.esign.utils.HttpClient;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.services.ServiceException;
import com.seeyon.utils.form.*;
import com.seeyon.v3x.services.form.FormFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

public class SealService {

    private static final Log log = LogFactory.getLog(SealService.class);
    private EsignConfigProvider configProvider = EsignConfigProvider.getInstance();
    private TokenCacheManager tokenCacheManager = (TokenCacheManager) AppContext.getBean("tokenCacheManager");
    private FormFactory formFactory;

    public FormFactory getFormFactory() {
        if (formFactory == null) {
            formFactory = (FormFactory) AppContext.getBean("formFactory");
        }
        return formFactory;
    }

    public void grantSeal(String appId,Map<String, Object> params) throws Exception {
        JsonObject reqParams = new JsonObject();
        String sealId = getSealId(appId,(String) params.get("orgId"), (String) params.get("sealName"));
        reqParams.put("sealId", sealId);
        List<String> authorizedPsnIds = new ArrayList<>();
        authorizedPsnIds.add((String) params.get("accountId"));
        reqParams.put("authorizedPsnIds", authorizedPsnIds);
        reqParams.put("sealRole", "SEAL_USER");
        reqParams.put("transactorPsnId", params.get("managerId"));
        JSONObject sealAuthScope = new JSONObject();
        List<String> templateIds = new ArrayList<>();
        templateIds.add("ALL");
        sealAuthScope.put("templateIds", templateIds);
        reqParams.put("sealAuthScope", sealAuthScope);
        EsignApiHeader esignApiHeader = EsignApiHeader.build();
        esignApiHeader.appId(appId)
                .httpMethod("POST")
                .heads("")
                .pathAndParameters(EsignApiUrl.SEAL_GRANT_URL)
                .contentMD5(reqParams.toString())
                .signature(tokenCacheManager.getSecretByAppId(appId));
        String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.SEAL_GRANT_URL;
        HttpClient.httpPostRaw(url, reqParams.toString(), esignApiHeader.convert2Headers(), null);
    }

    public String getAntiFakeSealId(String orgName) throws BusinessException {
        List<FormWhereCondition> conditions = new ArrayList<>();
        String formNo = configProvider.getBizConfigByKey(EsignConfigConstants.sealInfoFormCode);
        conditions.add(FormWhereCondition.build().display("印章类型").value("防伪章"));
        conditions.add(FormWhereCondition.build().display("所属组织").value(orgName));
        TableContext master = FormTableExecutor.master(formNo);
        FormColumn formColumn = FormTableExecutor.queryOne(master, conditions, true);
        if(formColumn == null) {
            return null;
        }
        Map<String, Object> fieldsMap = formColumn.getFieldsMap();
        return (String) fieldsMap.get("印章ID");
    }

    private String getSealId(String appId,String orgId, String sealName) throws Exception {
        String host = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST);
        int pageNo = 1;
        int pageSize = 20;
        EsignApiHeader esignApiHeader = EsignApiHeader.build();
        esignApiHeader.appId(appId)
                .httpMethod("GET")
                .heads("")
                .pathAndParameters(EsignApiUrl.SEAL_QUERY_URL + "?" + HttpClient.sortQueryString("orgId=" + orgId + "&pageNo=" + pageNo + "&pageSize=" + pageSize))
                .contentMD5("")
                .signature(tokenCacheManager.getSecretByAppId(appId));
        String url = host + EsignApiUrl.SEAL_QUERY_URL + "?orgId=" + orgId + "&pageNo=" + pageNo + "&pageSize=" + pageSize;
        String respStr = HttpClient.httpGet(url, esignApiHeader.convert2Headers(), "UTF-8");
        EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
        Map<String, Object> data = (Map<String, Object>) esignBaseResp.getData();
        LinkedList<Object> seals = (LinkedList<Object>) data.get("seals");
        for (Object seal : seals) {
            Map<String, Object> sealMap = (Map<String, Object>) seal;
            if (sealMap.get("sealName").equals(sealName)) {
                return (String) sealMap.get("sealId");
            }
        }
        return null;
    }

    public void upsertOaSealDoc(SealInfoVo vo) {
        String formNo = configProvider.getBizConfigByKey(EsignConfigConstants.sealInfoFormCode);
        List<FormWhereCondition> conditions = new ArrayList<>();
        conditions.add(FormWhereCondition.build().display("印章ID").value(vo.getSealId()));
        FormColumn formColumn = null;
        TableContext master = null;
        try {
            master = FormTableExecutor.master(formNo);
            formColumn = FormTableExecutor.queryOne(master,conditions,true);
        } catch (Exception e) {
            log.error("查询印章信息失败: " + e.getMessage(), e);
        }
        if (formColumn == null) {
            if ("已启用".equals(vo.getStatusDescription())) {
                Map<String, Object> params = new HashMap<>();
                params.put("印章ID", vo.getSealId());
                params.put("印章名称", vo.getSealName());
                params.put("印章类型", vo.getSealBizTypeDescription());
                params.put("印章状态", vo.getStatusDescription());
//               params.put("印章图片地址",vo.getSealImageDownloadUrl());

                try {
                    FormSaveUtil.formSave(configProvider.getBizConfigByKey(EsignConfigConstants.formLoginName),configProvider.getBizConfigByKey(EsignConfigConstants.sealInfoFormCode),formFactory,params,null);
                } catch (ServiceException e) {
                    log.error(vo.getSealName() + "信息写入OA档案失败," + e.getMessage(), e);
                }
            }
        } else {
            if (!"已启用".equals(vo.getStatusDescription()) && master != null) {
                try {
                    FormTableExecutor.delete(master,conditions);
                } catch (Exception e) {
                    log.error("删除停用印章失败" + e.getMessage(), e);
                }
            }
        }
    }
}
