package com.codvision.auth.service.third;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.codvision.base.service.ISysConfigService;
import com.codvision.commoncore.exception.BusinessException;
import com.codvision.commoncore.utils.DateUtil;
import com.codvision.commoncore.utils.Md5Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * 浙里办服务
 *
 * @author codvision
 */
@Slf4j
@Service
public class ZlbService {

    @Resource
    private ISysConfigService configService;

    private static final String URL_PREFIX = "https://hzapi.citybrain.hangzhou.gov.cn";
    private static final String TICKET_VALIDATION = "https://appapi.zjzwfw.gov.cn/sso/servlet/simpleauth?method=ticketValidation&";
    private static final String GET_USER_INFO = "https://appapi.zjzwfw.gov.cn/sso/servlet/simpleauth?method=getUserInfo&";

    private static String ZLB_SERVICE_CODE;
    private static String ZLB_SERVICE_PWD;
    private static String ZLB_KEY;
    private static String ZLB_SYSTEM_ID;
    private static String ZLB_APP_ID;

    @PostConstruct
    public void init() {
        ZLB_KEY = configService.getValueByKey("ZLB_KEY");
        ZLB_SYSTEM_ID = configService.getValueByKey("ZLB_SYSTEM_ID");
        ZLB_APP_ID = configService.getValueByKey("ZLB_APP_ID");
        ZLB_SERVICE_CODE = configService.getValueByKey("ZLB_SERVICE_CODE");
        ZLB_SERVICE_PWD = configService.getValueByKey("ZLB_SERVICE_PWD");
    }

    public String ticketValidation(String st) {
        Map<String, Object> paraMap = new HashMap<>(16);
        paraMap.put("servicecode", ZLB_SERVICE_CODE);
        String time = DateUtil.toString(DateUtil.toDate(DateUtil.getNowDateTime()));
        paraMap.put("time", time);
        paraMap.put("sign", Md5Utils.getMd5(ZLB_SERVICE_CODE + ZLB_SERVICE_PWD + time));
        paraMap.put("st", st);
        paraMap.put("datatype", "json");
        String result = HttpUtil.post(TICKET_VALIDATION, paraMap);
        JSONObject stResult = new JSONObject(result);
        if (!"0".equals(stResult.getStr("result"))) {
            throw new BusinessException("票据认证失败");
        }

        return stResult.getStr("token");
    }

    public JSONObject getUserInfo(String st) {
        Map<String, Object> paraMap = new HashMap<>(16);
        paraMap.put("servicecode", ZLB_SERVICE_CODE);
        String time = DateUtil.toString(DateUtil.toDate(DateUtil.getNowDateTime()));
        paraMap.put("time", time);
        paraMap.put("sign", Md5Utils.getMd5(ZLB_SERVICE_CODE + ZLB_SERVICE_PWD + time));
        paraMap.put("token", ticketValidation(st));
        paraMap.put("datatype", "json");
        String result = HttpUtil.post(GET_USER_INFO, paraMap);
        return new JSONObject(result);
    }

    public JSONObject getZlbLoginJson(String uri, JSONObject data) {
        JSONObject caller = new JSONObject();
        caller.set("appId", ZLB_APP_ID);
        caller.set("systemId", ZLB_SYSTEM_ID);
        caller.set("data", JSONUtil.toJsonStr(data));
        String timestamp = DateUtil.getNowDateTime();
        caller.set("timestamp", timestamp);
        String sign = "appId=" + ZLB_APP_ID + "&data=" + JSONUtil.toJsonStr(data) + "&systemId=" + ZLB_SYSTEM_ID + "&timestamp=" + timestamp;
        // 签名算法和私钥
        Sign sign2 = SecureUtil.sign(SignAlgorithm.SHA256withRSA, ZLB_KEY, null);
        byte[] sign1 = sign2.sign(sign.getBytes());
        Base64.Encoder encoder = Base64.getEncoder();
        sign = encoder.encodeToString(sign1);
        caller.set("sign", sign);
        String body = HttpRequest.post(URL_PREFIX + uri).body(JSONUtil.toJsonStr(caller)).execute().body();
        return new JSONObject(body).getJSONObject("result");
    }
}
