package com.sifang.modules.esign.service;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.jfinal.plugin.activerecord.Db;
import com.sifang.modules.config.EsignConfig;
import com.sifang.modules.esign.cn.tsign.hz.comm.EsignHttpHelper;
import com.sifang.modules.esign.cn.tsign.hz.comm.EsignHttpResponse;
import com.sifang.modules.esign.cn.tsign.hz.enums.EsignRequestType;
import com.sifang.modules.esign.cn.tsign.hz.exception.EsignDemoException;
import com.sifang.modules.esign.constants.ESignConstants;

import com.sifang.modules.sunshine.SystemSetting.entity.ProjectCompanySettings;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ESignAuthService extends BaseService {

    private static Logger logger= LoggerFactory.getLogger(ESignAuthService.class);

    /**
     * 获取机构认证&授权页面链接
     */
    public void createOrgAccount(ProjectCompanySettings settings) throws EsignDemoException {
        String apiaddr = "/v3/org-auth-url";

        Map<String, Object> param = new HashMap<>();

        // 组织机构认证配置项
        Map<String, Object> orgAuthConfig = new HashMap<>();
        orgAuthConfig.put("orgName", settings.getName());

        Map<String,Object> orgInfo=new HashMap<>();
        orgInfo.put("orgIDCardNum",settings.getEnterpriseQualificationNumber());
        orgInfo.put("orgIDCardType","CRED_ORG_USCC"); //组织机构证件类型，可选值如下： CRED_ORG_USCC - 统一社会信用代码  CRED_ORG_REGCODE - 工商注册号
        orgInfo.put("legalRepName",settings.getChargePerson()); //法定代表人姓名

        orgAuthConfig.put("orgInfo",orgInfo); //组织机构身份附加信息

        // 机构实名认证页面配置项
        Map<String, Object> orgAuthPageConfig = new HashMap<>();
        // 指定页面中默认选择的机构认证方式 ORG_BANK_TRANSFER:对公账户打款认证
        orgAuthPageConfig.put("orgDefaultAuthMode", "ORG_BANK_TRANSFER");

        // 经办人身份信息
        Map<String, Object> transactorInfo = new HashMap<>();
        transactorInfo.put("psnAccount", settings.getPsnAccount());

        orgAuthConfig.put("orgAuthPageConfig", orgAuthPageConfig);
        orgAuthConfig.put("transactorInfo", transactorInfo);

        // 机构授权配置项
        Map<String, Object> authorizeConfig = new HashMap<>();
        List<String> authorizedScopes = new ArrayList<>();
        authorizedScopes.add("get_org_identity_info");
        authorizedScopes.add("org_initiate_sign");
        authorizedScopes.add("manage_org_resource");
        authorizeConfig.put("authorizedScopes", authorizedScopes);

        param.put("orgAuthConfig", orgAuthConfig);
        param.put("authorizeConfig", authorizeConfig);
        param.put("transactorUseSeal",true);

        // 指定客户端类型，默认值 ALL
        param.put("clientType", "ALL");

        // 接收回调通知的Web地址
        param.put("notifyUrl", EsignConfig.NotifyUrl+"/a/main/sign/authConfirmCallBack");

        Gson gson = new Gson();
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm = gson.toJson(param);
        //请求方法
        EsignRequestType requestType = EsignRequestType.POST;
        //生成请求签名鉴权方式的Header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,
                jsonParm, requestType.name(), apiaddr, true);
        //发起接口请求
        EsignHttpResponse createOrgAccount = EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr, requestType, jsonParm, header, true);
        JsonObject jsonObject = gson.fromJson(createOrgAccount.getBody(), JsonObject.class);
        logger.info(">>>>>>>>>>>>>>>>>>createOrgAccount  jsonObject:{}",jsonObject);
        if (ESignConstants.SUCCESS.equals(jsonObject.get("code").getAsString())) {
            JsonObject data = jsonObject.getAsJsonObject("data");
            String authUrl = data.get("authUrl").getAsString();   // 机构认证授权长链接 【注】支持自定义域名，微信小程序H5内嵌场景需要使用长链接
            String authShortUrl = data.get("authShortUrl").getAsString();   // 机构认证授权短链接
            String authFlowId = data.get("authFlowId").getAsString();   // 认证授权流程ID
            settings.setAuthUrl(authUrl);
            settings.setAuthShortUrl(authShortUrl);
            settings.setAuthFlowId(authFlowId);
            // 发送短信通知法人 认证授权
        } else {
            throw new EsignDemoException("获取授权链接失败:" + jsonObject.get("message"));
        }
    }

    /**
     * 查询企业内部印章
     */
    public static String orgOwnSealList(String orgId) throws EsignDemoException {
        int pageNum = 1;
        int pageSize = 10;
         Gson gson=new Gson();
        //查询合同专用章：sealBizTypes=CONTRACT
        String apiaddr = "/v3/seals/org-own-seal-list?orgId=" + orgId + "&sealBizTypes=CONTRACT&pageNum=" + pageNum + "&pageSize=" + pageSize;

        //请求方法
        EsignRequestType requestType = EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,
                null, requestType.name(), apiaddr, true);
        //发起接口请求
        EsignHttpResponse response= EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr, requestType, null, header, true);
        JsonObject jsonObject = gson.fromJson(response.getBody(), JsonObject.class);
        if (ESignConstants.SUCCESS.equals(jsonObject.get("code").getAsString())) {
            JsonObject data = jsonObject.getAsJsonObject("data");
            JsonObject seal = data.get("seals").getAsJsonArray().get(0).getAsJsonObject();
            return seal.get("sealId").getAsString();
        } else {
            throw new EsignDemoException(jsonObject.get("message").getAsString());
        }
    }

    /**
     * 查询企业认证授权状态
     */
    public static EsignHttpResponse getOrgIdentityInfo(String orgName) throws EsignDemoException {
        String apiaddr="/v3/organizations/identity-info?orgName="+orgName;

        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm="{}";
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }

    /**
     * 查询机构授权信息
     */
    public static EsignHttpResponse getOrgAuthorizedInfo(String orgId) throws EsignDemoException {
        String apiaddr="/v3/organizations/"+orgId+"/authorized-info";

        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm="{}";
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }

    /**
     * 印章 跨企业授权
     */
    public static String orgSealExternalAuth(String orgId,String sealId,String pnsId,ProjectCompanySettings companySettings) throws EsignDemoException {
        logger.info("印章 跨企业授权  orgSealExternalAuth orgId:{},sealId:{},pnsId:{}",orgId,sealId,pnsId);
        String apiaddr="/v3/seals/org-seals/external-auth";
        Map<String, Object> param = new HashMap<>();
        param.put("orgId", orgId);
        param.put("sealId", sealId);
        param.put("transactorPsnId",pnsId);


        Map<String,Object> authorizedOrgInfo=new HashMap<>();
        authorizedOrgInfo.put("orgName","上海能辉科技股份有限公司");
        authorizedOrgInfo.put("orgIDCardNum","91310000685457643J");

        param.put("authorizedOrgInfo",authorizedOrgInfo);

        Calendar calendar = Calendar.getInstance();
        long time = calendar.getTimeInMillis();
        param.put("effectiveTime", time);
        calendar.add(Calendar.YEAR, 3);
        long time2=calendar.getTimeInMillis();
        param.put("expireTime",time2);
        param.put("redirectUrl", EsignConfig.NotifyUrl+"/a/main/redirect/eSignSuccess");
        //回调地址是在E签宝后台 直接配置的
       /* param.put("notifyUrl", EsignConfig.NotifyUrl+"/a/main/sign/orgSealExternalAuthCallBack");*/
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        Gson gson=new Gson();
        String jsonParm=gson.toJson(param);
        //请求方法
        EsignRequestType requestType = EsignRequestType.POST;
        //生成请求签名鉴权方式的Header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,
                jsonParm, requestType.name(), apiaddr, true);
        //发起接口请求
        EsignHttpResponse httpResponse = EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr, requestType, jsonParm, header, true);
        JsonObject jsonObject = gson.fromJson(httpResponse.getBody(), JsonObject.class);
        if(ESignConstants.SUCCESS.equals(jsonObject.get("code").getAsString())){
            JsonObject createByFileData = jsonObject.getAsJsonObject("data");
            String shortUrl = createByFileData.get("authorizationSignShortUrl").getAsString();
            String url = createByFileData.get("authorizationSignUrl").getAsString();
            String sealAuthBizId=createByFileData.get("sealAuthBizId").getAsString();
            companySettings.setSealAuthorizationSignUrl(url);
            logger.info(">>>>>>>>>>>>>印章 跨企业授权 签署长链接:{},短链接：{},sealAuthBizId:{}",url,shortUrl,sealAuthBizId);
            // 授权链接 未做短信发送到授权人手机
//            StringBuilder contextString = new StringBuilder("尊敬的用户"
//                    + "，您好！能辉光伏邀请您印章授权。点击进入:"+shortUrl);
//            Map<String, Object> result = SfSmsUtils.sendMsg(mobile, contextString.toString(), "能辉光伏", "", SfSmsUtils.SMS_TYPE_A);
//            logger.info("SfSmsUtils.sendMsg result:{}", result);
            return  sealAuthBizId;
        }
        return "";
    }

    /**
     * 获取个人认证链接
     * @return
     * @throws EsignDemoException
     */
    public static EsignHttpResponse getPsnAuthUrl(String pnsAccount) throws EsignDemoException {
        String apiaddr="/v3/psn-auth-url";
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm="{\n" +
                "    \"psnAuthConfig\": {\n" +
                "        \"psnAccount\": \"184xxxxx04\",\n" +
                "        \"psnAuthPageConfig\": {\n" +
                "            \"psnEditableFields\": [\n" +
                "                \"name\",\n" +
                "                \"IDCardNum\",\n" +
                "                \"mobile\",\n" +
                "                \"bankCardNum\"  \n" +
                "            ]\n" +
                "        }\n" +
                "    },\n" +
                "    \"clientType\": \"ALL\",\n" +
                "    \"appScheme\":\"esign://demo/realBack\",\n" +
                "    \"redirectConfig\": {\n" +
                "        \"redirectDelayTime\": \"3\",\n" +
                "        \"redirectUrl\": \"esign://demo/realBack\"\n" +
                "    },\n" +
                "    \"authorizeConfig\": {\n" +
                "        \"authorizedScopes\": [\n" +
                "            \"get_psn_identity_info\",\n" +
                "            \"psn_initiate_sign\",\n" +
                "            \"manage_psn_resource\"\n" +
                "        ]\n" +
                "    },\n" +
                "    \"repeatableAuth\": true\n" +
                "}";

        //请求方法
        EsignRequestType requestType= EsignRequestType.POST;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }

    /**
     * 查询个人认证授权状态
     */
    public static EsignHttpResponse getPsnIdentityInfo(String psnAccount) throws EsignDemoException {
        String apiaddr="/v3/persons/identity-info?psnAccount="+psnAccount;

        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm=null;
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }


    /**
     *  组织机构的内部成员
     */
    public static EsignHttpResponse getCompanyMemberListInfo(String orgId) throws EsignDemoException {
        String apiaddr="/v3/organizations/"+orgId+"/member-list?pageNum=1&pageSize=2";

        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm=null;
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }


    /**
     *  查询企业管理员
     */
    public static EsignHttpResponse getOrgAdministrators(String orgId) throws EsignDemoException {
        String apiaddr="/v3/organizations/"+orgId+"/administrators";

        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm=null;
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }

      /**
     * 印章授权
     */
    public static EsignHttpResponse companyInternalAuth(String orgId,String sealId,String pnsId,String mobile) throws EsignDemoException {
        String apiaddr="/v3/seals/org-seals/internal-auth";
        Map<String, Object> param = new HashMap<>();
        param.put("orgId", orgId);
        param.put("sealId", sealId);
        List<String> authorizedPsnIds=new ArrayList<>();
        authorizedPsnIds.add(pnsId);
        param.put("authorizedPsnIds",authorizedPsnIds);
        param.put("sealRole", "SEAL_USER");
        param.put("transactorPsnId",pnsId);
        Map<String,Object> sealAuthScope=new HashMap<>();
        List<String> templateIds=new ArrayList();
        templateIds.add("ALL");
        sealAuthScope.put("templateIds",templateIds);
        param.put("sealAuthScope",sealAuthScope);
        Calendar calendar = Calendar.getInstance();
        long time = calendar.getTimeInMillis();
        param.put("effectiveTime", time);
        calendar.add(Calendar.YEAR, 3);
        long time2=calendar.getTimeInMillis();
        param.put("expireTime",time2);
        param.put("redirectUrl", EsignConfig.NotifyUrl+"/a/main/redirect/eSignSuccess");
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        Gson gson=new Gson();
        String jsonParm=gson.toJson(param);
        //请求方法
        EsignRequestType requestType = EsignRequestType.POST;
        //生成请求签名鉴权方式的Header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,
                jsonParm, requestType.name(), apiaddr, true);
        //发起接口请求
        EsignHttpResponse httpResponse = EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr, requestType, jsonParm, header, true);
        JsonObject jsonObject = gson.fromJson(httpResponse.getBody(), JsonObject.class);
        if(ESignConstants.SUCCESS.equals(jsonObject.get("code").getAsString())){
            JsonObject createByFileData = jsonObject.getAsJsonObject("data");
            String shortUrl = createByFileData.get("authorizationSignShortUrl").getAsString();
            String url = createByFileData.get("authorizationSignUrl").getAsString();
            logger.info(">>>>>>>>>>>>>印章授权 签署长链接:{},短链接：{}",url,shortUrl );
            // 授权链接 未做短信发送到授权人手机
//            StringBuilder contextString = new StringBuilder("尊敬的用户"
//                    + "，您好！能辉光伏邀请您印章授权。点击进入:"+shortUrl);
//            Map<String, Object> result = SfSmsUtils.sendMsg(mobile, contextString.toString(), "能辉光伏", "", SfSmsUtils.SMS_TYPE_A);
//            logger.info("SfSmsUtils.sendMsg result:{}", result);
        }
        return  httpResponse;
    }


    /**
     * 查询印章跨企业授权状态
     */
    public static EsignHttpResponse getCompanyAuthorizedSealStatus(String orgId,String authorizerOrgId) throws EsignDemoException {
        String apiaddr="/v3/seals/org-authorized-seal-list?orgId="+orgId+"&pageNum=1&pageSize=20";
        if(StringUtil.isNotBlank(authorizerOrgId)){
            apiaddr+="&authorizerOrgId="+authorizerOrgId;
        }
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm=null;
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        return EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
    }

    /**
     *  添加成员角色
     */
    public static EsignHttpResponse addCompanyMemberRole(String orgId,String psnId) throws EsignDemoException {
        String apiaddr="/v3/organizations/"+orgId+"/member/add-role";
        Map<String, Object> param = new HashMap<>();
        param.put("memberPsnId", psnId);
        param.put("addRole","2"); // 印章保管员
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        Gson gson=new Gson();
        String jsonParm=gson.toJson(param);
        //请求方法
        EsignRequestType requestType = EsignRequestType.POST;
        //生成请求签名鉴权方式的Header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,
                jsonParm, requestType.name(), apiaddr, true);
        //发起接口请求
        EsignHttpResponse createOrgAccount = EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr, requestType, jsonParm, header, true);
        JsonObject jsonObject = gson.fromJson(createOrgAccount.getBody(), JsonObject.class);
        return createOrgAccount;
    }


    /**
     * 获取JSSDK授权数据 用于E签宝的合同数从思方渠道购买 当前不需要调用
    */
    public static String findjssdk() throws EsignDemoException {
        String apiaddr="/ep/jssdk/init-data";
        Map<String, Object> param = new HashMap<>();
        param.put("psnAccount", "cetc-yxhx@cetc-redsolar.cn");
        param.put("orgName","上海能辉科技股份有限公司");
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        Gson gson=new Gson();
        String jsonParm=gson.toJson(param);
        //请求方法
        EsignRequestType requestType = EsignRequestType.POST;
        //生成请求签名鉴权方式的Header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppIdSaa, EsignConfig.EsignAppSecretSaa,
                jsonParm, requestType.name(), apiaddr, true);
        //发起接口请求
        EsignHttpResponse createOrgAccount = EsignHttpHelper.doCommHttp(EsignConfig.EsignHostSaa, apiaddr, requestType, jsonParm, header, true);
        JsonObject jsonObject = gson.fromJson(createOrgAccount.getBody(), JsonObject.class);
        if (ESignConstants.SUCCESS.equals(jsonObject.get("code").getAsString())) {
           // JsonObject data = jsonObject.getAsJsonObject("data");

            return createOrgAccount.getBody();
        } else {
            throw new EsignDemoException(jsonObject.get("message").getAsString());
        }
    }

    //查询印章授权书签署链接
    public static String getCompanyAuthSealUrl(String orgId,String sealAuthBizId) throws EsignDemoException {
        String apiaddr="/v3/seals/org-seals/authorization-sign-url?orgId="+orgId+"&sealAuthBizId="+sealAuthBizId;
        //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
        String jsonParm=null;
        //请求方法
        EsignRequestType requestType= EsignRequestType.GET;
        //生成签名鉴权方式的的header
        Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(EsignConfig.EsignAppId, EsignConfig.EsignAppSecret,jsonParm,requestType.name(),apiaddr,true);
        //发起接口请求
        EsignHttpResponse response=EsignHttpHelper.doCommHttp(EsignConfig.EsignHost, apiaddr,requestType , jsonParm, header,true);
        Gson gson=new Gson();
        JsonObject jsonObject = gson.fromJson(response.getBody(), JsonObject.class);
        if (jsonObject.get("code").getAsInt()==0) {
            JsonObject data = jsonObject.getAsJsonObject("data");
            return data.get("authorizationSignUrl").getAsString();
        } else {
            throw new EsignDemoException(jsonObject.get("message").getAsString());
        }
    }


    public static void main(String[] arr) throws EsignDemoException {
     //   getOrgIdentityInfo("上海能辉科技股份有限公司");

     /*  String url= getCompanyAuthSealUrl("92249b8a751f40589d398bc6a42b1407","71e62d62-fd5e-4f3b-ad90-65d61af4aaf6");
       System.out.println(url);*/

        getCompanyAuthorizedSealStatus("fde64e5a22c2454593ad3993c2a6f4b6","");

       //System.out.println(DateUtils.yearSub(new Date(),3));

    }

}
