package com.bonus.sgzb.auth.utils;

import com.alibaba.fastjson2.JSON;
import com.bonus.sgzb.auth.form.NwApp;
import com.bonus.sgzb.auth.form.NwLoginConstants;
import com.bonus.sgzb.auth.form.OnlineApprove;
import com.bonus.sgzb.auth.form.RespLoginData;
import com.bonus.sgzb.common.core.exception.base.BaseException;
import com.bonus.sgzb.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

import java.util.Base64;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 集成南网注册登陆工具
 *
 * @author caoxianfei
 * @Version 1.0
 * @date 2021-08-13 0:14
 */
@Slf4j
public class HttpUtils {

    public static Map<String, Object> postFormForOauth2(String url, Object params, Map<String, String> map, OnlineApprove onlineApprove) throws Exception {
        log.info("进入post请求，入参为 url={},params={}", url, params);
        String finalUrl = NwLoginConstants.baseUrl + url;
        String body;
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            headers.setBasicAuth(onlineApprove.getAppId(), onlineApprove.getAppsecret());
            HttpEntity<Object> request = new HttpEntity<>(params, headers);
            if (Objects.nonNull(map)) {
                StringBuffer path = new StringBuffer("?");
                Set<Map.Entry<String, String>> entries = map.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    path.append(entry.getKey() + "=" + entry.getValue() + "&");
                }
                finalUrl = finalUrl + path.substring(0, path.length() - 1);
            }
            log.info("请求时入参，finalUrl={},request={}", finalUrl, request);
            body = new RestTemplate().postForEntity(finalUrl, request, String.class).getBody();
            log.info("finalUrl={},出参为,body={}", finalUrl, body);
        } catch (Exception e) {
            log.error("HttpUtils.postForm exception: ", e);
            throw new Exception("Http请求错误");
        }
        return JSON.parseObject(body, Map.class);
    }

    /**
     * className 传入返回对象的class
     * 传入的兑现必须 继承 BaseLoginEntity
     *
     * @param url
     * @param params
     * @param token
     * @param className
     * @param map       post请求如果路径上上有拼接参数，传入map 字段为key 值为value
     * @return
     */
    public static RespLoginData postForm(String url, Object params, String token, Class className, Map<String, String> map, OnlineApprove onlineApprove) throws Exception {
        log.info("进入post请求，入参为 url={},params={},token={}", url, params, token);
        String finalUrl = NwLoginConstants.baseUrl + url;
        String body;
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            if (StringUtils.isBlank(token)) {
                headers.setBasicAuth(onlineApprove.getAppId(), onlineApprove.getAppsecret());
            } else {
                headers.setBearerAuth(token);
            }
            HttpEntity<Object> request = new HttpEntity<>(params, headers);
            if (Objects.nonNull(map)) {
                StringBuffer path = new StringBuffer("?");
                Set<Map.Entry<String, String>> entries = map.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    path.append(entry.getKey() + "=" + entry.getValue() + "&");
                }
                finalUrl = finalUrl + path.substring(0, path.length() - 1);
            }
            log.info("请求时入参，finalUrl={},request={}", finalUrl, request);
            body = new RestTemplate().postForEntity(finalUrl, request, String.class).getBody();
            log.info("finalUrl={},出参为,body={}", finalUrl, body);
        } catch (Exception e) {
            log.error("HttpUtils.postForm exception: ", e);
            throw new Exception("Http请求错误");
        }
        return new RespLoginData(body, className);
    }


    /**
     * className 传入返回对象的class
     * 传入的兑现必须 继承 BaseLoginEntity
     *
     * @param url
     * @param params
     * @param token
     * @param className
     * @param nwApp
     * @param map       post请求如果路径上上有拼接参数，传入map 字段为key 值为value
     * @return
     */
    public static RespLoginData postJsonForApi(String url, Object params, String token, Class className, Map<String, String> map, NwApp nwApp) throws Exception {
        log.info("进入post请求，入参为 url={},params={},token={}", url, params, token);
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        //定义请求参数类型，这里用json所以是MediaType.APPLICATION_JSON
        headers.setContentType(MediaType.APPLICATION_JSON);
        if (!StringUtils.isBlank(token)) {
            headers.setBearerAuth(token);
        } else {
            headers.set(NwLoginConstants.LBCLOUD_ACCESS_KEY, NwLoginConstants.CONCAT_ACCESS_KEY + getLBCloudAccessKey(nwApp.getAppId(), nwApp.getAppsecret()));
        }
        String body;
        try {
            HttpEntity<Object> request = new HttpEntity<>(params, headers);
            String finalUrl = NwLoginConstants.baseUrl + url;
            if (Objects.nonNull(map)) {
                StringBuffer path = new StringBuffer();
                path.append("?");
                Set<Map.Entry<String, String>> entries = map.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    path.append(entry.getKey() + "=" + entry.getValue() + "&");
                }
                finalUrl = finalUrl + path.substring(0, path.length() - 1).toString();
            }
            log.info("请求时入参，finalUrl={},request={}", finalUrl, request);
            body = client.postForEntity(finalUrl, request, String.class).getBody();
            log.info("finalUrl={},出参为,body={}", finalUrl, body);
        } catch (Exception e) {
            log.error("HttpUtils.postJson exception: ", e);
            throw new Exception(NwLoginConstants.HTTP_ERQUEST_FAILED_MSG);
        }
        return new RespLoginData(body, className);
    }

    /**
     * className 传入返回对象的class
     * 传入的兑现必须 继承 BaseLoginEntity
     *
     * @param url
     * @param params
     * @param token
     * @param className
     * @param map       post请求如果路径上上有拼接参数，传入map 字段为key 值为value
     * @return
     */
    public static RespLoginData postJson(String url, Object params, String token, Class className, Map<String, String> map) {
        log.info("进入post请求，入参为 url={},params={},token={},map:{}", url, params, token, map);
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        //定义请求参数类型，这里用json所以是MediaType.APPLICATION_JSON
        headers.setContentType(MediaType.APPLICATION_JSON);
        if (!org.apache.commons.lang3.StringUtils.isBlank(token)) {
            headers.setBearerAuth(token);
        }
        String body;
        try {
            HttpEntity<Object> request = new HttpEntity<>(params, headers);
            String finalUrl = NwLoginConstants.baseUrl + url;
            if (Objects.nonNull(map)) {
                StringBuffer path = new StringBuffer();
                path.append("?");
                Set<Map.Entry<String, String>> entries = map.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    path.append(entry.getKey() + "=" + entry.getValue() + "&");
                }
                finalUrl = finalUrl + path.substring(0, path.length() - 1).toString();
            }
            log.info("请求时入参，finalUrl={},request={}", finalUrl, request);
            body = client.postForEntity(finalUrl, request, String.class).getBody();
            log.info("finalUrl={},出参为,body={}", finalUrl, body);
        } catch (Exception e) {
            log.error("HttpUtils.postJson exception: ", e);
            throw new BaseException("500", "Http请求错误");
        }
        return new RespLoginData(body, className);
    }

    private static String getLBCloudAccessKey(String username, String password) {
        Assert.notNull(username, "Username must not be null");
        Assert.notNull(password, "Password must not be null");
        log.error("check0003_appId=" + username + ",security=" + password);
        long time = System.currentTimeMillis();
        String sign = DigestUtils.md5Hex(time + NwLoginConstants.CONCAT_SIGN_WORD + password);
        byte[] encode = Base64.getEncoder().encode((time + NwLoginConstants.CONCAT_SIGN_WORD + username + NwLoginConstants.CONCAT_SIGN_WORD + sign).getBytes());
        String cloudAccessKey = new String(encode);
        return cloudAccessKey;
    }
}
